Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1263246 > unrolled thread
| Started by | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| First post | 2015-11-05 15:30 +0100 |
| Last post | 2015-11-06 09:00 +0100 |
| Articles | 10 on this page of 30 — 5 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Tomasz Nowicki <tn@semihalf.com> - 2015-11-05 15:30 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2015-11-05 19:20 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-06 09:00 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-06 10:00 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Tomasz Nowicki <tn@semihalf.com> - 2015-11-06 11:40 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-06 12:50 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Tomasz Nowicki <tn@semihalf.com> - 2015-11-06 13:50 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-06 14:30 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2015-11-06 15:50 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-06 16:40 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-06 16:50 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Tomasz Nowicki <tn@semihalf.com> - 2015-11-09 15:10 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2015-11-09 18:20 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Arnd Bergmann <arnd@arndb.de> - 2015-11-09 21:10 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-10 07:00 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2015-11-11 18:50 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Liviu Dudau <Liviu.Dudau@arm.com> - 2015-11-11 19:20 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Arnd Bergmann <arnd@arndb.de> - 2015-11-11 22:00 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2015-11-12 13:10 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-12 09:50 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Tomasz Nowicki <tn@semihalf.com> - 2015-11-12 14:30 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-12 15:10 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Tomasz Nowicki <tn@semihalf.com> - 2015-11-12 15:50 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-12 16:10 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Tomasz Nowicki <tn@semihalf.com> - 2015-11-13 14:00 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2015-11-13 18:10 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-13 19:00 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2015-11-06 14:00 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Tomasz Nowicki <tn@semihalf.com> - 2015-11-06 11:20 +0100
Re: [Patch v7 4/7] PCI/ACPI: Add interface acpi_pci_root_create() Jiang Liu <jiang.liu@linux.intel.com> - 2015-11-06 09:00 +0100
Page 2 of 2 — ← Prev page 1 [2]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2015-11-12 14:30 +0100 |
| Message-ID | <qu06R-ZA-9@gated-at.bofh.it> |
| In reply to | #1267719 |
On 12.11.2015 09:43, Jiang Liu wrote:
> On 2015/11/12 1:46, Lorenzo Pieralisi wrote:
>> On Tue, Nov 10, 2015 at 01:50:46PM +0800, Jiang Liu wrote:
>>
>> [...]
>>
>>>>> In particular, I would like to understand, for an eg DWordIO descriptor,
>>>>> what Range Minimum, Range Maximum and Translation Offset represent,
>>>>> they can't mean different things depending on the SW parsing them,
>>>>> this totally defeats the purpose.
>>>>
>>>> I have no clue about what those mean in ACPI though.
>>>>
>>>> Generally speaking, each PCI domain is expected to have a (normally 64KB)
>>>> range of CPU addresses that gets translated into PCI I/O space the same
>>>> way that config space and memory space are handled.
>>>> This is true for almost every architecture except for x86, which uses
>>>> different CPU instructions for I/O space compared to the other spaces.
>>>>
>>>>> By the way, ia64 ioremaps the translation_offset (ie new_space()), so
>>>>> basically that's the CPU physical address at which the PCI host bridge
>>>>> map the IO space transactions), I do not think ia64 is any different from
>>>>> arm64 in this respect, if it is please provide an HW description here from
>>>>> the PCI bus perspective here (also an example of ia64 ACPI PCI host bridge
>>>>> tables would help).
>>>>
>>>> The main difference between ia64 and a lot of the other architectures (e.g.
>>>> sparc is different again) is that ia64 defines a logical address range
>>>> in terms of having a small number for each I/O space followed by the
>>>> offset within that space as a 'port number' and uses a mapping function
>>>> that is defined as
>>>>
>>>> static inline void *__ia64_mk_io_addr (unsigned long port)
>>>> {
>>>> struct io_space *space = &io_space[IO_SPACE_NR(port)];
>>>> return (space->mmio_base | IO_SPACE_PORT(port););
>>>> }
>>>> static inline unsigned int inl(unsigned long port)
>>>> {
>>>> return *__ia64_mk_io_addr(port);
>>>> }
>>>>
>>>> Most architectures allow only one I/O port range and put it at a fixed
>>>> virtual address so that inl() simply becomes
>>>>
>>>> static inline u32 inl(unsigned long addr)
>>>> {
>>>> return readl(PCI_IOBASE + addr);
>>>> }
>>>>
>>>> which noticeably reduces code size.
>>>>
>>>> On some architectures (powerpc, arm, arm64), we then get the same simplified
>>>> definition with a fixed virtual address, and use pci_ioremap_io() or
>>>> something like that to to map a physical address range into this virtual
>>>> address window at the correct io_offset;
>>> Hi all,
>>> Thanks for explanation, I found a way to make the ACPI resource
>>> parsing interface arch neutral, it should help to address Lorenzo's
>>> concern. Please refer to the attached patch. (It's still RFC, not tested
>>> yet).
>>
>> If we go with this approach though, you are not adding the offset to
>> the resource when parsing the memory spaces in acpi_decode_space(), are we
>> sure that's what we really want ?
>>
>> In DT, a host bridge range has a:
>>
>> - CPU physical address
>> - PCI bus address
>>
>> We use that to compute the offset between primary bus (ie CPU physical
>> address) and secondary bus (ie PCI bus address).
>>
>> The value ending up in the PCI resource struct (for memory space) is
>> the CPU physical address, if you do not add the offset in acpi_decode_space
>> that does not hold true on platforms where CPU<->PCI offset != 0 on ACPI,
>> am I wrong ?
> Hi Lorenzo,
> I may have found the divergence between us about the design here. You
> treat it as a one-stage translation but I treat it as a
> two-stage translation as below:
> stage 1: map(translate) per-PCI-domain IO port address[0, 16M) into
> system global IO port address. Here system global IO port address is
> ioport_resource[0, IO_SPACE_LIMIT).
> stage 2: map system IO port address into system memory address.
>
> We need two objects of struct resource_win to support above two-stage
> translation. One object, type of IORESOURCE_IO, is used to support
> stage one, and it will also used to allocate IO port resources
> for PCI devices. Another object, type of IORESOURCE_MMIO, is used
> to allocate resource from iomem_resource and setup MMIO mapping
> to actually access IO ports.
>
> For ARM64, it doesn't support multiple per-PCI-domain(bus local)
> IO port address space yet, so stage one seems to be optional
> becomes the offset between bus local IO port address and system
> IO port address is always 0. But we still need two objects of
> struct resource_win. The first object is
> {
> offset:0,
> start:AddressMinimum,
> end:AddressMaximum,
> flags:IORESOURCE_IO
> }
> Here it's type of IORESOURCE_IO and offset must be zero because
> pcibios_resource_to_bus() will access it translate system IO
> port address into bus local IO port address. With my patch,
> the struct resource_win object created by the ACPI core will
> be reused for this.
>
> The second object is:
> {
> offset:Translation_Offset,
> start:AddressMinimum + Translation_Offset,
> end:AddressMaximum + Translation_Offset,
> flags:IORESOURCE_MMIO
> }
> Arch code need to create the second struct resource_win object
> and actually setup the MMIO mapping.
>
> But there's really another bug need to get fixed, funciton
> acpi_dev_ioresource_flags() assumes bus local IO port address
> space is size of 64K, which is wrong for IA64 and ARM64.
>
So what would be the Translation_Offset meaning for two cases DWordIo
(....,TypeTranslation) vs DWordIo (....,TypeStatic)? And why we did not
use TypeTranslation for IA64 so far?
I am worried that TypeTranslation fall into the IA64 category but ACPI
tables were already written incorrectly.
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Jiang Liu <jiang.liu@linux.intel.com> |
|---|---|
| Date | 2015-11-12 15:10 +0100 |
| Message-ID | <qu0JA-1tl-23@gated-at.bofh.it> |
| In reply to | #1267910 |
On 2015/11/12 21:21, Tomasz Nowicki wrote:
> On 12.11.2015 09:43, Jiang Liu wrote:
>> On 2015/11/12 1:46, Lorenzo Pieralisi wrote:
>>> On Tue, Nov 10, 2015 at 01:50:46PM +0800, Jiang Liu wrote:
>>>
>>> [...]
>>>
>>>>>> In particular, I would like to understand, for an eg DWordIO
>>>>>> descriptor,
>>>>>> what Range Minimum, Range Maximum and Translation Offset represent,
>>>>>> they can't mean different things depending on the SW parsing them,
>>>>>> this totally defeats the purpose.
>>>>>
>>>>> I have no clue about what those mean in ACPI though.
>>>>>
>>>>> Generally speaking, each PCI domain is expected to have a (normally
>>>>> 64KB)
>>>>> range of CPU addresses that gets translated into PCI I/O space the
>>>>> same
>>>>> way that config space and memory space are handled.
>>>>> This is true for almost every architecture except for x86, which uses
>>>>> different CPU instructions for I/O space compared to the other spaces.
>>>>>
>>>>>> By the way, ia64 ioremaps the translation_offset (ie new_space()), so
>>>>>> basically that's the CPU physical address at which the PCI host
>>>>>> bridge
>>>>>> map the IO space transactions), I do not think ia64 is any
>>>>>> different from
>>>>>> arm64 in this respect, if it is please provide an HW description
>>>>>> here from
>>>>>> the PCI bus perspective here (also an example of ia64 ACPI PCI
>>>>>> host bridge
>>>>>> tables would help).
>>>>>
>>>>> The main difference between ia64 and a lot of the other
>>>>> architectures (e.g.
>>>>> sparc is different again) is that ia64 defines a logical address range
>>>>> in terms of having a small number for each I/O space followed by the
>>>>> offset within that space as a 'port number' and uses a mapping
>>>>> function
>>>>> that is defined as
>>>>>
>>>>> static inline void *__ia64_mk_io_addr (unsigned long port)
>>>>> {
>>>>> struct io_space *space = &io_space[IO_SPACE_NR(port)];
>>>>> return (space->mmio_base | IO_SPACE_PORT(port););
>>>>> }
>>>>> static inline unsigned int inl(unsigned long port)
>>>>> {
>>>>> return *__ia64_mk_io_addr(port);
>>>>> }
>>>>>
>>>>> Most architectures allow only one I/O port range and put it at a fixed
>>>>> virtual address so that inl() simply becomes
>>>>>
>>>>> static inline u32 inl(unsigned long addr)
>>>>> {
>>>>> return readl(PCI_IOBASE + addr);
>>>>> }
>>>>>
>>>>> which noticeably reduces code size.
>>>>>
>>>>> On some architectures (powerpc, arm, arm64), we then get the same
>>>>> simplified
>>>>> definition with a fixed virtual address, and use pci_ioremap_io() or
>>>>> something like that to to map a physical address range into this
>>>>> virtual
>>>>> address window at the correct io_offset;
>>>> Hi all,
>>>> Thanks for explanation, I found a way to make the ACPI resource
>>>> parsing interface arch neutral, it should help to address Lorenzo's
>>>> concern. Please refer to the attached patch. (It's still RFC, not
>>>> tested
>>>> yet).
>>>
>>> If we go with this approach though, you are not adding the offset to
>>> the resource when parsing the memory spaces in acpi_decode_space(),
>>> are we
>>> sure that's what we really want ?
>>>
>>> In DT, a host bridge range has a:
>>>
>>> - CPU physical address
>>> - PCI bus address
>>>
>>> We use that to compute the offset between primary bus (ie CPU physical
>>> address) and secondary bus (ie PCI bus address).
>>>
>>> The value ending up in the PCI resource struct (for memory space) is
>>> the CPU physical address, if you do not add the offset in
>>> acpi_decode_space
>>> that does not hold true on platforms where CPU<->PCI offset != 0 on
>>> ACPI,
>>> am I wrong ?
>> Hi Lorenzo,
>> I may have found the divergence between us about the design here. You
>> treat it as a one-stage translation but I treat it as a
>> two-stage translation as below:
>> stage 1: map(translate) per-PCI-domain IO port address[0, 16M) into
>> system global IO port address. Here system global IO port address is
>> ioport_resource[0, IO_SPACE_LIMIT).
>> stage 2: map system IO port address into system memory address.
>>
>> We need two objects of struct resource_win to support above two-stage
>> translation. One object, type of IORESOURCE_IO, is used to support
>> stage one, and it will also used to allocate IO port resources
>> for PCI devices. Another object, type of IORESOURCE_MMIO, is used
>> to allocate resource from iomem_resource and setup MMIO mapping
>> to actually access IO ports.
>>
>> For ARM64, it doesn't support multiple per-PCI-domain(bus local)
>> IO port address space yet, so stage one seems to be optional
>> becomes the offset between bus local IO port address and system
>> IO port address is always 0. But we still need two objects of
>> struct resource_win. The first object is
>> {
>> offset:0,
>> start:AddressMinimum,
>> end:AddressMaximum,
>> flags:IORESOURCE_IO
>> }
>> Here it's type of IORESOURCE_IO and offset must be zero because
>> pcibios_resource_to_bus() will access it translate system IO
>> port address into bus local IO port address. With my patch,
>> the struct resource_win object created by the ACPI core will
>> be reused for this.
>>
>> The second object is:
>> {
>> offset:Translation_Offset,
>> start:AddressMinimum + Translation_Offset,
>> end:AddressMaximum + Translation_Offset,
>> flags:IORESOURCE_MMIO
>> }
>> Arch code need to create the second struct resource_win object
>> and actually setup the MMIO mapping.
>>
>> But there's really another bug need to get fixed, funciton
>> acpi_dev_ioresource_flags() assumes bus local IO port address
>> space is size of 64K, which is wrong for IA64 and ARM64.
>>
>
> So what would be the Translation_Offset meaning for two cases DWordIo
> (....,TypeTranslation) vs DWordIo (....,TypeStatic)? And why we did not
> use TypeTranslation for IA64 so far?
IA64 actually ignores the translation type flag and just assume it's
TypeTranslation, so there may be some IA64 BIOS implementations
accidentally using TypeStatic. That's why we parsing SparseTranslation
flag without checking TranslationType flag. I feel ARM64 may face the
same situation as IA64:(
We may expect (TypeStatic, 0-offset) and (TypeTranslation,
non-0-offset) in real word. For other two combinations, I haven't
found a real usage yet, though theoretically they are possible.
Thanks,
Gerry
>
> I am worried that TypeTranslation fall into the IA64 category but ACPI
> tables were already written incorrectly.
>
> Tomasz
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2015-11-12 15:50 +0100 |
| Message-ID | <qu1mh-1Ij-1@gated-at.bofh.it> |
| In reply to | #1267955 |
On 12.11.2015 15:04, Jiang Liu wrote:
> On 2015/11/12 21:21, Tomasz Nowicki wrote:
>> On 12.11.2015 09:43, Jiang Liu wrote:
>>> On 2015/11/12 1:46, Lorenzo Pieralisi wrote:
>>>> On Tue, Nov 10, 2015 at 01:50:46PM +0800, Jiang Liu wrote:
>>>>
>>>> [...]
>>>>
>>>>>>> In particular, I would like to understand, for an eg DWordIO
>>>>>>> descriptor,
>>>>>>> what Range Minimum, Range Maximum and Translation Offset represent,
>>>>>>> they can't mean different things depending on the SW parsing them,
>>>>>>> this totally defeats the purpose.
>>>>>>
>>>>>> I have no clue about what those mean in ACPI though.
>>>>>>
>>>>>> Generally speaking, each PCI domain is expected to have a (normally
>>>>>> 64KB)
>>>>>> range of CPU addresses that gets translated into PCI I/O space the
>>>>>> same
>>>>>> way that config space and memory space are handled.
>>>>>> This is true for almost every architecture except for x86, which uses
>>>>>> different CPU instructions for I/O space compared to the other spaces.
>>>>>>
>>>>>>> By the way, ia64 ioremaps the translation_offset (ie new_space()), so
>>>>>>> basically that's the CPU physical address at which the PCI host
>>>>>>> bridge
>>>>>>> map the IO space transactions), I do not think ia64 is any
>>>>>>> different from
>>>>>>> arm64 in this respect, if it is please provide an HW description
>>>>>>> here from
>>>>>>> the PCI bus perspective here (also an example of ia64 ACPI PCI
>>>>>>> host bridge
>>>>>>> tables would help).
>>>>>>
>>>>>> The main difference between ia64 and a lot of the other
>>>>>> architectures (e.g.
>>>>>> sparc is different again) is that ia64 defines a logical address range
>>>>>> in terms of having a small number for each I/O space followed by the
>>>>>> offset within that space as a 'port number' and uses a mapping
>>>>>> function
>>>>>> that is defined as
>>>>>>
>>>>>> static inline void *__ia64_mk_io_addr (unsigned long port)
>>>>>> {
>>>>>> struct io_space *space = &io_space[IO_SPACE_NR(port)];
>>>>>> return (space->mmio_base | IO_SPACE_PORT(port););
>>>>>> }
>>>>>> static inline unsigned int inl(unsigned long port)
>>>>>> {
>>>>>> return *__ia64_mk_io_addr(port);
>>>>>> }
>>>>>>
>>>>>> Most architectures allow only one I/O port range and put it at a fixed
>>>>>> virtual address so that inl() simply becomes
>>>>>>
>>>>>> static inline u32 inl(unsigned long addr)
>>>>>> {
>>>>>> return readl(PCI_IOBASE + addr);
>>>>>> }
>>>>>>
>>>>>> which noticeably reduces code size.
>>>>>>
>>>>>> On some architectures (powerpc, arm, arm64), we then get the same
>>>>>> simplified
>>>>>> definition with a fixed virtual address, and use pci_ioremap_io() or
>>>>>> something like that to to map a physical address range into this
>>>>>> virtual
>>>>>> address window at the correct io_offset;
>>>>> Hi all,
>>>>> Thanks for explanation, I found a way to make the ACPI resource
>>>>> parsing interface arch neutral, it should help to address Lorenzo's
>>>>> concern. Please refer to the attached patch. (It's still RFC, not
>>>>> tested
>>>>> yet).
>>>>
>>>> If we go with this approach though, you are not adding the offset to
>>>> the resource when parsing the memory spaces in acpi_decode_space(),
>>>> are we
>>>> sure that's what we really want ?
>>>>
>>>> In DT, a host bridge range has a:
>>>>
>>>> - CPU physical address
>>>> - PCI bus address
>>>>
>>>> We use that to compute the offset between primary bus (ie CPU physical
>>>> address) and secondary bus (ie PCI bus address).
>>>>
>>>> The value ending up in the PCI resource struct (for memory space) is
>>>> the CPU physical address, if you do not add the offset in
>>>> acpi_decode_space
>>>> that does not hold true on platforms where CPU<->PCI offset != 0 on
>>>> ACPI,
>>>> am I wrong ?
>>> Hi Lorenzo,
>>> I may have found the divergence between us about the design here. You
>>> treat it as a one-stage translation but I treat it as a
>>> two-stage translation as below:
>>> stage 1: map(translate) per-PCI-domain IO port address[0, 16M) into
>>> system global IO port address. Here system global IO port address is
>>> ioport_resource[0, IO_SPACE_LIMIT).
>>> stage 2: map system IO port address into system memory address.
>>>
>>> We need two objects of struct resource_win to support above two-stage
>>> translation. One object, type of IORESOURCE_IO, is used to support
>>> stage one, and it will also used to allocate IO port resources
>>> for PCI devices. Another object, type of IORESOURCE_MMIO, is used
>>> to allocate resource from iomem_resource and setup MMIO mapping
>>> to actually access IO ports.
>>>
>>> For ARM64, it doesn't support multiple per-PCI-domain(bus local)
>>> IO port address space yet, so stage one seems to be optional
>>> becomes the offset between bus local IO port address and system
>>> IO port address is always 0. But we still need two objects of
>>> struct resource_win. The first object is
>>> {
>>> offset:0,
>>> start:AddressMinimum,
>>> end:AddressMaximum,
>>> flags:IORESOURCE_IO
>>> }
>>> Here it's type of IORESOURCE_IO and offset must be zero because
>>> pcibios_resource_to_bus() will access it translate system IO
>>> port address into bus local IO port address. With my patch,
>>> the struct resource_win object created by the ACPI core will
>>> be reused for this.
>>>
>>> The second object is:
>>> {
>>> offset:Translation_Offset,
>>> start:AddressMinimum + Translation_Offset,
>>> end:AddressMaximum + Translation_Offset,
>>> flags:IORESOURCE_MMIO
>>> }
>>> Arch code need to create the second struct resource_win object
>>> and actually setup the MMIO mapping.
>>>
>>> But there's really another bug need to get fixed, funciton
>>> acpi_dev_ioresource_flags() assumes bus local IO port address
>>> space is size of 64K, which is wrong for IA64 and ARM64.
>>>
>>
>> So what would be the Translation_Offset meaning for two cases DWordIo
>> (....,TypeTranslation) vs DWordIo (....,TypeStatic)? And why we did not
>> use TypeTranslation for IA64 so far?
>
> IA64 actually ignores the translation type flag and just assume it's
> TypeTranslation, so there may be some IA64 BIOS implementations
> accidentally using TypeStatic. That's why we parsing SparseTranslation
> flag without checking TranslationType flag. I feel ARM64 may face the
> same situation as IA64:(
>
> We may expect (TypeStatic, 0-offset) and (TypeTranslation,
> non-0-offset) in real word. For other two combinations, I haven't
> found a real usage yet, though theoretically they are possible.
>
I think we should not bend the generic code for IA64 only and expose
other platforms to the same issue. Instead, lets interpret spec
correctly and create IA64 quirk for the sake of backward compatibility.
Thoughts?
Regards,
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Jiang Liu <jiang.liu@linux.intel.com> |
|---|---|
| Date | 2015-11-12 16:10 +0100 |
| Message-ID | <qu1FE-240-27@gated-at.bofh.it> |
| In reply to | #1267993 |
On 2015/11/12 22:45, Tomasz Nowicki wrote:
> On 12.11.2015 15:04, Jiang Liu wrote:
>> On 2015/11/12 21:21, Tomasz Nowicki wrote:
>>> On 12.11.2015 09:43, Jiang Liu wrote:
>>>> On 2015/11/12 1:46, Lorenzo Pieralisi wrote:
>>>>> On Tue, Nov 10, 2015 at 01:50:46PM +0800, Jiang Liu wrote:
>>>>>
>>>>> [...]
>>>>>
>>>>>>>> In particular, I would like to understand, for an eg DWordIO
>>>>>>>> descriptor,
>>>>>>>> what Range Minimum, Range Maximum and Translation Offset represent,
>>>>>>>> they can't mean different things depending on the SW parsing them,
>>>>>>>> this totally defeats the purpose.
>>>>>>>
>>>>>>> I have no clue about what those mean in ACPI though.
>>>>>>>
>>>>>>> Generally speaking, each PCI domain is expected to have a (normally
>>>>>>> 64KB)
>>>>>>> range of CPU addresses that gets translated into PCI I/O space the
>>>>>>> same
>>>>>>> way that config space and memory space are handled.
>>>>>>> This is true for almost every architecture except for x86, which
>>>>>>> uses
>>>>>>> different CPU instructions for I/O space compared to the other
>>>>>>> spaces.
>>>>>>>
>>>>>>>> By the way, ia64 ioremaps the translation_offset (ie
>>>>>>>> new_space()), so
>>>>>>>> basically that's the CPU physical address at which the PCI host
>>>>>>>> bridge
>>>>>>>> map the IO space transactions), I do not think ia64 is any
>>>>>>>> different from
>>>>>>>> arm64 in this respect, if it is please provide an HW description
>>>>>>>> here from
>>>>>>>> the PCI bus perspective here (also an example of ia64 ACPI PCI
>>>>>>>> host bridge
>>>>>>>> tables would help).
>>>>>>>
>>>>>>> The main difference between ia64 and a lot of the other
>>>>>>> architectures (e.g.
>>>>>>> sparc is different again) is that ia64 defines a logical address
>>>>>>> range
>>>>>>> in terms of having a small number for each I/O space followed by the
>>>>>>> offset within that space as a 'port number' and uses a mapping
>>>>>>> function
>>>>>>> that is defined as
>>>>>>>
>>>>>>> static inline void *__ia64_mk_io_addr (unsigned long port)
>>>>>>> {
>>>>>>> struct io_space *space = &io_space[IO_SPACE_NR(port)];
>>>>>>> return (space->mmio_base | IO_SPACE_PORT(port););
>>>>>>> }
>>>>>>> static inline unsigned int inl(unsigned long port)
>>>>>>> {
>>>>>>> return *__ia64_mk_io_addr(port);
>>>>>>> }
>>>>>>>
>>>>>>> Most architectures allow only one I/O port range and put it at a
>>>>>>> fixed
>>>>>>> virtual address so that inl() simply becomes
>>>>>>>
>>>>>>> static inline u32 inl(unsigned long addr)
>>>>>>> {
>>>>>>> return readl(PCI_IOBASE + addr);
>>>>>>> }
>>>>>>>
>>>>>>> which noticeably reduces code size.
>>>>>>>
>>>>>>> On some architectures (powerpc, arm, arm64), we then get the same
>>>>>>> simplified
>>>>>>> definition with a fixed virtual address, and use pci_ioremap_io() or
>>>>>>> something like that to to map a physical address range into this
>>>>>>> virtual
>>>>>>> address window at the correct io_offset;
>>>>>> Hi all,
>>>>>> Thanks for explanation, I found a way to make the ACPI resource
>>>>>> parsing interface arch neutral, it should help to address Lorenzo's
>>>>>> concern. Please refer to the attached patch. (It's still RFC, not
>>>>>> tested
>>>>>> yet).
>>>>>
>>>>> If we go with this approach though, you are not adding the offset to
>>>>> the resource when parsing the memory spaces in acpi_decode_space(),
>>>>> are we
>>>>> sure that's what we really want ?
>>>>>
>>>>> In DT, a host bridge range has a:
>>>>>
>>>>> - CPU physical address
>>>>> - PCI bus address
>>>>>
>>>>> We use that to compute the offset between primary bus (ie CPU physical
>>>>> address) and secondary bus (ie PCI bus address).
>>>>>
>>>>> The value ending up in the PCI resource struct (for memory space) is
>>>>> the CPU physical address, if you do not add the offset in
>>>>> acpi_decode_space
>>>>> that does not hold true on platforms where CPU<->PCI offset != 0 on
>>>>> ACPI,
>>>>> am I wrong ?
>>>> Hi Lorenzo,
>>>> I may have found the divergence between us about the design
>>>> here. You
>>>> treat it as a one-stage translation but I treat it as a
>>>> two-stage translation as below:
>>>> stage 1: map(translate) per-PCI-domain IO port address[0, 16M) into
>>>> system global IO port address. Here system global IO port address is
>>>> ioport_resource[0, IO_SPACE_LIMIT).
>>>> stage 2: map system IO port address into system memory address.
>>>>
>>>> We need two objects of struct resource_win to support above two-stage
>>>> translation. One object, type of IORESOURCE_IO, is used to support
>>>> stage one, and it will also used to allocate IO port resources
>>>> for PCI devices. Another object, type of IORESOURCE_MMIO, is used
>>>> to allocate resource from iomem_resource and setup MMIO mapping
>>>> to actually access IO ports.
>>>>
>>>> For ARM64, it doesn't support multiple per-PCI-domain(bus local)
>>>> IO port address space yet, so stage one seems to be optional
>>>> becomes the offset between bus local IO port address and system
>>>> IO port address is always 0. But we still need two objects of
>>>> struct resource_win. The first object is
>>>> {
>>>> offset:0,
>>>> start:AddressMinimum,
>>>> end:AddressMaximum,
>>>> flags:IORESOURCE_IO
>>>> }
>>>> Here it's type of IORESOURCE_IO and offset must be zero because
>>>> pcibios_resource_to_bus() will access it translate system IO
>>>> port address into bus local IO port address. With my patch,
>>>> the struct resource_win object created by the ACPI core will
>>>> be reused for this.
>>>>
>>>> The second object is:
>>>> {
>>>> offset:Translation_Offset,
>>>> start:AddressMinimum + Translation_Offset,
>>>> end:AddressMaximum + Translation_Offset,
>>>> flags:IORESOURCE_MMIO
>>>> }
>>>> Arch code need to create the second struct resource_win object
>>>> and actually setup the MMIO mapping.
>>>>
>>>> But there's really another bug need to get fixed, funciton
>>>> acpi_dev_ioresource_flags() assumes bus local IO port address
>>>> space is size of 64K, which is wrong for IA64 and ARM64.
>>>>
>>>
>>> So what would be the Translation_Offset meaning for two cases DWordIo
>>> (....,TypeTranslation) vs DWordIo (....,TypeStatic)? And why we did not
>>> use TypeTranslation for IA64 so far?
>>
>> IA64 actually ignores the translation type flag and just assume it's
>> TypeTranslation, so there may be some IA64 BIOS implementations
>> accidentally using TypeStatic. That's why we parsing SparseTranslation
>> flag without checking TranslationType flag. I feel ARM64 may face the
>> same situation as IA64:(
>>
>> We may expect (TypeStatic, 0-offset) and (TypeTranslation,
>> non-0-offset) in real word. For other two combinations, I haven't
>> found a real usage yet, though theoretically they are possible.
>>
>
> I think we should not bend the generic code for IA64 only and expose
> other platforms to the same issue. Instead, lets interpret spec
> correctly and create IA64 quirk for the sake of backward compatibility.
> Thoughts?
I think there are at least two factors related to this issue.
First we still lack of a way/framework to fix errors in ACPI resource
descriptors. Recently we have refined ACPI resource parsing interfaces
and enforced strictly sanity check. This brings us some regressions
which are really BIOS flaws, but it used to work and now breaks:(
I'm still struggling to get those regressions fixed. So we may run
into the same situation if we enforce strict check for TranslationType:(
Second enforcing strict check doesn't bring us too much benifits.
Translation type is almost platform specific, and we haven't found a
platform support both TypeTranslation and TypeStatic, so arch code
may assume the correct translation type no matter what BIOS reports.
So it won't hurt us even BIOS reports wrong translation type.
So I'm tending to keep current implementation with looser checking,
otherwise it may cause regressions.
Thanks,
Gerry
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2015-11-13 14:00 +0100 |
| Message-ID | <qum7n-6wQ-13@gated-at.bofh.it> |
| In reply to | #1268017 |
On 12.11.2015 16:05, Jiang Liu wrote:
> On 2015/11/12 22:45, Tomasz Nowicki wrote:
>> On 12.11.2015 15:04, Jiang Liu wrote:
>>> On 2015/11/12 21:21, Tomasz Nowicki wrote:
>>>> On 12.11.2015 09:43, Jiang Liu wrote:
>>>>> On 2015/11/12 1:46, Lorenzo Pieralisi wrote:
>>>>>> On Tue, Nov 10, 2015 at 01:50:46PM +0800, Jiang Liu wrote:
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>>>>> In particular, I would like to understand, for an eg DWordIO
>>>>>>>>> descriptor,
>>>>>>>>> what Range Minimum, Range Maximum and Translation Offset represent,
>>>>>>>>> they can't mean different things depending on the SW parsing them,
>>>>>>>>> this totally defeats the purpose.
>>>>>>>>
>>>>>>>> I have no clue about what those mean in ACPI though.
>>>>>>>>
>>>>>>>> Generally speaking, each PCI domain is expected to have a (normally
>>>>>>>> 64KB)
>>>>>>>> range of CPU addresses that gets translated into PCI I/O space the
>>>>>>>> same
>>>>>>>> way that config space and memory space are handled.
>>>>>>>> This is true for almost every architecture except for x86, which
>>>>>>>> uses
>>>>>>>> different CPU instructions for I/O space compared to the other
>>>>>>>> spaces.
>>>>>>>>
>>>>>>>>> By the way, ia64 ioremaps the translation_offset (ie
>>>>>>>>> new_space()), so
>>>>>>>>> basically that's the CPU physical address at which the PCI host
>>>>>>>>> bridge
>>>>>>>>> map the IO space transactions), I do not think ia64 is any
>>>>>>>>> different from
>>>>>>>>> arm64 in this respect, if it is please provide an HW description
>>>>>>>>> here from
>>>>>>>>> the PCI bus perspective here (also an example of ia64 ACPI PCI
>>>>>>>>> host bridge
>>>>>>>>> tables would help).
>>>>>>>>
>>>>>>>> The main difference between ia64 and a lot of the other
>>>>>>>> architectures (e.g.
>>>>>>>> sparc is different again) is that ia64 defines a logical address
>>>>>>>> range
>>>>>>>> in terms of having a small number for each I/O space followed by the
>>>>>>>> offset within that space as a 'port number' and uses a mapping
>>>>>>>> function
>>>>>>>> that is defined as
>>>>>>>>
>>>>>>>> static inline void *__ia64_mk_io_addr (unsigned long port)
>>>>>>>> {
>>>>>>>> struct io_space *space = &io_space[IO_SPACE_NR(port)];
>>>>>>>> return (space->mmio_base | IO_SPACE_PORT(port););
>>>>>>>> }
>>>>>>>> static inline unsigned int inl(unsigned long port)
>>>>>>>> {
>>>>>>>> return *__ia64_mk_io_addr(port);
>>>>>>>> }
>>>>>>>>
>>>>>>>> Most architectures allow only one I/O port range and put it at a
>>>>>>>> fixed
>>>>>>>> virtual address so that inl() simply becomes
>>>>>>>>
>>>>>>>> static inline u32 inl(unsigned long addr)
>>>>>>>> {
>>>>>>>> return readl(PCI_IOBASE + addr);
>>>>>>>> }
>>>>>>>>
>>>>>>>> which noticeably reduces code size.
>>>>>>>>
>>>>>>>> On some architectures (powerpc, arm, arm64), we then get the same
>>>>>>>> simplified
>>>>>>>> definition with a fixed virtual address, and use pci_ioremap_io() or
>>>>>>>> something like that to to map a physical address range into this
>>>>>>>> virtual
>>>>>>>> address window at the correct io_offset;
>>>>>>> Hi all,
>>>>>>> Thanks for explanation, I found a way to make the ACPI resource
>>>>>>> parsing interface arch neutral, it should help to address Lorenzo's
>>>>>>> concern. Please refer to the attached patch. (It's still RFC, not
>>>>>>> tested
>>>>>>> yet).
>>>>>>
>>>>>> If we go with this approach though, you are not adding the offset to
>>>>>> the resource when parsing the memory spaces in acpi_decode_space(),
>>>>>> are we
>>>>>> sure that's what we really want ?
>>>>>>
>>>>>> In DT, a host bridge range has a:
>>>>>>
>>>>>> - CPU physical address
>>>>>> - PCI bus address
>>>>>>
>>>>>> We use that to compute the offset between primary bus (ie CPU physical
>>>>>> address) and secondary bus (ie PCI bus address).
>>>>>>
>>>>>> The value ending up in the PCI resource struct (for memory space) is
>>>>>> the CPU physical address, if you do not add the offset in
>>>>>> acpi_decode_space
>>>>>> that does not hold true on platforms where CPU<->PCI offset != 0 on
>>>>>> ACPI,
>>>>>> am I wrong ?
>>>>> Hi Lorenzo,
>>>>> I may have found the divergence between us about the design
>>>>> here. You
>>>>> treat it as a one-stage translation but I treat it as a
>>>>> two-stage translation as below:
>>>>> stage 1: map(translate) per-PCI-domain IO port address[0, 16M) into
>>>>> system global IO port address. Here system global IO port address is
>>>>> ioport_resource[0, IO_SPACE_LIMIT).
>>>>> stage 2: map system IO port address into system memory address.
>>>>>
>>>>> We need two objects of struct resource_win to support above two-stage
>>>>> translation. One object, type of IORESOURCE_IO, is used to support
>>>>> stage one, and it will also used to allocate IO port resources
>>>>> for PCI devices. Another object, type of IORESOURCE_MMIO, is used
>>>>> to allocate resource from iomem_resource and setup MMIO mapping
>>>>> to actually access IO ports.
>>>>>
>>>>> For ARM64, it doesn't support multiple per-PCI-domain(bus local)
>>>>> IO port address space yet, so stage one seems to be optional
>>>>> becomes the offset between bus local IO port address and system
>>>>> IO port address is always 0. But we still need two objects of
>>>>> struct resource_win. The first object is
>>>>> {
>>>>> offset:0,
>>>>> start:AddressMinimum,
>>>>> end:AddressMaximum,
>>>>> flags:IORESOURCE_IO
>>>>> }
>>>>> Here it's type of IORESOURCE_IO and offset must be zero because
>>>>> pcibios_resource_to_bus() will access it translate system IO
>>>>> port address into bus local IO port address. With my patch,
>>>>> the struct resource_win object created by the ACPI core will
>>>>> be reused for this.
>>>>>
>>>>> The second object is:
>>>>> {
>>>>> offset:Translation_Offset,
>>>>> start:AddressMinimum + Translation_Offset,
>>>>> end:AddressMaximum + Translation_Offset,
>>>>> flags:IORESOURCE_MMIO
>>>>> }
>>>>> Arch code need to create the second struct resource_win object
>>>>> and actually setup the MMIO mapping.
>>>>>
>>>>> But there's really another bug need to get fixed, funciton
>>>>> acpi_dev_ioresource_flags() assumes bus local IO port address
>>>>> space is size of 64K, which is wrong for IA64 and ARM64.
>>>>>
>>>>
>>>> So what would be the Translation_Offset meaning for two cases DWordIo
>>>> (....,TypeTranslation) vs DWordIo (....,TypeStatic)? And why we did not
>>>> use TypeTranslation for IA64 so far?
>>>
>>> IA64 actually ignores the translation type flag and just assume it's
>>> TypeTranslation, so there may be some IA64 BIOS implementations
>>> accidentally using TypeStatic. That's why we parsing SparseTranslation
>>> flag without checking TranslationType flag. I feel ARM64 may face the
>>> same situation as IA64:(
>>>
>>> We may expect (TypeStatic, 0-offset) and (TypeTranslation,
>>> non-0-offset) in real word. For other two combinations, I haven't
>>> found a real usage yet, though theoretically they are possible.
>>>
>>
>> I think we should not bend the generic code for IA64 only and expose
>> other platforms to the same issue. Instead, lets interpret spec
>> correctly and create IA64 quirk for the sake of backward compatibility.
>> Thoughts?
> I think there are at least two factors related to this issue.
>
> First we still lack of a way/framework to fix errors in ACPI resource
> descriptors. Recently we have refined ACPI resource parsing interfaces
> and enforced strictly sanity check. This brings us some regressions
> which are really BIOS flaws, but it used to work and now breaks:(
> I'm still struggling to get those regressions fixed. So we may run
> into the same situation if we enforce strict check for TranslationType:(
>
> Second enforcing strict check doesn't bring us too much benifits.
> Translation type is almost platform specific, and we haven't found a
> platform support both TypeTranslation and TypeStatic, so arch code
> may assume the correct translation type no matter what BIOS reports.
> So it won't hurt us even BIOS reports wrong translation type.
>
That is my point, lets pass down all we need from resource range
descriptors to arch code, then archs with known quirks can whatever is
needed to make it works. However, generic code like acpi_decode_space
cannot play with offsets with silent IA64 assumption.
To sum it up, your last patch looks ok to me modulo Lorenzo's concern:
>>>>>> If we go with this approach though, you are not adding the offset to
>>>>>> the resource when parsing the memory spaces in acpi_decode_space(),
>>>>>> are we
>>>>>> sure that's what we really want ?
>>>>>>
>>>>>> In DT, a host bridge range has a:
>>>>>>
>>>>>> - CPU physical address
>>>>>> - PCI bus address
>>>>>>
>>>>>> We use that to compute the offset between primary bus (ie CPU
physical
>>>>>> address) and secondary bus (ie PCI bus address).
>>>>>>
>>>>>> The value ending up in the PCI resource struct (for memory space) is
>>>>>> the CPU physical address, if you do not add the offset in
>>>>>> acpi_decode_space
>>>>>> that does not hold true on platforms where CPU<->PCI offset != 0 on
>>>>>> ACPI,
>>>>>> am I wrong ?
His concern is that your patch will cause:
acpi_pci_root_validate_resources(&device->dev, list,
IORESOURCE_MEM);
to fail now.
Regards,
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2015-11-13 18:10 +0100 |
| Message-ID | <quq1k-NM-15@gated-at.bofh.it> |
| In reply to | #1268932 |
Please trim your emails, thanks. On Fri, Nov 13, 2015 at 01:57:30PM +0100, Tomasz Nowicki wrote: > On 12.11.2015 16:05, Jiang Liu wrote: [...] > >>>IA64 actually ignores the translation type flag and just assume it's > >>>TypeTranslation, so there may be some IA64 BIOS implementations > >>>accidentally using TypeStatic. That's why we parsing SparseTranslation > >>>flag without checking TranslationType flag. I feel ARM64 may face the > >>>same situation as IA64:( > >>> > >>>We may expect (TypeStatic, 0-offset) and (TypeTranslation, > >>>non-0-offset) in real word. For other two combinations, I haven't > >>>found a real usage yet, though theoretically they are possible. I do not understand why (TypeStatic, non-0-offset) is not a valid option. Aren't there any (x86) platforms with a CPU<->PCI _physical_ address space offset out there (I am talking about memory space) ? > >>I think we should not bend the generic code for IA64 only and expose > >>other platforms to the same issue. Instead, lets interpret spec > >>correctly and create IA64 quirk for the sake of backward compatibility. > >>Thoughts? > >I think there are at least two factors related to this issue. > > > >First we still lack of a way/framework to fix errors in ACPI resource > >descriptors. Recently we have refined ACPI resource parsing interfaces > >and enforced strictly sanity check. This brings us some regressions > >which are really BIOS flaws, but it used to work and now breaks:( > >I'm still struggling to get those regressions fixed. So we may run > >into the same situation if we enforce strict check for TranslationType:( > > > >Second enforcing strict check doesn't bring us too much benifits. > >Translation type is almost platform specific, and we haven't found a > >platform support both TypeTranslation and TypeStatic, so arch code > >may assume the correct translation type no matter what BIOS reports. > >So it won't hurt us even BIOS reports wrong translation type. TBH I still do not understand what TranslationType actually means, I will ask whoever added that to the specification to understand it. > That is my point, lets pass down all we need from resource range > descriptors to arch code, then archs with known quirks can whatever > is needed to make it works. However, generic code like > acpi_decode_space cannot play with offsets with silent IA64 > assumption. > > To sum it up, your last patch looks ok to me modulo Lorenzo's concern: > >>>>>> If we go with this approach though, you are not adding the offset to > >>>>>> the resource when parsing the memory spaces in acpi_decode_space(), > >>>>>> are we > >>>>>> sure that's what we really want ? > >>>>>> > >>>>>> In DT, a host bridge range has a: > >>>>>> > >>>>>> - CPU physical address > >>>>>> - PCI bus address > >>>>>> > >>>>>> We use that to compute the offset between primary bus (ie CPU > physical > >>>>>> address) and secondary bus (ie PCI bus address). > >>>>>> > >>>>>> The value ending up in the PCI resource struct (for memory space) is > >>>>>> the CPU physical address, if you do not add the offset in > >>>>>> acpi_decode_space > >>>>>> that does not hold true on platforms where CPU<->PCI offset != 0 on > >>>>>> ACPI, > >>>>>> am I wrong ? > His concern is that your patch will cause: > acpi_pci_root_validate_resources(&device->dev, list, > IORESOURCE_MEM); > to fail now. Not really. My concern is that there might be platforms out there with an offset between the CPU and PCI physical address spaces, and if we remove the offset value in acpi_decode_space we can break them, because in the kernel struct resource data we have to have CPU physical addresses, not PCI ones. If offset == 0, we are home and dry, I do not understand why that's a given, which is what we would assume if Jiang's patch is merged as-is unless I am mistaken. Thanks, Lorenzo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Jiang Liu <jiang.liu@linux.intel.com> |
|---|---|
| Date | 2015-11-13 19:00 +0100 |
| Message-ID | <quqNH-15a-11@gated-at.bofh.it> |
| In reply to | #1269100 |
On 2015/11/14 1:03, Lorenzo Pieralisi wrote: > Please trim your emails, thanks. > > On Fri, Nov 13, 2015 at 01:57:30PM +0100, Tomasz Nowicki wrote: >> On 12.11.2015 16:05, Jiang Liu wrote: > > [...] > >>>>> IA64 actually ignores the translation type flag and just assume it's >>>>> TypeTranslation, so there may be some IA64 BIOS implementations >>>>> accidentally using TypeStatic. That's why we parsing SparseTranslation >>>>> flag without checking TranslationType flag. I feel ARM64 may face the >>>>> same situation as IA64:( >>>>> >>>>> We may expect (TypeStatic, 0-offset) and (TypeTranslation, >>>>> non-0-offset) in real word. For other two combinations, I haven't >>>>> found a real usage yet, though theoretically they are possible. > > I do not understand why (TypeStatic, non-0-offset) is not a valid > option. Aren't there any (x86) platforms with a CPU<->PCI _physical_ > address space offset out there (I am talking about memory space) ? It's possible, but we have found such a design yet. If we eventually encounter such a case, we need to enhance x86 specific code to support it. > >>>> I think we should not bend the generic code for IA64 only and expose >>>> other platforms to the same issue. Instead, lets interpret spec >>>> correctly and create IA64 quirk for the sake of backward compatibility. >>>> Thoughts? >>> I think there are at least two factors related to this issue. >>> >>> First we still lack of a way/framework to fix errors in ACPI resource >>> descriptors. Recently we have refined ACPI resource parsing interfaces >>> and enforced strictly sanity check. This brings us some regressions >>> which are really BIOS flaws, but it used to work and now breaks:( >>> I'm still struggling to get those regressions fixed. So we may run >>> into the same situation if we enforce strict check for TranslationType:( >>> >>> Second enforcing strict check doesn't bring us too much benifits. >>> Translation type is almost platform specific, and we haven't found a >>> platform support both TypeTranslation and TypeStatic, so arch code >>> may assume the correct translation type no matter what BIOS reports. >>> So it won't hurt us even BIOS reports wrong translation type. > > TBH I still do not understand what TranslationType actually means, > I will ask whoever added that to the specification to understand it. > >> That is my point, lets pass down all we need from resource range >> descriptors to arch code, then archs with known quirks can whatever >> is needed to make it works. However, generic code like >> acpi_decode_space cannot play with offsets with silent IA64 >> assumption. >> >> To sum it up, your last patch looks ok to me modulo Lorenzo's concern: >>>>>>>> If we go with this approach though, you are not adding the offset to >>>>>>>> the resource when parsing the memory spaces in acpi_decode_space(), >>>>>>>> are we >>>>>>>> sure that's what we really want ? >>>>>>>> >>>>>>>> In DT, a host bridge range has a: >>>>>>>> >>>>>>>> - CPU physical address >>>>>>>> - PCI bus address >>>>>>>> >>>>>>>> We use that to compute the offset between primary bus (ie CPU >> physical >>>>>>>> address) and secondary bus (ie PCI bus address). >>>>>>>> >>>>>>>> The value ending up in the PCI resource struct (for memory space) is >>>>>>>> the CPU physical address, if you do not add the offset in >>>>>>>> acpi_decode_space >>>>>>>> that does not hold true on platforms where CPU<->PCI offset != 0 on >>>>>>>> ACPI, >>>>>>>> am I wrong ? >> His concern is that your patch will cause: >> acpi_pci_root_validate_resources(&device->dev, list, >> IORESOURCE_MEM); >> to fail now. > > Not really. My concern is that there might be platforms out there with > an offset between the CPU and PCI physical address spaces, and if we > remove the offset value in acpi_decode_space we can break them, > because in the kernel struct resource data we have to have CPU physical > addresses, not PCI ones. If offset == 0, we are home and dry, I do not > understand why that's a given, which is what we would assume if Jiang's > patch is merged as-is unless I am mistaken. We try to exclude offset from struct resource in generic ACPI code, and it's the arch's responsibility to decide how to manipulate struct resource object if offset is not zero. Currently offset is always zero for x86, and IA64 has arch specific code to handle non-zero offset. So we should be safe without breaking existing code. For ARM64, it's a little different from IA64 so it's hard to share code between IA64 and ARM64. > > Thanks, > Lorenzo > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2015-11-06 14:00 +0100 |
| Message-ID | <qrOMy-4BZ-19@gated-at.bofh.it> |
| In reply to | #1263847 |
On Fri, Nov 06, 2015 at 04:52:47PM +0800, Jiang Liu wrote:
[...]
> >>> +int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
> >>> +{
> >>> + int ret;
> >>> + struct list_head *list = &info->resources;
> >>> + struct acpi_device *device = info->bridge;
> >>> + struct resource_entry *entry, *tmp;
> >>> + unsigned long flags;
> >>> +
> >>> + flags = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT;
> >>> + ret = acpi_dev_get_resources(device, list,
> >>> + acpi_dev_filter_resource_type_cb,
> >>> + (void *)flags);
> >>> + if (ret < 0)
> >>> + dev_warn(&device->dev,
> >>> + "failed to parse _CRS method, error code %d\n", ret);
> >>> + else if (ret == 0)
> >>> + dev_dbg(&device->dev,
> >>> + "no IO and memory resources present in _CRS\n");
> >>> + else {
> >>> + resource_list_for_each_entry_safe(entry, tmp, list) {
> >>> + if (entry->res->flags & IORESOURCE_DISABLED)
> >>> + resource_list_destroy_entry(entry);
> >>> + else
> >>> + entry->res->name = info->name;
> >>> + }
> >>> + acpi_pci_root_validate_resources(&device->dev, list,
> >>> + IORESOURCE_MEM);
> >>> + acpi_pci_root_validate_resources(&device->dev, list,
> >>> + IORESOURCE_IO);
> >>
> >> It is not clear to me why we need these two calls above ^^^. We are
> >> using pci_acpi_root_add_resources(info) later. Is it not enough?
> >>
> >> Also, I cannot use acpi_pci_probe_root_resources() in my ARM64 PCI
> >> driver. It is because acpi_dev_get_resources is adding
> >> translation_offset to IO ranges start address and then:
> >> acpi_pci_root_validate_resources(&device->dev, list,
> >> IORESOURCE_IO);
> >> rejects that IO regions as it is out of my 0x0-SZ_16M window.
> >>
> >> Does acpi_pci_probe_root_resources meant to be x86 specific and I
> >> should avoid using it?
> >
> > IIUC, you _have_ to have the proper translation_offset to map the bridge
> > window into the IO address space:
> >
> > http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/348708.html
> >
> > Then, using the offset, you should do something ia64 does, namely,
> > retrieve the CPU address corresponding to IO space (see arch/ia64/pci/pci.c
> > - add_io_space()) and map it in the physical address space by using
> > pci_remap_iospace(), it is similar to what we have to do with DT.
> >
> > It is extremely confusing and I am not sure I got it right myself,
> > I am still grokking ia64 code to understand what it really does.
> >
> > So basically, the IO bridge window coming from acpi_dev_get_resource()
> > should represent the IO space in 0 - 16M, IIUC.
> >
> > By using the offset (that was initialized using translation_offset) and
> > the resource->start, you can retrieve the cpu address that you need to
> > actually map the IO space, since that's what we do on ARM (ie the
> > IO resource is an offset into the virtual address space set aside
> > for IO).
> >
> > Confusing, to say the least. Jiang, did I get it right ?
> Hi Lorenzo and Tomasz,
> With a cup of coffee, I got myself awake eventually:)
> Now we are going to talk about IO port on IA64, really a little
> complex:( Actually there are two types of translation.
> 1) A PCI domain has a 24-bit IO port address space, there may
> be multiple IO port address spaces in systems with multiple PCI
> domains. So the first type of translation is to translate domain
> specific IO port address into system global IO port address
> (iomem_resource) by
> res->start = acpi_des->start + acpi_des->translation_offset
And that's what I do not understand, or better I do not understand
why the acpi_pci_root_validate_resources (for IO) does not fail on ia64,
since that should work as arm64, namely IO ports are mapped through
MMIO.
I think the check in acpi_pci_root_validate_resources() (for
IORESOURCE_IO) fails at present on ia64 too, correct ?
If not, how can it work ? res->start definitely contains the
CPU physical address mapping IO space after adding the
translation_offset, so the check in acpi_pci_root_validate_resources()
for IO can't succeed.
In add_io_space() ia64 does the same thing as Tomasz has to do,
namely overwriting the res->start and end with the offset into
the virtual address space allocated for IO, which is different from
the CPU physical address allocated to IO space.
Please correct me if I am wrong.
> 2) IA64 needs to map IO port address spaces into MMIO address
> space because it has no instructions to access IO ports directly.
> So IA64 has reserved a MMIO range to map IO port address spaces.
> This type of translation relies on architecture specific information
> instead of ACPI descriptors.
That's how ARM64 works too, the IO space resources are an offset into
a chunk of virtual address space allocated to PCI IO memory, so it
seems to me that arm64 and ia64 should work the same way, and that
at present acpi_pci_root_validate_resources() should fail on ia64 too.
Thanks,
Lorenzo
>
> On the other hand, ACPI specification has defined "I/O to Memory
> Translation" flag and "Memory to I/O Translation" flag in
> ACPI Extended Address Space Descriptor, but current implementation
> doesn't really support such a use case. So we need to find a way
> out here. Could you please help to provide more information about
> PCI host bridge resource descriptor implementation details on
> ARM64?
>
> >
> > Lorenzo
> >
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Tomasz Nowicki <tn@semihalf.com> |
|---|---|
| Date | 2015-11-06 11:20 +0100 |
| Message-ID | <qrMhH-3aK-3@gated-at.bofh.it> |
| In reply to | #1263467 |
On 05.11.2015 19:19, Lorenzo Pieralisi wrote:
> On Thu, Nov 05, 2015 at 03:21:34PM +0100, Tomasz Nowicki wrote:
>> On 14.10.2015 08:29, Jiang Liu wrote:
>
> [...]
>
>>> +static void acpi_pci_root_validate_resources(struct device *dev,
>>> + struct list_head *resources,
>>> + unsigned long type)
>>> +{
>>> + LIST_HEAD(list);
>>> + struct resource *res1, *res2, *root = NULL;
>>> + struct resource_entry *tmp, *entry, *entry2;
>>> +
>>> + BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0);
>>> + root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource;
>>> +
>>> + list_splice_init(resources, &list);
>>> + resource_list_for_each_entry_safe(entry, tmp, &list) {
>>> + bool free = false;
>>> + resource_size_t end;
>>> +
>>> + res1 = entry->res;
>>> + if (!(res1->flags & type))
>>> + goto next;
>>> +
>>> + /* Exclude non-addressable range or non-addressable portion */
>>> + end = min(res1->end, root->end);
>>> + if (end <= res1->start) {
>>> + dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n",
>>> + res1);
>>> + free = true;
>>> + goto next;
>>> + } else if (res1->end != end) {
>>> + dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n",
>>> + res1, (unsigned long long)end + 1,
>>> + (unsigned long long)res1->end);
>>> + res1->end = end;
>>> + }
>>> +
>>> + resource_list_for_each_entry(entry2, resources) {
>>> + res2 = entry2->res;
>>> + if (!(res2->flags & type))
>>> + continue;
>>> +
>>> + /*
>>> + * I don't like throwing away windows because then
>>> + * our resources no longer match the ACPI _CRS, but
>>> + * the kernel resource tree doesn't allow overlaps.
>>> + */
>>> + if (resource_overlaps(res1, res2)) {
>>> + res2->start = min(res1->start, res2->start);
>>> + res2->end = max(res1->end, res2->end);
>>> + dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n",
>>> + res2, res1);
>>> + free = true;
>>> + goto next;
>>> + }
>>> + }
>>> +
>>> +next:
>>> + resource_list_del(entry);
>>> + if (free)
>>> + resource_list_free_entry(entry);
>>> + else
>>> + resource_list_add_tail(entry, resources);
>>> + }
>>> +}
>>> +
>>> +int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
>>> +{
>>> + int ret;
>>> + struct list_head *list = &info->resources;
>>> + struct acpi_device *device = info->bridge;
>>> + struct resource_entry *entry, *tmp;
>>> + unsigned long flags;
>>> +
>>> + flags = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT;
>>> + ret = acpi_dev_get_resources(device, list,
>>> + acpi_dev_filter_resource_type_cb,
>>> + (void *)flags);
>>> + if (ret < 0)
>>> + dev_warn(&device->dev,
>>> + "failed to parse _CRS method, error code %d\n", ret);
>>> + else if (ret == 0)
>>> + dev_dbg(&device->dev,
>>> + "no IO and memory resources present in _CRS\n");
>>> + else {
>>> + resource_list_for_each_entry_safe(entry, tmp, list) {
>>> + if (entry->res->flags & IORESOURCE_DISABLED)
>>> + resource_list_destroy_entry(entry);
>>> + else
>>> + entry->res->name = info->name;
>>> + }
>>> + acpi_pci_root_validate_resources(&device->dev, list,
>>> + IORESOURCE_MEM);
>>> + acpi_pci_root_validate_resources(&device->dev, list,
>>> + IORESOURCE_IO);
>>
>> It is not clear to me why we need these two calls above ^^^. We are
>> using pci_acpi_root_add_resources(info) later. Is it not enough?
>>
>> Also, I cannot use acpi_pci_probe_root_resources() in my ARM64 PCI
>> driver. It is because acpi_dev_get_resources is adding
>> translation_offset to IO ranges start address and then:
>> acpi_pci_root_validate_resources(&device->dev, list,
>> IORESOURCE_IO);
>> rejects that IO regions as it is out of my 0x0-SZ_16M window.
>>
>> Does acpi_pci_probe_root_resources meant to be x86 specific and I
>> should avoid using it?
>
> IIUC, you _have_ to have the proper translation_offset to map the bridge
> window into the IO address space:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/348708.html
>
> Then, using the offset, you should do something ia64 does, namely,
> retrieve the CPU address corresponding to IO space (see arch/ia64/pci/pci.c
> - add_io_space()) and map it in the physical address space by using
> pci_remap_iospace(), it is similar to what we have to do with DT.
>
> It is extremely confusing and I am not sure I got it right myself,
> I am still grokking ia64 code to understand what it really does.
>
> So basically, the IO bridge window coming from acpi_dev_get_resource()
> should represent the IO space in 0 - 16M, IIUC.
Yes, you are right IMO.
>
> By using the offset (that was initialized using translation_offset) and
> the resource->start, you can retrieve the cpu address that you need to
> actually map the IO space, since that's what we do on ARM (ie the
> IO resource is an offset into the virtual address space set aside
> for IO).
>
Right, that is clear to me, below my current implementation example
which works for ARM64 now:
static struct acpi_pci_root_ops acpi_pci_root_ops = {
[...]
.prepare_resources = pci_acpi_root_prepare_resources,
};
static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
{
struct list_head *list = &ci->resources;
struct acpi_device *device = ci->bridge;
struct resource_entry *entry, *tmp;
unsigned long flags;
int ret;
flags = IORESOURCE_IO | IORESOURCE_MEM;
ret = acpi_dev_get_resources(device, list,
acpi_dev_filter_resource_type_cb,
(void *)flags);
if (ret < 0) {
dev_warn(&device->dev,
"failed to parse _CRS method, error code %d\n", ret);
return ret;
} else if (ret == 0)
dev_dbg(&device->dev,
"no IO and memory resources present in _CRS\n");
resource_list_for_each_entry_safe(entry, tmp, &ci->resources) {
struct resource *res = entry->res;
if (entry->res->flags & IORESOURCE_DISABLED)
resource_list_destroy_entry(entry);
else
res->name = ci->name;
/*
* TODO: need to move pci_register_io_range() function out
* of drivers/of/address.c for both used by DT and ACPI
*/
if (res->flags & IORESOURCE_IO) {
unsigned long port;
int err;
resource_size_t length = res->end - res->start;
resource_size_t start = res->start;
err = pci_register_io_range(res->start, length);
if (err) {
resource_list_destroy_entry(entry);
continue;
}
port = pci_address_to_pio(res->start);
if (port == (unsigned long)-1) {
resource_list_destroy_entry(entry);
continue;
}
res->start = port;
res->end = res->start + length;
entry->offset = port - (start - entry->offset);
if (pci_remap_iospace(res, start) < 0)
resource_list_destroy_entry(entry);
}
}
return ret;
}
As you see acpi_dev_get_resources returns:
res->start = acpi_des->start + acpi_des->translation_offset (CPU address)
which then must be adjusted as you described to get io port and call
pci_remap_iospace.
This is also why I can not use acpi_pci_probe_root_resources here. Lets
assume we have IO range like that DSDT table form QEMU:
DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x00000000, // Granularity
0x00000000, // Range Minimum
0x0000FFFF, // Range Maximum
0x3EFF0000, // Translation Offset
0x00010000, // Length
,, , TypeStatic)
so see acpi_dev_get_resources returns res->start = acpi_des->start (0x0)
+ acpi_des->translation_offset(0x3EFF0000) = 0x3EFF0000. This will be
rejected in acpi_pci_root_validate_resources() as 0x3EFF0000 does not
fit within 0-16M.
My question is if acpi_pci_probe_root_resources is handling
translation_offset properly and if we have some silent assumption
specific for e.g. ia64 here.
Thanks for help in looking at it.
Tomasz
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Jiang Liu <jiang.liu@linux.intel.com> |
|---|---|
| Date | 2015-11-06 09:00 +0100 |
| Message-ID | <qrK6e-1Ca-11@gated-at.bofh.it> |
| In reply to | #1263246 |
On 2015/11/5 22:21, Tomasz Nowicki wrote:
> On 14.10.2015 08:29, Jiang Liu wrote:
>> Introduce common interface acpi_pci_root_create() and related data
>> structures to create PCI root bus for ACPI PCI host bridges. It will
>> be used to kill duplicated arch specific code for IA64 and x86. It may
>> also help ARM64 in future.
>>
>> Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Tested-by: Tony Luck <tony.luck@intel.com>
>> Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
>> Signed-off-by: Liu Jiang <jiang.liu@linux.intel.com>
>> ---
>> drivers/acpi/pci_root.c | 204
>> ++++++++++++++++++++++++++++++++++++++++++++++
>> include/linux/pci-acpi.h | 24 ++++++
>> 2 files changed, 228 insertions(+)
>>
>> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
>> index 393706a5261b..850d7bf0c873 100644
>> --- a/drivers/acpi/pci_root.c
>> +++ b/drivers/acpi/pci_root.c
>> @@ -652,6 +652,210 @@ static void acpi_pci_root_remove(struct
>> acpi_device *device)
>> kfree(root);
>> }
>>
>> +/*
>> + * Following code to support acpi_pci_root_create() is copied from
>> + * arch/x86/pci/acpi.c and modified so it could be reused by x86, IA64
>> + * and ARM64.
>> + */
>> +static void acpi_pci_root_validate_resources(struct device *dev,
>> + struct list_head *resources,
>> + unsigned long type)
>> +{
>> + LIST_HEAD(list);
>> + struct resource *res1, *res2, *root = NULL;
>> + struct resource_entry *tmp, *entry, *entry2;
>> +
>> + BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0);
>> + root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource;
>> +
>> + list_splice_init(resources, &list);
>> + resource_list_for_each_entry_safe(entry, tmp, &list) {
>> + bool free = false;
>> + resource_size_t end;
>> +
>> + res1 = entry->res;
>> + if (!(res1->flags & type))
>> + goto next;
>> +
>> + /* Exclude non-addressable range or non-addressable portion */
>> + end = min(res1->end, root->end);
>> + if (end <= res1->start) {
>> + dev_info(dev, "host bridge window %pR (ignored, not CPU
>> addressable)\n",
>> + res1);
>> + free = true;
>> + goto next;
>> + } else if (res1->end != end) {
>> + dev_info(dev, "host bridge window %pR ([%#llx-%#llx]
>> ignored, not CPU addressable)\n",
>> + res1, (unsigned long long)end + 1,
>> + (unsigned long long)res1->end);
>> + res1->end = end;
>> + }
>> +
>> + resource_list_for_each_entry(entry2, resources) {
>> + res2 = entry2->res;
>> + if (!(res2->flags & type))
>> + continue;
>> +
>> + /*
>> + * I don't like throwing away windows because then
>> + * our resources no longer match the ACPI _CRS, but
>> + * the kernel resource tree doesn't allow overlaps.
>> + */
>> + if (resource_overlaps(res1, res2)) {
>> + res2->start = min(res1->start, res2->start);
>> + res2->end = max(res1->end, res2->end);
>> + dev_info(dev, "host bridge window expanded to %pR;
>> %pR ignored\n",
>> + res2, res1);
>> + free = true;
>> + goto next;
>> + }
>> + }
>> +
>> +next:
>> + resource_list_del(entry);
>> + if (free)
>> + resource_list_free_entry(entry);
>> + else
>> + resource_list_add_tail(entry, resources);
>> + }
>> +}
>> +
>> +int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
>> +{
>> + int ret;
>> + struct list_head *list = &info->resources;
>> + struct acpi_device *device = info->bridge;
>> + struct resource_entry *entry, *tmp;
>> + unsigned long flags;
>> +
>> + flags = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT;
>> + ret = acpi_dev_get_resources(device, list,
>> + acpi_dev_filter_resource_type_cb,
>> + (void *)flags);
>> + if (ret < 0)
>> + dev_warn(&device->dev,
>> + "failed to parse _CRS method, error code %d\n", ret);
>> + else if (ret == 0)
>> + dev_dbg(&device->dev,
>> + "no IO and memory resources present in _CRS\n");
>> + else {
>> + resource_list_for_each_entry_safe(entry, tmp, list) {
>> + if (entry->res->flags & IORESOURCE_DISABLED)
>> + resource_list_destroy_entry(entry);
>> + else
>> + entry->res->name = info->name;
>> + }
>> + acpi_pci_root_validate_resources(&device->dev, list,
>> + IORESOURCE_MEM);
>> + acpi_pci_root_validate_resources(&device->dev, list,
>> + IORESOURCE_IO);
>
> It is not clear to me why we need these two calls above ^^^. We are
> using pci_acpi_root_add_resources(info) later. Is it not enough?
Hi Tomasz,
acpi_pci_root_validate_resources() will try adjust (or fix)
conflicting resources among all resources of the PCI host bridge,
but pci_acpi_root_add_resources() only rejects conflicting resources.
>
> Also, I cannot use acpi_pci_probe_root_resources() in my ARM64 PCI
> driver. It is because acpi_dev_get_resources is adding
> translation_offset to IO ranges start address and then:
> acpi_pci_root_validate_resources(&device->dev, list,
> IORESOURCE_IO);
> rejects that IO regions as it is out of my 0x0-SZ_16M window.
>
> Does acpi_pci_probe_root_resources meant to be x86 specific and I should
> avoid using it?
It should be generic, but we have some issue in support of
translation_offset. I'm trying to get this fixed.
Thanks,
Gerry
>
> Thanks,
> Tomasz
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | linux.kernel
csiph-web