0 Replies Latest reply on Dec 12, 2009 11:16 PM by 807559

    Device driver register sets

      Background: I am using Solaris 10 update3 running on a simulated sparc 64-bit machine in Simics. I added a new hardware memory-mapped device in Simics, and need to create a Solaris device driver in order to read/write to this new device.

      I created a simple device driver and am trying to map registers so that they can be accessed. To do this, I tried to create a simple Solaris device driver heavily based on the sample "Quote" driver in the Sun tutorial. I was able to install and use the Quote version, and then modified it to be able to access device memory instead of just allocated kernel memory. When installing the device driver on the simulated machine, it fails on attach() on the call to ddi_regs_map_setup() with rnumber=0. The problem is that there are no register sets available to map! A call to ddi_dev_nregs() returns 0.

      My newbie question is: where are the device register sets defined for a device in a Solaris system?
      I can't find information on this anywhere. Are the register sets dependent on the "parent" property in the .conf file, where each type of device has a different pre-defined register set? That doesn't make much sense to me, because I am creating a new type of device that needs its own register set. The Solaris documentation mentions that registers can be defined in the .conf file using the "reg" property, but stops short of explaining the format that is expected in the property. I feel like I'm completely missing the boat on something here but I've been searching all day and couldn't find out how to define new register sets for a device!

      My .conf file:
      name="testdevice" parent="pseudo" instance=0;
      This is the call in attach() that fails due to no register sets being available:
      //The base address that the new device is memory-mapped to
      #define NEWDEVICE_BASEADDR 0x4000d000000
      int newdevice_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
        qsp->testReg = (char*)(NEWDEVICE_BASEADDR);
        qsp->testReg_len = 8;
        //Map test register
        da_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
        da_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
        da_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
        int numRegs=0;
        ddi_dev_nregs(dip, &numRegs);
        cmn_err(CE_WARN, "Number of registers: %d", numRegs);
        int err;
        err = ddi_regs_map_setup(dip, 0, (caddr_t *)&(qsp->testReg), 0,
                qsp->testReg_len, &da_attr, &qsp->testReg_handle);