AT91RM9200 and possibly other ARM targets are broken in
8-current after recent commit (more)
Hans Petter Selasky
hselasky at c2i.net
Tue Apr 22 21:00:12 UTC 2008
Hi Mark,
Here is the modified and compiled code:
#define USBD_P2U POINTER_TO_UNSIGNED
static void
dumppv(vm_offset_t kva)
{
struct pv_entry *pv;
pd_entry_t *pde;
pt_entry_t *pte;
vm_paddr_t pa;
struct vm_page *pg;
printf("dumping 0x%08x ", kva);
vm_page_lock_queues(); /* XXX paranoid XXX */
/* get the physical address */
pa = pmap_kextract(kva);
if (pa == 0) {
printf("dumppv: 0x%08x no mapping\n", kva);
vm_page_unlock_queues();
return;
}
/* find the vm_page for physical address */
pg = PHYS_TO_VM_PAGE(pa);
if (pg == NULL) {
printf("dumppv: 0x%08x 0x%08x no vm_page\n", kva, pa);
vm_page_unlock_queues();
return;
}
/* dump the vm_page attributes */
printf("dumppv attrs: 0x%08x\n", pg->md.pvh_attrs);
/* run through all those that share the page */
TAILQ_FOREACH(pv, &(pg->md.pv_list), pv_list) {
/* indicate kernel or user mapping */
if (pv->pv_pmap == pmap_kernel())
printf ("dumppv kpv: ");
else
printf ("dumppv upv: ");
/* print entry */
printf("0x%08x 0x%08x 0x%08x ", USBD_P2U(pv->pv_pmap), pv->pv_va, pv->pv_flags);
/* print the PDE or PTE which will hold caching */
if (pmap_get_pde_pte(pv->pv_pmap, pv->pv_va, &pde, &pte)) {
if (pmap_pde_section(pde))
printf("sec: 0x%08x", *pde);
else
printf("pte: 0x%08x 0x%08x", *pde, *pte);
}
printf("\n");
}
vm_page_unlock_queues();
return;
}
This is what I get:
usbd_pc_alloc_mem:
dumping 0xcc009500 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc00a480 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc00b400 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc00c380 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc00d300 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc00e280 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc00f200 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc010180 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc011100 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc012080 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc013000 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc014e80 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc015e00 dumppv attrs: 0x00000000
usbd_pc_alloc_mem:
dumping 0xcc016d80 dumppv attrs: 0x00000000
usbd_pc_load_mem:
dumping 0xc1544150 dumppv attrs: 0x00000000
usbd_pc_load_mem:
dumping 0xc1544148 dumppv attrs: 0x00000000
usbd_pc_load_mem:
dumping 0xc1544150 dumppv attrs: 0x00000000
Does it make any sense to you? Looks like the page structure is not initialised.
--HPS
On Tuesday 22 April 2008, Mark Tinguely wrote:
> > Line 2730:
> >
> > /* allocate memory */
> > if (bus_dmamem_alloc(
> > utag->tag, &ptr, (BUS_DMA_WAITOK | BUS_DMA_COHERENT), &map))
> > { goto error;
> > }
> >
> > > I *think* this new address lives in DMA S/G lists and should not be
> > > mapped into an address space except to temporarily to copy data
> > > in/out. I will assume this assumption is incorrect and look through
> > > the pmap code all over again.
> >
> > Is there a function I can call that will tell if the memory I get is in
> > cache enabled memory or not ?
> >
> > If there are any prints you want me to add in the kernel code I can
> > easily do that within short time.
>
> /* Assuming the calling VA is mapped into the KVM - put into arm/pmap.c
> *
> * kva is the kernel virtual address of the page to test.
> *
> * pvh_attrs/pv_flags are listed in include/pmap.h
> * the PDE/PTE will have cache information too.
> *
> */
> void
> dumppv(vm_offset_t kva)
> {
> struct pv_entry *pv;
> pd_entry_t *pde;
> pt_entry_t *pte;
> vm_paddr_t pa;
> struct vm_page pg;
>
> vm_page_lock_queues(); /* XXX paranoid XXX */
> /* get the physical address */
> pa = pmap_kextract(kva);
> if (pa == 0) {
> printf("dumppv: 0x%08x no mapping\n", kva);
> vm_page_unlock_queues();
> return;
> }
> /* find the vm_page for physical address */
> pg = PHYS_TO_VM_PAGE(pa);
> if (pg == NULL) {
> printf("dumppv: 0x%08x 0x%08x no vm_page\n", kva, pa);
> vm_page_unlock_queues();
> return;
> }
>
> /* dump the vm_page attributes */
> printf("dumppv attrs: 0x%08x\n", pg->md.pvh_attrs);
>
> /* run through all those that share the page */
> TAILQ_FOREACH(pv, pg->md.pv_list, pv_list) {
> /* indicate kernel or user mapping */
> if (pv->pv_pmap == pmap_kernel())
> printf ("dumppv kpv: ");
> else
> printf ("dumppv upv: ");
> /* print entry */
> printf("0x%08x 0x%08x 0x%08x ", pv->pv_pmap, pv->pv_va,
> pv->pv_flags); /* print the PDE or PTE which will hold caching */
> if (pmap_get_pde_pte(pv->pv_pmap, pv->pv_va, &pde, &pte)) {
> if (pmap_pde_section(pde))
> printf("sec: 0x%08x", *pde);
> else
> printf("pte: 0x%08x 0x%08x", *pde, *pte);
> }
> printf("\n");
> }
> vm_page_unlock_queues();
> }
>
> Warning Will Rogers .... This is crude attempt using existing routines.
> Untested, Uncompiled - do not use in a routine that already locked the
> the pmap and vm_page.
>
> > I think what has happend is that when the USB code is reading back the
> > OHCI transfer descriptors after that the transfer has completed we are
> > still looking at the old length field which then tells the USB stack that
> > the transfer is short. It is not "SET_CONFIG" that fails, but probably
> > reading the USB descriptors.
> >
> > > 2) set configuration has a USBD_ERR_SHORT_XFER error.
> > >
> > > I don't know if turning on USB debug printing will give more clues.
> >
> > If I turn on full debugging the problem disappears, which I think is
> > because the CPU cache is used up due to the excessive prints which the
> > following debug level settings cause:
> >
> > sysctl hw.usb.ohci.debug=16
> > sysctl hw.usb.debug=15
>
> Strange that the debug cause things to work. filling the cache does not not
> make sense to me. adding another process map to mix would. Does it start
> working with the debug levels are very small (like 1)?
>
> > > I will look through the pmap code and see if I can chase up something.
> >
> > I see one problem:
> >
> > "malloc" is used by BUS-DMA to allocate DMA memory having a size less
> > than PAGE_SIZE. What happens when you have multiple DMA allocations in
> > the same PAGE and you then turn on/off the CPU caching on a per
> > allocation/free basis ?
> >
> > Mark, I really appreciate that you look into this.
>
> Walking through the pmap stuff will take a long, long time (days).
> I guess I need to chase down how add a COHERENT mapping.
>
> Maybe the dumppv() will find something and not crash on you.
>
> --Mark Tinguely
More information about the freebsd-arm
mailing list