Date: Fri, 18 Nov 2005 13:51:25 +0200 (EET) From: Dmitry Pryanishnikov <dmitry@atlantis.dp.ua> To: freebsd-hackers@freebsd.org Subject: Physical memory access from kld Message-ID: <20051118124856.F199@atlantis.atlantis.dp.ua>
next in thread | raw e-mail | index | archive | help
Hello! I'm trying to add Intel 875P chipset support for ecc.ko module. Basically this module outputs whether chipset supports and utilizes ECC, how much memory does it have, and whether there were memory errors. Well, this chipset has a very confusing architecture. Instead of having all relevant bits in PCI device configuration space, Intel has moved part of important DRAM controller registers into memory-mapped region, which is in turn controlled by the Overflow device 6, which isn't (in turn) even available by default. Many thanks to the author of http://www.x86-secret.com/articles/tweak/pat/patsecrets-2.htm for making it possible to access it at all - Intel's pdf doesn't even mention special register 0xF4 of Device 0! Very confusing desing, much worse than previous Intel chips ;( So, what tricks should I do in order to access memory-mapped registers of this "hidden" device 6? I wrote the code (currently under FreeBSD-4, but I want to port it then to RELENG_6) that enables device 6. Luckily BAR6 (starting address of memory-mapped registers) has been set up correctly by the mobo's (D875PBZ) BIOS. I can even "dd if=/dev/mem skip=xxx" and read those registers. But obviously I can't just dereference the pointer read from BAR6 since this physical address isn't mapped in kernel's virtual address space. What API should I use in order to map it in RELENG_4? In RELENG_6? And how to construct 'pcicfgregs' object for this "shadow" Overflow device under RELENG_6? During boot this device is invisible, so OS doesn't create 'pcicfgregs' for it. Under RELENG_4 all is simple: static pcicfgregs pci_cfg,pci_cfg2; ... bzero(cfgp, sizeof pci_cfg); pci_cfg.slot = 0; pci_cfg.func = 0; ... pci_cfg2 = pci_cfg; pci_cfg2.slot = 6 ; pci_cfg2.func = 0; and voila - pci_cfgread() / pci_cfgwrite() are happy. But under RELENG_6 there is no such API, and pci_read_config() / pci_write_config() do require valid (pcicfgregs *)->dev. So for Device 0 I'm just using OS-created objects: STAILQ_FOREACH(dinfo,&pci_devq,pci_links) { cfgp = &dinfo->cfg; if (cfgp->baseclass != PCIC_BRIDGE) continue; if (cfgp->subclass != PCIS_BRIDGE_HOST) continue; /* Here I have valid "pcicfgregs *cfgp" */ How to create valid *cfgp for Device 6? Sincerely, Dmitry -- Atlantis ISP, System Administrator e-mail: dmitry@atlantis.dp.ua nic-hdl: LYNX-RIPE
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051118124856.F199>