* Mapping PADDR into virtual memory problem.
@ 2016-07-13 21:25 joe moriarty
2016-07-13 21:45 ` Rob Gardner
2016-07-13 21:52 ` David Miller
0 siblings, 2 replies; 3+ messages in thread
From: joe moriarty @ 2016-07-13 21:25 UTC (permalink / raw)
To: sparclinux
I'm stuck trying to get this to work and I don't know why what I am
doing doesn't work. I'm hoping maybe someone on here has a suggestion.
The piece of code below is suppose to take a PADDR and memory map it to
a kernel address. The output I get from the code below is shown here:
PCI: Enabling device: (0002:08:00.0), cmd 3
vm_area->phys_addr=0x0008080100040000
vaddr=0x0000000136180000
nr_pages2
page protection =0x9C08080100040690
I/O address location mapped
ioread32 RegBase[0] = 0x00000000
vread RegBase[0] = 0x00000000
PCI: Enabling device: (0002:09:00.0), cmd 3
vm_area->phys_addr=0x0008080110040000
vaddr=0x0000000136200000
nr_pages2
page protection =0x9C08080110040690
I/O address location mapped
ioread32 RegBase[0] = 0x00000000
vread RegBase[0] = 0x00000000
PCI: Enabling device: (0002:0a:00.0), cmd 3
vm_area->phys_addr=0x0008080120040000
vaddr=0x0000000136280000
nr_pages2
page protection =0x9C08080120040690
I/O address location mapped
ioread32 RegBase[0] = 0x00000000
vread RegBase[0] = 0x00000000
PCI: Enabling device: (0002:0b:00.0), cmd 3
vm_area->phys_addr=0x0008080130040000
vaddr=0x0000000136300000
nr_pages2
page protection =0x9C08080130040690
I/O address location mapped
ioread32 RegBase[0] = 0x00000000
vread RegBase[0] = 0x00000000
I know I should be getting 0x00EA0408 from RegBase[0].
Do you see anything obvious that is wrong?
void __iomem *ioremap_prefetch(unsigned long offset, unsigned long size)
{
struct vm_struct *vm_area = NULL;
unsigned long vaddr;
int error = 0, tmp_val;
pgprot_t prot = __pgprot(pgprot_val(PAGE_SHARED) |
(_PAGE_PADDR_4V &
offset));
void __iomem *ret_addr;
/*
* Get Contiguous Kernel Virtual Memory Area. Note:
get_vm_area will
* page align the area to use.
*/
vm_area = get_vm_area(size, VM_IOREMAP | VM_NO_GUARD);
if (!vm_area) {
printk("Unable to allocate Contiguous Virtual Memory
for Mapping
\n");
error = 1;
goto done;
}
vm_area->phys_addr = (phys_addr_t)offset;
vm_area->nr_pages = size / PAGE_SIZE;
vaddr = (unsigned long)vm_area->addr;
printk("vm_area->phys_addr=0x%016llX\n", (unsigned long
long)vm_area->ph
ys_addr);
printk("vaddr=0x%016llX\n", (unsigned long long)vaddr);
printk("nr_pages=%d\n", vm_area->nr_pages);
printk("page protection =0x%08lX\n", (unsigned
long)pgprot_val(prot));
if(ioremap_page_range((unsigned long)vm_area->addr,
(unsigned long)vm_area->addr + size,
vm_area->phys_addr, prot)) {
printk("Unable to Map Page Range.\n");
error = 1;
goto done;
}
else {
printk("I/O address location mapped\n");
ret_addr = vm_area->addr;
printk("ioread32 RegBase[0] = 0x%08X\n",
ioread32(ret_addr));
vread((char *)&tmp_val, ret_addr, 4);
printk("vread RegBase[0] = 0x%08X\n", tmp_val);
}
done:
if(error) {
/*
* Cleanup After oneself
*/
free_vm_area(vm_area);
ret_addr = 0;
}
return (ret_addr);
//return ((void __iomem *)offset);
}
Thanks In Advance,
Joe
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Mapping PADDR into virtual memory problem.
2016-07-13 21:25 Mapping PADDR into virtual memory problem joe moriarty
@ 2016-07-13 21:45 ` Rob Gardner
2016-07-13 21:52 ` David Miller
1 sibling, 0 replies; 3+ messages in thread
From: Rob Gardner @ 2016-07-13 21:45 UTC (permalink / raw)
To: sparclinux
On 07/13/2016 03:25 PM, joe moriarty wrote:
> I'm stuck trying to get this to work and I don't know why what I am
> doing doesn't work. I'm hoping maybe someone on here has a
> suggestion. The piece of code below is suppose to take a PADDR and
> memory map it to a kernel address. The output I get from the code
> below is shown here:
>
> PCI: Enabling device: (0002:08:00.0), cmd 3
> vm_area->phys_addr=0x0008080100040000
> vaddr=0x0000000136180000
> nr_pages2
> page protection =0x9C08080100040690
> I/O address location mapped
> ioread32 RegBase[0] = 0x00000000
> vread RegBase[0] = 0x00000000
> PCI: Enabling device: (0002:09:00.0), cmd 3
> vm_area->phys_addr=0x0008080110040000
> vaddr=0x0000000136200000
> nr_pages2
> page protection =0x9C08080110040690
> I/O address location mapped
> ioread32 RegBase[0] = 0x00000000
> vread RegBase[0] = 0x00000000
> PCI: Enabling device: (0002:0a:00.0), cmd 3
> vm_area->phys_addr=0x0008080120040000
> vaddr=0x0000000136280000
> nr_pages2
> page protection =0x9C08080120040690
> I/O address location mapped
> ioread32 RegBase[0] = 0x00000000
> vread RegBase[0] = 0x00000000
> PCI: Enabling device: (0002:0b:00.0), cmd 3
> vm_area->phys_addr=0x0008080130040000
> vaddr=0x0000000136300000
> nr_pages2
> page protection =0x9C08080130040690
> I/O address location mapped
> ioread32 RegBase[0] = 0x00000000
> vread RegBase[0] = 0x00000000
>
> I know I should be getting 0x00EA0408 from RegBase[0].
> Do you see anything obvious that is wrong?
>
> void __iomem *ioremap_prefetch(unsigned long offset, unsigned long size)
> {
> struct vm_struct *vm_area = NULL;
> unsigned long vaddr;
> int error = 0, tmp_val;
> pgprot_t prot = __pgprot(pgprot_val(PAGE_SHARED) |
> (_PAGE_PADDR_4V &
> offset));
I don't understand why offset is put into prot. And maybe just use
PAGE_KERNEL here?
> void __iomem *ret_addr;
>
> /*
> * Get Contiguous Kernel Virtual Memory Area. Note:
> get_vm_area will
> * page align the area to use.
> */
> vm_area = get_vm_area(size, VM_IOREMAP | VM_NO_GUARD);
> if (!vm_area) {
> printk("Unable to allocate Contiguous Virtual Memory
> for Mapping
> \n");
> error = 1;
> goto done;
> }
> vm_area->phys_addr = (phys_addr_t)offset;
> vm_area->nr_pages = size / PAGE_SIZE;
> vaddr = (unsigned long)vm_area->addr;
> printk("vm_area->phys_addr=0x%016llX\n", (unsigned long
> long)vm_area->ph
> ys_addr);
> printk("vaddr=0x%016llX\n", (unsigned long long)vaddr);
> printk("nr_pages=%d\n", vm_area->nr_pages);
> printk("page protection =0x%08lX\n", (unsigned
> long)pgprot_val(prot));
> if(ioremap_page_range((unsigned long)vm_area->addr,
> (unsigned long)vm_area->addr + size,
> vm_area->phys_addr, prot)) {
> printk("Unable to Map Page Range.\n");
> error = 1;
> goto done;
> }
> else {
> printk("I/O address location mapped\n");
> ret_addr = vm_area->addr;
> printk("ioread32 RegBase[0] = 0x%08X\n",
> ioread32(ret_addr));
ioread32 I think assumes the address you are reading from is physical.
> vread((char *)&tmp_val, ret_addr, 4);
vread explicitly returns zeros if the vm area was created with VM_IOREMAP.
Since you seem to have a virtual address now that maps to your desired
physical address, why can't you simply dereference that virtual address?
ie,
x = *(int *)ret_addr;
Rob
> printk("vread RegBase[0] = 0x%08X\n", tmp_val);
> }
>
> done:
> if(error) {
> /*
> * Cleanup After oneself
> */
> free_vm_area(vm_area);
> ret_addr = 0;
> }
> return (ret_addr);
> //return ((void __iomem *)offset);
> }
>
> Thanks In Advance,
> Joe
> --
> To unsubscribe from this list: send the line "unsubscribe sparclinux" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Mapping PADDR into virtual memory problem.
2016-07-13 21:25 Mapping PADDR into virtual memory problem joe moriarty
2016-07-13 21:45 ` Rob Gardner
@ 2016-07-13 21:52 ` David Miller
1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2016-07-13 21:52 UTC (permalink / raw)
To: sparclinux
vread() always provides all zeros for VM_IOREMAP areas.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-07-13 21:52 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-13 21:25 Mapping PADDR into virtual memory problem joe moriarty
2016-07-13 21:45 ` Rob Gardner
2016-07-13 21:52 ` David Miller
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.