Writing device drivers: How to access a specific memory area?

2008-12-25 Thread Andre Albsmeier
Hello all,

I am writing a driver which needs to access memory at a
specific location. The location depends on what the BIOS
has configured into the host bridge. For example, my
current machine uses an Intel 975X chipset and the memory
location I am interested in has been set to 0xFED14000 and
is 16KB in size (this is MCHBAR of the 975X memory hub).

I have no idea how to access this space from my driver.
I have played around with bus_alloc_resource() but this
only gives me back NULL.

However, a devinfo -r gives me:

nexus0
  npx0
  acpi0
  Interrupt request lines:
  9
  I/O ports:
  0x10-0x1f
...
  0x800-0x87f
  I/O memory addresses:
  0x0-0x9
  0xc-0xd
  0xe-0xf
  0x10-0x7fff
  0xf000-0xf3ff
  0xfec0-0xfec00fff
  0xfed13000-0xfed19fff <---
  0xfed1c000-0xfed1
  0xfed2-0xfed3
  0xfed5-0xfed8
  0xfee0-0xfee00fff
  0xffb0-0xffbf
  0xfff0-0x
cpu0
...

The line marked with <--- shows the range which includes
the location I am interested in. It is probably assigned
to the acpi0 device.

How do I proceed from this? Do I have to hack around in
the ACPI-Code? I don't hope so ;-)

I only need access to this memory location during the
probe of my driver to read some configuration data.
I do not need to access it later anymore...

Thanks a lot for any hints,

-Andre
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: Writing device drivers: How to access a specific memory area?

2008-12-25 Thread Rui Paulo


On 25 Dec 2008, at 09:53, Andre Albsmeier wrote:


Hello all,

I am writing a driver which needs to access memory at a
specific location. The location depends on what the BIOS
has configured into the host bridge. For example, my
current machine uses an Intel 975X chipset and the memory
location I am interested in has been set to 0xFED14000 and
is 16KB in size (this is MCHBAR of the 975X memory hub).


You probably just need to do something like:

rid = PCI_BAR(number);
res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);

And then,
bus_read_4(res, offset from specified PCI BAR);




I have no idea how to access this space from my driver.
I have played around with bus_alloc_resource() but this
only gives me back NULL.

However, a devinfo -r gives me:

nexus0
 npx0
 acpi0
 Interrupt request lines:
 9
 I/O ports:
 0x10-0x1f
...
 0x800-0x87f
 I/O memory addresses:
 0x0-0x9
 0xc-0xd
 0xe-0xf
 0x10-0x7fff
 0xf000-0xf3ff
 0xfec0-0xfec00fff
 0xfed13000-0xfed19fff  <---
 0xfed1c000-0xfed1
 0xfed2-0xfed3
 0xfed5-0xfed8
 0xfee0-0xfee00fff
 0xffb0-0xffbf
 0xfff0-0x
   cpu0
...

The line marked with <--- shows the range which includes
the location I am interested in. It is probably assigned
to the acpi0 device.

How do I proceed from this? Do I have to hack around in
the ACPI-Code? I don't hope so ;-)


You'll probably need to create a fake ACPI child driver to access it.


Create your identify routine with something like:

static void mydriver_identify(driver_t *driver, device_t parent)
{
if (device_find_child(parent, "mydriver", -1) == NULL &&
mydriver_match(parent))
device_add_child(parent, "mydriver", -1);
}

mydriver_match() should check if you were given the acpi0 device.





I only need access to this memory location during the
probe of my driver to read some configuration data.


Is this pci configuration space ? If so, pci_read_config (man 9 pci)  
should be just what you need.


Regards,
--
Rui Paulo

___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: Writing device drivers: How to access a specific memory area?

2008-12-28 Thread Andre Albsmeier
On Thu, 25-Dec-2008 at 13:57:00 +, Rui Paulo wrote:
> 
> On 25 Dec 2008, at 09:53, Andre Albsmeier wrote:
> 
> > Hello all,
> >
> > I am writing a driver which needs to access memory at a
> > specific location. The location depends on what the BIOS
> > has configured into the host bridge. For example, my
> > current machine uses an Intel 975X chipset and the memory
> > location I am interested in has been set to 0xFED14000 and
> > is 16KB in size (this is MCHBAR of the 975X memory hub).
> 
> You probably just need to do something like:
> 
> rid = PCI_BAR(number);
> res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);

The problem was, that this memory belongs to acpi0
so I couldn't read it from my driver which has no
resources assigned to it. But, I found a way, see below...

> 
> And then,
> bus_read_4(res, offset from specified PCI BAR);
> 
> >
> >
> > I have no idea how to access this space from my driver.
> > I have played around with bus_alloc_resource() but this
> > only gives me back NULL.
> >
> > However, a devinfo -r gives me:
> >
> > nexus0
> >  npx0
> >  acpi0
> >  Interrupt request lines:
> >  9
> >  I/O ports:
> >  0x10-0x1f
> > ...
> >  0x800-0x87f
> >  I/O memory addresses:
> >  0x0-0x9
> >  0xc-0xd
> >  0xe-0xf
> >  0x10-0x7fff
> >  0xf000-0xf3ff
> >  0xfec0-0xfec00fff
> >  0xfed13000-0xfed19fff  <---
> >  0xfed1c000-0xfed1
> >  0xfed2-0xfed3
> >  0xfed5-0xfed8
> >  0xfee0-0xfee00fff
> >  0xffb0-0xffbf
> >  0xfff0-0x
> >cpu0
> > ...
> >
> > The line marked with <--- shows the range which includes
> > the location I am interested in. It is probably assigned
> > to the acpi0 device.
> >
> > How do I proceed from this? Do I have to hack around in
> > the ACPI-Code? I don't hope so ;-)
> 
> You'll probably need to create a fake ACPI child driver to access it.
> 
> 
> Create your identify routine with something like:
> 
> static void mydriver_identify(driver_t *driver, device_t parent)
> {
>   if (device_find_child(parent, "mydriver", -1) == NULL &&
>   mydriver_match(parent))
>   device_add_child(parent, "mydriver", -1);
> }
> 
> mydriver_match() should check if you were given the acpi0 device.

Found something easier: I just do a bus_set_resource() followed
by bus_alloc_resource_any(), access my host bridge registers,
and free things with bus_release_resource() followed by
bus_delete_resource().

> 
> 
> >
> >
> > I only need access to this memory location during the
> > probe of my driver to read some configuration data.
> 
> Is this pci configuration space ? If so, pci_read_config (man 9 pci)  

Unfortunately not. As I wrote, it is a 16k memory window
where the 975x maps a part of its config registers. The
address of this window can be read by pci_read_config( dev, 0x44, 4 ).
Then you can access the bridge's cXdrcY registers through
this memory window which I needed to determine the
machines RAM layout.

Thanks anyway for your help,

-Andre
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"