1 Reply Latest reply: May 13, 2009 12:07 AM by 807567 RSS

    ISA Bridge driver porting, accessing a register without mapping it

    807567
      Hi All,

      I am working on porting a specific pci card Linux driver to Solaris x86 platform.

      Card is PCI to ISA Bridge and has a FPGA on it. When I checked with prtconf, reg value only has pci configuration space, but no other address space (Also ddi_dev_nregs() returns '1'). (Also in Linux box, as seen via lspci, Base Address Registers are all 0).

      In Linux we are able to directly access to the register on address 0x150 like:
      outb(val, 0x150+0xF) 
      but in Solaris since we are not able to map registers (except rnumber 0), not able to access them. For rnumber from 1 to 6 ddi_regs_map_setup() call fails.


      I have also tried to access these register by mapping config space and give a call to ddi_put8() with an offset of 0x150. This also not able to set the registers.


      Is there any way in Solaris to access device registers without mapping them ?


      Cheers,

      Ferruh YIGIT
      Sr. Software Eng. Havelsan AS,
      Istanbul, Turkey

      Edited by: Ferruhy on Feb 19, 2009 3:56 AM
        • 1. Re: ISA Bridge driver porting, accessing a register without mapping it
          807567
          I am a newbie in OpenSolaris and its userspace tools. Just guessing.

          Looking up the userspace tool:

          http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/pcitool/pcitool.c
              427 
              428 /*
              429  * Retrieve first 16 dwords of device's config header, except for the first
              430  * dword.  First 16 dwords are defined by the PCI specification.
              431  */
              432 static int
              433 get_config_header(int fd, uint8_t bus_no, uint8_t dev_no, uint8_t func_no,
              434     pci_conf_hdr_t *config_hdr_p)
              435 {
              436      pcitool_reg_t cfg_prg;
              437      int i;
              438      int rval = SUCCESS;
              439 
              440      /* Prepare a local pcitool_reg_t so as to not disturb the caller's. */
              441      cfg_prg.offset = 0;
              442      cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_4 + NATIVE_ENDIAN;
              443      cfg_prg.bus_no = bus_no;
              444      cfg_prg.dev_no = dev_no;
              445      cfg_prg.func_no = func_no;
              446      cfg_prg.barnum = 0;
              447      cfg_prg.user_version = PCITOOL_VERSION;
              448 
              449      /* Get dwords 1-15 of config space. They must be read as uint32_t. */
              450      for (i = 1; i < (sizeof (pci_conf_hdr_t) / sizeof (uint32_t)); i++) {
              451           cfg_prg.offset += sizeof (uint32_t);
              452           if ((rval =
              453               ioctl(fd, PCITOOL_DEVICE_GET_REG, &cfg_prg)) != SUCCESS) {
              454                break;
              455           }
              456           config_hdr_p->dwords[i] = (uint32_t)cfg_prg.data;
              457      }
              458 
              459      return (rval);
              460 }
              461 
          and here:
              271 /* Header 0 (for regular devices) have these fields. */
              272 static field_type_t last_dev_fields[] = {
              273      { PCI_CONF_BASE0, 4, "BAR0", "Base Address Register 0 (@10)" },
              274      { PCI_CONF_BASE1, 4, "BAR1", "Base Address Register 1 (@14)" },
              275      { PCI_CONF_BASE2, 4, "BAR2", "Base Address Register 2 (@18)" },
              276      { PCI_CONF_BASE3, 4, "BAR3", "Base Address Register 3 (@1C)" },
              277      { PCI_CONF_BASE4, 4, "BAR4", "Base Address Register 4 (@20)" },
              278      { PCI_CONF_BASE5, 4, "BAR5", "Base Address Register 5 (@24)" },
              279      { PCI_CONF_ROM, 4, "ROM", "Expansion ROM Base Address Register (@30)" },
              280      { 0, 0, NULL, NULL }
              281 };
              282 
              283 /* Header 1 (PCI-PCI bridge devices) have these fields. */
              284 static field_type_t last_pcibrg_fields[] = {
              285      { PCI_CONF_BASE0, 4, "BAR0", "Base Address Register 0 (@10)" },
              286      { PCI_CONF_BASE1, 4, "BAR1", "Base Address Register 1 (@14)" },
              287      { PCI_BCNF_ROM, 4, "ROM", "Expansion ROM Base Address Register (@38)" },
              288      { 0, 0, NULL, NULL }
              289 };
              290 
          it seemed that the above can be used to read the PCI BAR information?