Writing device drivers: How to access a specific memory area?
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?
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?
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"