2019-05-29 07:18:00 -07:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2017-07-10 18:05:09 -07:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2016 SiFive
|
|
|
|
*/
|
|
|
|
|
2019-10-28 00:42:47 -07:00
|
|
|
#ifndef _ASM_RISCV_PCI_H
|
|
|
|
#define _ASM_RISCV_PCI_H
|
2017-07-10 18:05:09 -07:00
|
|
|
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/dma-mapping.h>
|
|
|
|
|
|
|
|
#include <asm/io.h>
|
|
|
|
|
RISC-V: PCI: Avoid handing out address 0 to devices
For RISC-V platforms we permit assigning addresses from 0 to PCI devices,
both in the memory and the I/O bus space, and we happily do so if there
is no conflict, e.g.:
pci 0000:07:00.0: BAR 0: assigned [io 0x0000-0x0007]
pci 0000:07:00.1: BAR 0: assigned [io 0x0008-0x000f]
pci 0000:06:01.0: PCI bridge to [bus 07]
pci 0000:06:01.0: bridge window [io 0x0000-0x0fff]
(with the SiFive HiFive Unmatched RISC-V board and a dual serial port
option card based on the OxSemi OXPCIe952 device wired for the legacy
UART mode).
Address 0 is treated specially however in many places, for example in
`pci_iomap_range' and `pci_iomap_wc_range' we require that the start
address is non-zero, and even if we let such an address through, then
individual device drivers could reject a request to handle a device at
such an address, such as in `uart_configure_port'. Consequently given
devices configured as shown above only one is actually usable:
Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
serial 0000:07:00.0: enabling device (0000 -> 0001)
serial: probe of 0000:07:00.0 failed with error -12
serial 0000:07:00.1: enabling device (0000 -> 0001)
serial 0000:07:00.1: detected caps 00000700 should be 00000500
0000:07:00.1: ttyS0 at I/O 0x8 (irq = 39, base_baud = 15625000) is a 16C950/954
Therefore avoid handing out address 0, by bumping the lowest address
available to PCI via PCIBIOS_MIN_IO and PCIBIOS_MIN_MEM up by 4 and 16
respectively, which is the minimum allocation size for I/O and memory
BARs.
With this in place the system in question we have:
pci 0000:07:00.0: BAR 0: assigned [io 0x1000-0x1007]
pci 0000:07:00.1: BAR 0: assigned [io 0x1008-0x100f]
pci 0000:06:01.0: PCI bridge to [bus 07]
pci 0000:06:01.0: bridge window [io 0x1000-0x1fff]
and then devices work correctly:
Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
serial 0000:07:00.0: enabling device (0000 -> 0001)
serial 0000:07:00.0: detected caps 00000700 should be 00000500
0000:07:00.0: ttyS0 at I/O 0x1000 (irq = 38, base_baud = 15625000) is a 16C950/954
serial 0000:07:00.1: enabling device (0000 -> 0001)
serial 0000:07:00.1: detected caps 00000700 should be 00000500
0000:07:00.1: ttyS1 at I/O 0x1008 (irq = 39, base_baud = 15625000) is a 16C950/954
Especially I/O space ranges are particularly valuable, because bridges
only decode bits from 12 up and consequently where 16-bit addressing is
in effect, as few as 16 separate ranges can be assigned to individual
buses only, however a generic change to avoid handing out address 0 only
has turned out controversial as per the discussion referred via the link
below.
Conversely sorting this out in platform code has been standard practice
since forever to avoid a clash with legacy devices subtractively decoded
by the southbridge where present. This can be revised should a generic
solution be adopted sometime.
Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Link: https://lore.kernel.org/r/alpine.DEB.2.21.2202260044180.25061@angie.orcam.me.uk
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2022-04-27 15:15:47 -07:00
|
|
|
#define PCIBIOS_MIN_IO 4
|
|
|
|
#define PCIBIOS_MIN_MEM 16
|
2017-07-10 18:05:09 -07:00
|
|
|
|
2022-07-22 14:49:44 -07:00
|
|
|
#if defined(CONFIG_PCI) && defined(CONFIG_NUMA)
|
2020-11-18 17:38:29 -07:00
|
|
|
static inline int pcibus_to_node(struct pci_bus *bus)
|
|
|
|
{
|
|
|
|
return dev_to_node(&bus->dev);
|
|
|
|
}
|
|
|
|
#ifndef cpumask_of_pcibus
|
|
|
|
#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
|
|
|
|
cpu_all_mask : \
|
|
|
|
cpumask_of_node(pcibus_to_node(bus)))
|
|
|
|
#endif
|
2022-07-22 14:49:44 -07:00
|
|
|
#endif /* defined(CONFIG_PCI) && defined(CONFIG_NUMA) */
|
2020-11-18 17:38:29 -07:00
|
|
|
|
2022-07-22 14:49:44 -07:00
|
|
|
/* Generic PCI */
|
|
|
|
#include <asm-generic/pci.h>
|
2017-07-10 18:05:09 -07:00
|
|
|
|
2019-10-28 00:42:47 -07:00
|
|
|
#endif /* _ASM_RISCV_PCI_H */
|