Re: puc(4): 64-bit BARs

2020-03-02 Thread Theo de Raadt
That's quite a hack you wrote, but I think any nicer way of doing it is
going to require a big rewrite..

Patrick Wildt  wrote:

> as it turns out, puc(4) has trouble with 64-bit BARs.  The issue is that
> puc(4) tries to map every BAR before doing anything else.  While iter-
> ating over the BARs it assumes the next BAR is always 4 bytes after the
> other.  For 64-bit BARs that's wrong.  On a device with a 64-bit BAR, it
> will map the BAR correctly, and then using the 0x4 offset try to map an-
> other BAR, thus breaking the previously correctly mapped bar.
> 
> Now I'm not sure this is the best fix, but I think the easiest way is to
> just skip that particular entry.  Thus, with two 64-bit BARs, sc->sc_bar
> mappings[1] and [3] will be empty.  That's fine since the pucdata.c
> entries reference the absolute BAR address, like 0x10 and 0x18, and the
> mapping to the index of the array is done using that absolute value:
> 
> #define PUC_PORT_BAR_INDEX(bar) (((bar) - PCI_MAPREG_START) / 4)
> 
> bar = PUC_PORT_BAR_INDEX(desc->ports[i].bar);
> if (!sc->sc_bar_mappings[bar].mapped) {
> ...
> 
> Feedback?
> 
> Patrick
> 
> diff --git a/sys/dev/pci/puc.c b/sys/dev/pci/puc.c
> index 2c5f3065177..7ec25ecaad2 100644
> --- a/sys/dev/pci/puc.c
> +++ b/sys/dev/pci/puc.c
> @@ -163,8 +163,11 @@ puc_pci_attach(struct device *parent, struct device 
> *self, void *aux)
>   0, >sc_bar_mappings[i].t, >sc_bar_mappings[i].h,
>   >sc_bar_mappings[i].a, >sc_bar_mappings[i].s, 0)
> == 0);
> - if (sc->sc_bar_mappings[i].mapped)
> + if (sc->sc_bar_mappings[i].mapped) {
> + if (type == PCI_MAPREG_MEM_TYPE_64BIT)
> + i++;
>   continue;
> + }
>  
>  #if NCOM > 0
>   /*
> @@ -184,6 +187,8 @@ puc_pci_attach(struct device *parent, struct device 
> *self, void *aux)
>   sc->sc_bar_mappings[i].h = comconsioh;
>   sc->sc_bar_mappings[i].s = COM_NPORTS;
>   sc->sc_bar_mappings[i].mapped = 1;
> + if (type == PCI_MAPREG_MEM_TYPE_64BIT)
> + i++;
>   continue;
>   }
>  #endif
> 



Re: puc(4): 64-bit BARs

2020-03-02 Thread Mark Kettenis
> Date: Mon, 2 Mar 2020 13:56:11 +0100
> From: Patrick Wildt 
> 
> Hi,
> 
> as it turns out, puc(4) has trouble with 64-bit BARs.  The issue is that
> puc(4) tries to map every BAR before doing anything else.  While iter-
> ating over the BARs it assumes the next BAR is always 4 bytes after the
> other.  For 64-bit BARs that's wrong.  On a device with a 64-bit BAR, it
> will map the BAR correctly, and then using the 0x4 offset try to map an-
> other BAR, thus breaking the previously correctly mapped bar.
> 
> Now I'm not sure this is the best fix, but I think the easiest way is to
> just skip that particular entry.  Thus, with two 64-bit BARs, sc->sc_bar
> mappings[1] and [3] will be empty.  That's fine since the pucdata.c
> entries reference the absolute BAR address, like 0x10 and 0x18, and the
> mapping to the index of the array is done using that absolute value:
> 
> #define PUC_PORT_BAR_INDEX(bar) (((bar) - PCI_MAPREG_START) / 4)
> 
> bar = PUC_PORT_BAR_INDEX(desc->ports[i].bar);
> if (!sc->sc_bar_mappings[bar].mapped) {
> ...
> 
> Feedback?

ok kettenis@

> Patrick
> 
> diff --git a/sys/dev/pci/puc.c b/sys/dev/pci/puc.c
> index 2c5f3065177..7ec25ecaad2 100644
> --- a/sys/dev/pci/puc.c
> +++ b/sys/dev/pci/puc.c
> @@ -163,8 +163,11 @@ puc_pci_attach(struct device *parent, struct device 
> *self, void *aux)
>   0, >sc_bar_mappings[i].t, >sc_bar_mappings[i].h,
>   >sc_bar_mappings[i].a, >sc_bar_mappings[i].s, 0)
> == 0);
> - if (sc->sc_bar_mappings[i].mapped)
> + if (sc->sc_bar_mappings[i].mapped) {
> + if (type == PCI_MAPREG_MEM_TYPE_64BIT)
> + i++;
>   continue;
> + }
>  
>  #if NCOM > 0
>   /*
> @@ -184,6 +187,8 @@ puc_pci_attach(struct device *parent, struct device 
> *self, void *aux)
>   sc->sc_bar_mappings[i].h = comconsioh;
>   sc->sc_bar_mappings[i].s = COM_NPORTS;
>   sc->sc_bar_mappings[i].mapped = 1;
> + if (type == PCI_MAPREG_MEM_TYPE_64BIT)
> + i++;
>   continue;
>   }
>  #endif
> 
> 



puc(4): 64-bit BARs

2020-03-02 Thread Patrick Wildt
Hi,

as it turns out, puc(4) has trouble with 64-bit BARs.  The issue is that
puc(4) tries to map every BAR before doing anything else.  While iter-
ating over the BARs it assumes the next BAR is always 4 bytes after the
other.  For 64-bit BARs that's wrong.  On a device with a 64-bit BAR, it
will map the BAR correctly, and then using the 0x4 offset try to map an-
other BAR, thus breaking the previously correctly mapped bar.

Now I'm not sure this is the best fix, but I think the easiest way is to
just skip that particular entry.  Thus, with two 64-bit BARs, sc->sc_bar
mappings[1] and [3] will be empty.  That's fine since the pucdata.c
entries reference the absolute BAR address, like 0x10 and 0x18, and the
mapping to the index of the array is done using that absolute value:

#define PUC_PORT_BAR_INDEX(bar) (((bar) - PCI_MAPREG_START) / 4)

bar = PUC_PORT_BAR_INDEX(desc->ports[i].bar);
if (!sc->sc_bar_mappings[bar].mapped) {
...

Feedback?

Patrick

diff --git a/sys/dev/pci/puc.c b/sys/dev/pci/puc.c
index 2c5f3065177..7ec25ecaad2 100644
--- a/sys/dev/pci/puc.c
+++ b/sys/dev/pci/puc.c
@@ -163,8 +163,11 @@ puc_pci_attach(struct device *parent, struct device *self, 
void *aux)
0, >sc_bar_mappings[i].t, >sc_bar_mappings[i].h,
>sc_bar_mappings[i].a, >sc_bar_mappings[i].s, 0)
  == 0);
-   if (sc->sc_bar_mappings[i].mapped)
+   if (sc->sc_bar_mappings[i].mapped) {
+   if (type == PCI_MAPREG_MEM_TYPE_64BIT)
+   i++;
continue;
+   }
 
 #if NCOM > 0
/*
@@ -184,6 +187,8 @@ puc_pci_attach(struct device *parent, struct device *self, 
void *aux)
sc->sc_bar_mappings[i].h = comconsioh;
sc->sc_bar_mappings[i].s = COM_NPORTS;
sc->sc_bar_mappings[i].mapped = 1;
+   if (type == PCI_MAPREG_MEM_TYPE_64BIT)
+   i++;
continue;
}
 #endif