Re: kernel q
o.k., here is the story: we are developping a uwb (ultra wide band) network chip. this should be a wireless 100-500 Mbps with Qos communication chip. ( bluetooth and WiFi, beware ;-) the prototype i am working on has it's registers and rams mapped as memory on a PCI card. i tried using /dev/mem to access it, but it didn't work. so i tried looking at examples and builded my own driver. i am succesfull at accessing my card as a file. (/dev/uwb/0) i was not successful at accessing it as mmapped (i can mmap it, write/read to/from it, but it does not do the real writing/reading to/from the card, and i get no errors either). the only issue, is that when i do a read or write, even that the length of the copy_from_user or copy_to_user is 4 bytes long, it seems to read/write more than that so if i access (read) adress 0xa4, i get the register at 0xa0 also read. (probably being cached) arch is x86 (Pentium III) any idea ? cheers, erez. btw, here are the main code: static ssize_t uwb_dev_read (struct file *filp, char *buf, size_t count, loff_t * offp) { unsigned int num=(unsigned int)filp-private_data-1; unsigned long p=*offp; ssize_t ret = 0; int size; //printk(KERN_INFO UWB read: addr=%d, len=%d\n,(int)p,(int)count); //printk(KERN_INFO UWB num=%d, num_boards=%d\n,(int)num,(int)num_boards); if (numnum_boards) return -EFAULT; if (p(unsigned int)mem_size) return -EFAULT; size=MIN(count,(unsigned int)mem_size-p); size=MIN(size,4); //printk(KERN_INFO UWB read addres 0x%lx..0x%lx ... ,p,p+size-1); //printk(KERN_INFO UWB coping to user space\n); if (copy_to_user (buf, uwb_mem[num]+p, size)) return -EFAULT; ret=size; //printk(KERN_INFO UWB done read\n); //printk(%d bytes read \n,ret); *offp+=ret; return ret; } static ssize_t uwb_dev_write(struct file *filp, const char *buf, size_t count, loff_t * offp) { unsigned int num=(unsigned int)filp-private_data-1; unsigned long p=*offp; ssize_t ret = 0; int size; if (numnum_boards) return -EFAULT; if (p(unsigned int)mem_size) return -EFAULT; size=MIN(count,(unsigned int)mem_size-p); size=MIN(size,4); if (copy_from_user (uwb_mem[num]+p, buf, size)) return -EFAULT; ret=size; *offp+=ret; return ret; } static int uwb_dev_mmap(struct file * filp, struct vm_area_struct * vma) { unsigned int num=(unsigned int)filp-private_data-1; //unsigned int num=0; //unsigned long offset = vma-vm_pgoff PAGE_SHIFT; ssize_t ret = 0; unsigned long prot = pgprot_val(vma-vm_page_prot); if (boot_cpu_data.x86 3) prot |= _PAGE_PCD | _PAGE_PWT; vma-vm_page_prot = __pgprot(prot); /* * Accessing memory above the top the kernel knows about or * through a file pointer that was marked O_SYNC will be * done non-cached. */ //if (noncached_address(offset) || (file-f_flags O_SYNC)) // vma-vm_page_prot = pgprot_noncached(vma-vm_page_prot); /* Don't try to swap out physical pages.. */ vma-vm_flags |= VM_RESERVED; /* * Don't dump addresses that are not real memory to a core file. */ /* if (offset = __pa(high_memory) || (file-f_flags O_SYNC)) vma-vm_flags |= VM_IO; */ vma-vm_flags |= VM_IO; if (vma-vm_end-vma-vm_start mem_size[num]) ret= -EAGAIN; else if (remap_page_range(vma-vm_start, (unsigned long) uwb_mem[num], vma-vm_end-vma-vm_start, vma-vm_page_prot)) ret= -EAGAIN; printk (uwb: mmap, physical_ptr=0x%8X, size=0x%X, uwb num=%d, vm_ptr=0x%08X, ret=%d\n,(unsigned int) uwb_mem[num],(unsigned int)(vma-vm_end-vma-vm_start),(int)num,(unsigned int)vma-vm_start,(unsigned int)ret); return ret; } /* * uwb_init_one - look for and attempt to init a single UWB */ static int __init uwb_init_one (struct pci_dev *dev, int num) { int rc; //u8 hw_status; DPRINTK (ENTER\n); mem_size[num]=UWB_ADDR_END(dev)-UWB_ADDR(dev)+1; uwb_mem[num] = ioremap (UWB_ADDR(dev), mem_size[num]); if (uwb_mem[num] == NULL) { printk (KERN_ERR UWB cannot ioremap UWB Memory\n); DPRINTK (EXIT, returning -EBUSY\n); rc = -EBUSY; return rc; } //printk(KERN_INFO UWB found addr %lX..%lX\n,UWB_ADDR(dev),UWB_ADDR_END(dev)); DPRINTK (EXIT, returning 0\n); return 0; } static int __init uwb_init (void) { int rc=0; struct pci_dev *pdev; int num=0; int i; char name[15]; DPRINTK (ENTER\n); // init_MUTEX (uwb_open_sem); pci_for_each_dev(pdev) {
Re: kernel q
On Tue, 21 Oct 2003, Erez Doron wrote: o.k., here is the story: we are developping a uwb (ultra wide band) network chip. this should be a wireless 100-500 Mbps with Qos communication chip. ( bluetooth and WiFi, beware ;-) the prototype i am working on has it's registers and rams mapped as memory on a PCI card. i tried using /dev/mem to access it, but it didn't work. so i tried looking at examples and builded my own driver. You did something wrong there, since /dev/mem surely works for PCI MMIO regions. You can look at the kernel module in svgalib for a simple device driver that allows mmap to MMIO regions. i am succesfull at accessing my card as a file. (/dev/uwb/0) i was not successful at accessing it as mmapped (i can mmap it, write/read to/from it, but it does not do the real writing/reading to/from the card, and i get no errors either). the only issue, is that when i do a read or write, even that the length of the copy_from_user or copy_to_user is 4 bytes long, it seems to read/write more than that so if i access (read) adress 0xa4, i get the register at 0xa0 also read. (probably being cached) arch is x86 (Pentium III) any idea ? Look at the MTRR setup (cat /proc/mtrr). The default is uncached, so if your range is not in any of the MTRRs listed, it is accessed uncached by the CPU. btw, here are the main code: if (numnum_boards) return -EFAULT; if (p(unsigned int)mem_size) return -EFAULT; size=MIN(count,(unsigned int)mem_size-p); size=MIN(size,4); //printk(KERN_INFO UWB read addres 0x%lx..0x%lx ... ,p,p+size-1); //printk(KERN_INFO UWB coping to user space\n); if (copy_to_user (buf, uwb_mem[num]+p, size)) return -EFAULT; I would not use copy to user directly from IO regions, since you should access ioremapped regions with readb, readw, readl, rather than pointer derefernce. Try first reading the data, and then copying it to userspace. A similar remark holds for the writes, of course. Here's a working example from svgalib: case _IOC_NR(SVGAHELPER_READL): copy_from_user(iov,(char *)arg,sizeof(iov)); iov.val=readl(iov.port); copy_to_user((char *)arg,iov,sizeof(iov)); break; static int uwb_dev_mmap(struct file * filp, struct vm_area_struct * vma) { //if (noncached_address(offset) || (file-f_flags O_SYNC)) // vma-vm_page_prot = pgprot_noncached(vma-vm_page_prot); Why did you leave out this code? You do want the accesses to be uncached. -- Matan Ziv-Av. [EMAIL PROTECTED] = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: kernel q
afaik, /proc/bus/pci/XX/YY is configuration space and not memory space also: dd if=/dev/mem skip=physical adress bs=4 count=1 of=filename does not generate any read cycle to my pci card cheers, erez. Gleb Natapov wrote: Hello, On Tue, Oct 21, 2003 at 10:53:54AM +0200, Erez Doron wrote: o.k., here is the story: we are developping a uwb (ultra wide band) network chip. this should be a wireless 100-500 Mbps with Qos communication chip. ( bluetooth and WiFi, beware ;-) the prototype i am working on has it's registers and rams mapped as memory on a PCI card. i tried using /dev/mem to access it, but it didn't work. so i tried looking at examples and builded my own driver. The new way of doing it from userspace is by mmapping /proc/bus/pci/XX/YY AFAIK, but /dev/mem works for me. You must be doing something wrong. -- Gleb. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: kernel q
On Tue, Oct 21, 2003 at 02:24:19PM +0200, Erez Doron wrote: afaik, /proc/bus/pci/XX/YY is configuration space and not memory space it is configuration space when you read/write it and memory space when you mmap it. Look up the implementation of mmap for this file in kernel (drivers/pci/proc.c) Newest XFree86 uses this method instead of /dev/mem. also: dd if=/dev/mem skip=physical adress bs=4 count=1 of=filename does not generate any read cycle to my pci card You can't reach PCI address space by reading /dev/mem. Look at drivers/char/mem.c:read_mem /* * This funcion reads the *physical* memory. The f_pos points directly to the * memory location. */ static ssize_t read_mem(struct file * file, char * buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; unsigned long end_mem; ssize_t read; end_mem = __pa(high_memory); if (p = end_mem) return 0; ^ cheers, erez. Gleb Natapov wrote: Hello, On Tue, Oct 21, 2003 at 10:53:54AM +0200, Erez Doron wrote: o.k., here is the story: we are developping a uwb (ultra wide band) network chip. this should be a wireless 100-500 Mbps with Qos communication chip. ( bluetooth and WiFi, beware ;-) the prototype i am working on has it's registers and rams mapped as memory on a PCI card. i tried using /dev/mem to access it, but it didn't work. so i tried looking at examples and builded my own driver. The new way of doing it from userspace is by mmapping /proc/bus/pci/XX/YY AFAIK, but /dev/mem works for me. You must be doing something wrong. -- Gleb. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED] -- Gleb. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
kernel q
hi i am using copy_from_user and copy_to_user functions. how do i make that physical memory non cached ? ( it seems to write when it wants and read adresses i didnt ask it to read) cheers, erez. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: kernel q
On Mon, 20 Oct 2003, Erez Doron wrote: i am using copy_from_user and copy_to_user functions. how do i make that physical memory non cached ? ( it seems to write when it wants and read adresses i didnt ask it to read) can you explain what do you mean by 'reads when it wants to'? after you 'copy_from_user', your kernel-space buffer does not contain the data that exists in the user-space buffer? if this is the case - you seem to have some bug in your code. the same should be for the writing part, i.e. after 'copy_to_user', the user-space buffer should contain the desired text. why do you think caching is your problem, anyway? also, in what context do you use these functions? a system call? an interrupt handler? -- guy For world domination - press 1, or dial 0, and please hold, for the creator. -- nob o. dy = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: kernel q
Quoth Erez Doron: i am using copy_from_user and copy_to_user functions. how do i make that physical memory non cached ? The simplest way is to snarf a block of contiguous memory OUTside the kernel, export it and write to/read from it somehow (e.g. by mmap, etc). Cheerio -- ---OFCNL This is MY list. This list belongs to ME! I will flame anyone I want. Official Flamer/Cabal NON-Leader [EMAIL PROTECTED] = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: kernel q
On Mon, Oct 20, 2003 at 09:46:48PM +0200, Official Flamer/Cabal NON-Leader wrote: Quoth Erez Doron: i am using copy_from_user and copy_to_user functions. how do i make that physical memory non cached ? The simplest way is to snarf a block of contiguous memory OUTside the kernel, export it and write to/read from it somehow (e.g. by mmap, etc). Simplest, but it's also considered a fairly ugly hack :P Erez, what are you trying to do, and on which arch? how to make physical memory non cached is fairly architecture dependant, AFAIK. Cheers, Muli -- Muli Ben-Yehuda http://www.mulix.org signature.asc Description: Digital signature
Re: kernel q
Quoth Muli Ben-Yehuda: Simplest, but it's also considered a fairly ugly hack :P Ugly, yes. However, when you want performance and wish to avoid caching (the latter Erez states and the first I interpolate, possibly wrongly) and, self-admittedly, being much less conversant with optimization than you ;-) - I suspect he would also want contiguity which, notwithstanding the kmalloc call's availablity, is, under most real-life circumstances, an ineffective mechanism vis-a-vis its inability to claim a significant amount of memory, this being in use by the kernel itself and, therefore, not available for use for any significant or interesting size, namely - pretty much anything over a quarter meg, the latter number being the kernel's limit in any case, as far as I remeber. If you have parsed the above sentence, please suggest a more elegant solution and a less inelegant hack. And yes - it is a hack, but an effective one. physical memory non cached is fairly architecture dependant, AFAIK. I assume x86, which may be wrong. Erez? ObLanguage - Ah - verbal contortions. I seem to be the Sir Humphrey of Linux IL. -- ---OFCNL This is MY list. This list belongs to ME! I will flame anyone I want. Official Flamer/Cabal NON-Leader [EMAIL PROTECTED] = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: kernel q
On Mon, Oct 20, 2003 at 10:44:09PM +0200, Official Flamer/Cabal NON-Leader wrote: Quoth Muli Ben-Yehuda: Simplest, but it's also considered a fairly ugly hack :P Ugly, yes. However, when you want performance and wish to avoid caching (the latter Erez states and the first I interpolate, possibly wrongly) and, self-admittedly, being much less conversant with optimization than you ;-) - I suspect he would also want contiguity which, notwithstanding the kmalloc call's availablity, is, under most real-life circumstances, an ineffective mechanism vis-a-vis its inability to claim a significant amount of memory, this being in use by the kernel itself and, therefore, not available for use for any significant or interesting size, namely - pretty much anything over a quarter meg, the latter number being the kernel's limit in any case, as far as I remeber. If you have parsed the above sentence, please suggest a more elegant solution and a less inelegant hack. The elegance of a solution depends on how well it answers the requirements, of course, which are inadequately specified in this case. Assuming the need for a large contigous chunk of physical memory, allocating it when the kernel boots up through the usual facilities (get_free_pages) and exporting it to userspace via mmap on a device file seems and remap_page_range seem to be the prefered way to go. In general, the mem=XXX trick is working outside the system, and thus considered ugly. Any solution that achieves the same goal while working within the confines of the system, system being the Linux kernel in this case, scores points on elegance. vis-a-vis kmalloc's slab allocator's inherent limit of 131702 bytes, if you need a single physically contigous area larger than the above, you have several options: use mem=XXX, carve it out of the memory maps we build during boot (ugly and intrusive), or use alloc_bootmem to allocate it during boot. This is probably the best way to go with stock kernels. There's also a patch floating around since 1.3.xx days called 'bigphysarea' which does pretty much what the name implies, but it has never been included AFAIK. And yes - it is a hack, but an effective one. That was never contended, oh wielder-of-the-differential-scsi-cable. physical memory non cached is fairly architecture dependant, AFAIK. I assume x86, which may be wrong. Erez? ObLanguage - Ah - verbal contortions. I seem to be the Sir Humphrey of Linux IL. Oh, said contortions are quite pleasant. Do go on ;-) Cheers, Muli -- Muli Ben-Yehuda http://www.mulix.org signature.asc Description: Digital signature