PCI: vmd: add PCH rootbus#2
Conversation
This function is too long and needs to be shortened to make it more readable. Certain VMD devices like 0xAD0B has two bus ranges, current implementation supports only one range. This clean up is a prework for enablement additional VMD bus range. Signed-off-by: Szymon Durawa <szymon.durawa@linux.intel.com> Suggested-by: Nirmal Patel <nirmal.patel@linux.intel.com>
Starting from 0xAD0B VMD enhacement introduces separate rootbus for PCH. It means that all 3 MMIO BARs exposed by VMD are shared now between CPU IOC and PCH. This patch adds PCH bus enumeration and MMIO management for devices with VMD enhancement support. Signed-off-by: Szymon Durawa <szymon.durawa@linux.intel.com> Suggested-by: Nirmal Patel <nirmal.patel@linux.intel.com>
| VMD_FEAT_BIOS_PM_QUIRK = (1 << 5), | ||
|
|
||
| /* | ||
| * Some client VMD devices have their VMD rootports connected to both |
There was a problem hiding this comment.
Nie wspominaj tutaj, że mówimy tu o "client" ponieważ nikogo to nie obchodzi. Część ludzi nie ogarnie nawet co masz na myśli.
To co jest ważne to fakty. a fakt jest taki:
"Starting from Intel Lunar Lake, VMD driver might be connected to PCH rootbus" (jeżeli dobrze pamiętam, to Lunar lake).
| * PCI_VMD_PRIMARY_PCH_BUS but original value is 0xE1 which is stored | ||
| * in vmd->busn_start_pch. | ||
| */ | ||
| if (vmd_has_pch_rootbus(vmd) && bus->number == PCI_VMD_PRIMARY_PCH_BUS) |
There was a problem hiding this comment.
wydaje mi się, że te warunki są jednoznaczne w tym miejscu i możesz sprawdzić tylko jeden z nich.
| if (vmd_has_pch_rootbus(vmd) && bus->number == PCI_VMD_PRIMARY_PCH_BUS) | ||
| busnr_ecam = vmd->busn_start_pch - vmd->busn_start; | ||
| else | ||
| busnr_ecam = bus->number - vmd->busn_start; |
There was a problem hiding this comment.
jeżeli zachodzi koniecznośc takiego WA zdecydowanie czytelniejsze, będzie, jeżeli stworzysz pole (jeżeli dobrze rozumiem) vmd->busn_offset[2] i będziesz tam przypisywał wartość:
vmd->busn_offset[0] = bus->number;
vmd->busn_offset[1] = 0xE1;
Chodzi mi o to że nazywanie pól pod pch ogranicza rozszerzalność tego rozwiązania (jeżeli ktoś za parę lat doda inny pcie bus ciężko będzie utrzymać odpowiednie nazewnictwo).
| struct resource resources[6]; | ||
| struct irq_domain *irq_domain; | ||
| struct pci_bus *bus; | ||
| struct pci_bus *bus_pch; |
There was a problem hiding this comment.
nie da rady zmergować busów w tablice?
There was a problem hiding this comment.
dodac define na ilosc busow
| }; | ||
|
|
||
| /* | ||
| * Update first cfgbar range (IOC) with value stored |
There was a problem hiding this comment.
nie musisz tłumaczyć kodu, każdy ogarnięty developer widzi co robisz. To co nas interesuje to dlaczego jest taka potrzeba. Najelpszy byłby link do specyfikacji jeżeli jest to PCIe spek. Pewnie nie jest.
| * | ||
| * The only way we could use a 64-bit non-prefetchable MEMBAR is | ||
| * if its address is <4GB so that we can convert it to a 32-bit | ||
| * resource. To be visible to the host OS, all VMD endpoints must |
| } | ||
|
|
||
| /* | ||
| * Align resource information the same as for vmd_configure_membar1 |
| * Align resource information the same as for vmd_configure_membar1 | ||
| * function. | ||
| */ | ||
| static void vmd_configure_membar2(struct vmd_dev *vmd, |
There was a problem hiding this comment.
te dwie funkcje vmd_configure_membar1 i vmd_configure_membar2 wydaje mi się, że można połączyć w jedną ponieważ kod jest niemal indentyczny (poza resorces, które updatujesz) oczywiście są one sobie odpowiadające więc jesteś w stanie odnosić się po indexach.
There was a problem hiding this comment.
no i wtedy możesz ładnie opisać co się znajduje w poszczególnych resources (jeżeli oczywiscie merge tych funkcji jest możliwy).
| struct resource *res; | ||
| u32 upper_bits, reg; | ||
| unsigned long flags; | ||
| u64 vmd_enh_membar2_offset = 0; |
There was a problem hiding this comment.
podobnie jak wyżej, proszę zmień vmd_membar2_pch_offset
| } | ||
|
|
||
| /* | ||
| * VMD enhacement specific: pci_scan_bridge_extend() in probe.c |
There was a problem hiding this comment.
skróciłbym to trochę, i na razie podkreślił że to jest te miejsce przez które robimy RFC
This is a workaround for pci_scan_bridge_extend() code.
It assigns setup as broken when primary != bus->number.
For PCH rootbus primary is not "hard-wired to 0".
To avoid this, vmd->bus_pch->number and vmd->bus_pch->primary are updated to same value.
| @@ -31,6 +31,15 @@ | |||
| #define PCI_REG_VMLOCK 0x70 | |||
| #define MB2_SHADOW_EN(vmlock) (vmlock & 0x2) | |||
|
|
|||
There was a problem hiding this comment.
VMD enhacement nie zmienia prezentacji urzadzen
Starting from 0xAD0B VMD enhacement introduces separate rootbus for PCH. It means that all 3 MMIO BARs exposed by VMD are shared now between CPU IOC and PCH. This patch adds PCH bus enumeration and MMIO management for devices with VMD enhancement support. Signed-off-by: Szymon Durawa <szymon.durawa@linux.intel.com> Suggested-by: Nirmal Patel <nirmal.patel@linux.intel.com>
This function is too long and needs to be shortened to make it more readable. Certain VMD devices like 0xAD0B has two bus ranges, current implementation supports only one range. This clean up is a prework for enablement additional VMD bus range. Signed-off-by: Szymon Durawa <szymon.durawa@linux.intel.com> Suggested-by: Nirmal Patel <nirmal.patel@linux.intel.com>
…tbus for PCH. It means that all 3 MMIO BARs exposed by VMD are shared now between CPU IOC and PCH. This patch adds PCH bus enumeration and MMIO management for devices with VMD enhancement support. Signed-off-by: Szymon Durawa <szymon.durawa@linux.intel.com> Suggested-by: Nirmal Patel <nirmal.patel@linux.intel.com>
| #define VMD_MEMBAR1 2 | ||
| #define VMD_MEMBAR2 4 | ||
|
|
||
| #define VMD_ROOTBUS_SIZE 2 |
| struct irq_domain *irq_domain; | ||
| struct pci_bus *bus; | ||
| u8 busn_start; | ||
| struct pci_bus *bus[VMD_ROOTBUS_SIZE]; |
There was a problem hiding this comment.
you can eventually consider to group it into struct but it is fine for me.
| }; | ||
|
|
||
| enum vmd_rootbus { | ||
| VMD_ROOTBUS0, |
There was a problem hiding this comment.
imo VMD_ROOTBUS_0, but is is fine anyway
| * PCI_VMD_PRIMARY_PCH_BUS but original value is 0xE1 which is stored | ||
| * in vmd->busn_start[VMD_ROOTBUS1]. | ||
| */ | ||
| if (vmd_has_pch_rootbus(vmd) && bus->number == PCI_VMD_PRIMARY_PCH_BUS) |
There was a problem hiding this comment.
you can detect it by:
if (&(vmd->bus[VMD_ROOTBUS1]) == bus)
and I think it is better readable, because you are not reaying on hack but on adress.
Eventually, you can consider passing enum vmd_rootbus instead of bus, and deference it here.
If you passing struct vmd_dev *vmd and passing struct pci_bus *bus placed inside vmd the struct is not mandatory because you can obtain it easy.
There was a problem hiding this comment.
Condition is rewritten using ? operand.
| unsigned char bus_number = 0; | ||
|
|
||
| /* | ||
| * VMD enhacement specific: for PCH rootbus, bus number is set to |
There was a problem hiding this comment.
Please remove VMD enhancement specyfic. It has nothing to do with VMD and it is not specific, it is a hack for kernel code elsewhere.
Please add reference to vmd_create_pch_bus. Simple
See comment in vmd_create_pch_bus().
Should be fine.
| vmd->busn_start[VMD_ROOTBUS1] = 225; | ||
| } else { | ||
| pci_err(dev, | ||
| "Unknown Bus Offset Setting (%d)\n", |
There was a problem hiding this comment.
"Unknown Bus Offset Setting (%d)\n" is not really helpful.
What about:
Determined 3 vmd configs but VMD in PCH bus is not supported, aborting.
Probably you can find better wording, I didn't check it.
| } | ||
| } | ||
|
|
||
| static void vmd_configure_membar(struct vmd_dev *vmd, |
There was a problem hiding this comment.
Description upon the function would be recommended and helpful.
https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html
| */ | ||
| vmd_configure_membar(vmd, VMD_MEMBAR1, VMD_RESOURCE_MEMBAR1, 0, | ||
| pch_membar1_offset, NULL); | ||
| vmd_configure_membar(vmd, VMD_MEMBAR2, VMD_RESOURCE_MEMBAR2, |
There was a problem hiding this comment.
What I don' like here is repeated initialization please consider reverting order. or use if/else
| pci_err(dev, | ||
| "Unknown Bus Offset Setting (%d)\n", | ||
| BUS_RESTRICT_CFG(reg)); | ||
| return -ENODEV; |
There was a problem hiding this comment.
Please consider other error codes (in each case now -ENODEV is returned from various functions)
mtkaczyk
left a comment
There was a problem hiding this comment.
- Please update module version
- Please update patches author (currently it is
sdurawa)
| #define MB2_SHADOW_EN(vmlock) (vmlock & 0x2) | ||
|
|
||
| #define PCI_VMD_PRIMARY_PCH_BUS 0x80 | ||
| #define PCI_REG_BUSRANGE0 0xC8 |
There was a problem hiding this comment.
Probably we should make all defines starting with PCI_VMD or just VMD. We should avoid name confusion with different components.
If you would like to stay with PCI_* then it is not right place for those defines because they are probably global and should be placed in include/linux/pci_regs.h - we don't want that.
| #define MB2_SHADOW_SIZE 16 | ||
|
|
||
| enum vmd_resource { | ||
| VMD_RESOURCE_CFGBAR, |
There was a problem hiding this comment.
VMD_RESOURCE_CFGBAR = 0 to force initialization from 0
| VMD_RESOURCE_CFGBAR, | |
| VMD_RESOURCE_CFGBAR = 0, |
| VMD_FEAT_HAS_BUS_RESTRICTIONS | \ | ||
| VMD_FEAT_OFFSET_FIRST_VECTOR | \ | ||
| VMD_FEAT_BIOS_PM_QUIRK) | ||
| VMD_FEAT_BIOS_PM_QUIRK | \ |
There was a problem hiding this comment.
Looks like to alligned same way as above but it could be presentation issue:
| VMD_FEAT_BIOS_PM_QUIRK | \ | |
| VMD_FEAT_BIOS_PM_QUIRK | \ |
| }; | ||
|
|
||
| enum vmd_rootbus { | ||
| VMD_ROOTBUS_0, |
There was a problem hiding this comment.
| VMD_ROOTBUS_0, | |
| VMD_ROOTBUS_0 = 0, |
| struct pci_bus *bus; | ||
| u8 busn_start; | ||
| struct pci_bus *bus[VMD_ROOTBUS_COUNT]; | ||
| u8 busn_start[VMD_ROOTBUS_COUNT]; |
There was a problem hiding this comment.
It is asking to be placed in structure.
struct vmd_pci_bus {
struct pci_bus *bus;
u8 busn_start;
| u8 busn_start[VMD_ROOTBUS_COUNT]; | |
| struct vmd_pci_bus vmd_bus[VMD_ROOTBUS_COUNT]; |
but I think it is fine either way
| pci_scan_child_bus(vmd->bus); | ||
| vmd_domain_reset(vmd); | ||
| WARN(sysfs_create_link(&vmd->dev->dev.kobj, | ||
| &vmd->bus[VMD_ROOTBUS_0]->dev.kobj, "domain"), |
There was a problem hiding this comment.
Shouldn't we create domain link for pch attached ROOTBUS_1?
There was a problem hiding this comment.
No, there is only required for VMD domain. When creating sys link for ROOTBUS 1 there is an error "cannot create duplicate filename '/devices/pci0000:00/0000:00:0e.0/domain'".
| vmd->busn_start[VMD_ROOTBUS_1] = 225; | ||
| } else { | ||
| pci_err(dev, | ||
| "VMD Bus Restriction detected type %d,", |
There was a problem hiding this comment.
| "VMD Bus Restriction detected type %d,", | |
| pci_err(dev, "VMD Bus Restriction detected type %d, but PCH Rootbus is not supported, aborting.", | |
| BUS_RESTRICT_CFG(reg)); | |
There was a problem hiding this comment.
This messages cannot be divided because kernel is not guarantying that they will be flushed together, one by one.
| if (!upper_bits) | ||
| flags &= ~IORESOURCE_MEM_64; | ||
|
|
||
| snprintf(name, sizeof(name), "VMD MEMBAR%d", membar_number/2); |
There was a problem hiding this comment.
strncat should be avoided :)
| snprintf(name, sizeof(name), "VMD MEMBAR%d", membar_number/2); | |
| snprintf(name, sizeof(name), "VMD MEMBAR%d %s", membar_number / 2, | |
| resource_number > VMD_RESOURCE_MEMBAR_2 : "PCH", ""); |
There was a problem hiding this comment.
Fixed with resource_number > VMD_RESOURCE_MEMBAR_2 ? "PCH":""
| */ | ||
| static void vmd_configure_membar(struct vmd_dev *vmd, | ||
| enum vmd_resource resource_number, | ||
| u8 membar_number, resource_size_t start_offset, |
There was a problem hiding this comment.
| u8 membar_number, resource_size_t start_offset, | |
| enum vmd_resource membar_number, resource_size_t start_offset, |
There was a problem hiding this comment.
membar number does not have an enum, it is a standalone define.
|
|
||
| if (!vmd->bus[VMD_ROOTBUS_1]) { | ||
| pci_free_resource_list(&resources_pch); | ||
| vmd_remove_irq_domain(vmd); |
There was a problem hiding this comment.
Should we? We didn't register PCH MSI yet.
There was a problem hiding this comment.
Shoudn't we call pci_stop_root_bus and pci_remove_root_bus?
There was a problem hiding this comment.
correct, irq domain cannot be removed here, I have added stopping and removig PCH bus instead.
Introducing 2 commits to support PCH rootbus for Intel VMD enhancements.