puc(4): serial console, UART's address != PCI-BAR

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

puc(4): serial console, UART's address != PCI-BAR

SASANO Takayoshi
Hello,

I have CH382-based PCI Express UART card and trying to use this port as
serial console. But specifing I/O port by "machine comaddr 0xd0c0"
at bootloader, kernel crashes with protection fault.

Here is the log.
--------
pci3 at ppb2 bus 3
puc0 at pci3 dev 0 function 0 "Nanjing QinHeng Electronics CH382" rev 0x10: ports: 2 com
puc0: couldn't map BAR at offset 0x10
puc0: com port uses unmapped BAR (0x10)
puc0: com port uses unmapped BAR (0x10)
(snip)
vscsi0 at root
scsibus3 at vscsi0: 256 targets
softraid0 at root
scsibus4 at softraid0: 256 targets
root on sd1a (693a5e2a4cd28136.a) swap on sd1b dump on sd1b
radeondrm0: 1440x900
wsdisplay0 at radeondrm0 mux 1: console (std, vt100 emulation), using wskbd0
wsdisplay0: screen 1-5 added (std, vt100 emulation)
kernel: protection fault trap, code=0
Stopped at      comwrite+0x16:  movq    mptramp_gdt32_desc+0x36(%rax),%rdi
ddb{2}> ps
   TID   PPID   PGRP    UID  S       FLAGS  WAIT          COMMAND
*62499      1      1      0  7           0                init
 40202      0      0      0  3     0x14200  bored         ttm_swap
 16400      0      0      0  3     0x14200  pgzero        zerothread
 63444      0      0      0  3     0x14200  aiodoned      aiodoned
 19864      0      0      0  3     0x14200  syncer        update
 33777      0      0      0  3     0x14200  cleaner       cleaner
 29173      0      0      0  3     0x14200  reaper        reaper
 19502      0      0      0  3     0x14200  pgdaemon      pagedaemon
 30664      0      0      0  3     0x14200  bored         crynlk
 14562      0      0      0  3     0x14200  bored         crypto
 90437      0      0      0  3     0x14200  pftm          pfpurge
 83523      0      0      0  3     0x14200  bored         sensors
 66506      0      0      0  3     0x14200  usbtsk        usbtask
 59687      0      0      0  3     0x14200  usbatsk       usbatsk
 26939      0      0      0  3  0x40014200  acpi0         acpi0
 52265      0      0      0  7  0x40014200                idle3
  7097      0      0      0  3  0x40014200                idle2
  7435      0      0      0  7  0x40014200                idle1
 91364      0      0      0  3     0x14200  bored         softnet
 20307      0      0      0  3     0x14200  bored         systqmp
 26585      0      0      0  3     0x14200  bored         systq
   754      0      0      0  7  0x40014200                idle0
 71396      0      0      0  3     0x14200  bored         sbar
     1      0      1      0  3        0x82  wait          init
     0     -1      0      0  3     0x10200  scheduler     swapper
ddb{2}> trace
comwrite() at comwrite+0x16
dosendsyslog() at dosendsyslog+0x1ce
sys_sendsyslog() at sys_sendsyslog+0xbe
syscall() at syscall+0x27b
--- syscall (number 112) ---
end of kernel
end trace frame: 0x25f8573e0a2, count: -4
0x25f85635b5a:
ddb{2}> boot poweroff
--------

Here is the PCI configuration register of my CH382.

--------
 3:0:0: Nanjing QinHeng Electronics CH382
        0x0000: Vendor ID: 1c00 Product ID: 3253
        0x0004: Command: 0007 Status: 0010
        0x0008: Class: 07 Subclass: 00 Interface: 05 Revision: 10
        0x000c: BIST: 00 Header Type: 00 Latency Timer: 00 Cache Line Size: 10
        0x0010: BAR io addr: 0x0000d000/0x0100
        0x0014: BAR mem prefetchable 32bit addr: 0xd0100000/0x00008000
        0x0018: BAR io addr: 0x0000d100/0x0004
        0x001c: BAR empty (00000000)
        0x0020: BAR empty (00000000)
        0x0024: BAR empty (00000000)
        0x0028: Cardbus CIS: 00000000
        0x002c: Subsystem Vendor ID: 1c00 Product ID: 3253
        0x0030: Expansion ROM Base Address: fe900000
        0x0038: 00000000
        0x003c: Interrupt Pin: 01 Line: 0b Min Gnt: 00 Max Lat: 00
        0x0060: Capability 0x01: Power Management
                State: D0
        0x0068: Capability 0x05: Message Signaled Interrupts (MSI)
        0x0080: Capability 0x10: PCI Express
                Link Speed: 2.5 / 2.5 GT/s Link Width: x1 / x1
--------

puc_pci_attach() in sys/dev/pci/puc.c requires BAR == UART's address
(specified with machine comaddr argument).

CH382's UART lies on BAR + 0xc0, so 0xd0c0 is real address.

To solve this problem, I am testing this patch. It seems to be working,
but can I use _bus_space_map() in puc.c?

--------
Index: puc.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/puc.c,v
retrieving revision 1.24
diff -u -p -r1.24 puc.c
--- puc.c 14 Mar 2015 03:38:49 -0000 1.24
+++ puc.c 23 Aug 2016 13:30:50 -0000
@@ -151,6 +151,7 @@ puc_pci_attach(struct device *parent, st
  for (i = 0; i < PUC_NBARS; i++) {
  pcireg_t type;
  int bar;
+ bus_size_t size;
 
  sc->sc_bar_mappings[i].mapped = 0;
  bar = PCI_MAPREG_START + 4 * i;
@@ -174,12 +175,14 @@ puc_pci_attach(struct device *parent, st
  * work.
  */
  if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, bar, type,
-    &sc->sc_bar_mappings[i].a, NULL, NULL) == 0 &&
+    &sc->sc_bar_mappings[i].a, &size, NULL) == 0 &&
     pa->pa_iot == comconsiot &&
-    sc->sc_bar_mappings[i].a == comconsaddr) {
+    (sc->sc_bar_mappings[i].a <= comconsaddr &&
+     (sc->sc_bar_mappings[i].a + size) > comconsaddr) &&
+    _bus_space_map(comconsiot, sc->sc_bar_mappings[i].a,
+   size, 0, &sc->sc_bar_mappings[i].h) == 0) {
  sc->sc_bar_mappings[i].t = comconsiot;
- sc->sc_bar_mappings[i].h = comconsioh;
- sc->sc_bar_mappings[i].s = COM_NPORTS;
+ sc->sc_bar_mappings[i].s = size;
  sc->sc_bar_mappings[i].mapped = 1;
  continue;
  }


Regards,
--
SASANO Takayoshi <[hidden email]>