Date: Tue, 22 Apr 2008 23:01:28 +0200 From: Hans Petter Selasky <hselasky@c2i.net> To: Mark Tinguely <tinguely@casselton.net> Cc: freebsd-arm@freebsd.org, jhb@freebsd.org Subject: Re: AT91RM9200 and possibly other ARM targets are broken in 8-current after recent commit (more) Message-ID: <200804222301.28841.hselasky@c2i.net> In-Reply-To: <200804222024.m3MKOXZN097466@casselton.net> References: <200804222024.m3MKOXZN097466@casselton.net>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804222301.28841.hselasky>