Date: Wed, 19 Dec 2012 09:56:28 +0100 From: Hans Petter Selasky <hselasky@c2i.net> To: Warner Losh <imp@bsdimp.com> Cc: Oleksandr Tymoshenko <gonzo@freebsd.org>, Andrew Turner <andrew@fubar.geek.nz>, freebsd-usb@freebsd.org Subject: Re: EHCI on armv6 with Write-Back caches Message-ID: <201212190956.28609.hselasky@c2i.net> In-Reply-To: <1482FC19-720A-480A-BAD2-C8CD306E2E5F@bsdimp.com> References: <20121218204931.5322922d@fubar.geek.nz> <201212182044.11326.hselasky@c2i.net> <1482FC19-720A-480A-BAD2-C8CD306E2E5F@bsdimp.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi again, Different vendors use different naming conventions about sync operations. Maybe we should start defining some names and agree about that first? usb_pc_cpu_flush: This function is a system abstraction which is supposed to ensure that all CPU cached data for the given buffer is written to RAM before this function returns. usb_pc_cpu_invalidate: This function is a system abstraction which is supposed to ensure that all CPU cached data is cleared for the given buffer. These functions have been carefully added in all the USB drivers using DMA. Atomicity: I understand that the ARM hardware is not always compatible to this approach. 1) Flushing data to RAM is not a problem in any case? Do you agree? 2) Invalidating data is a problem, because invalidation can cause nearby data to be cleared aswell. So basically for those systems which are not handling this, flushing data means a lock of all CPU's until the flush/invalidate sequence is complete? Any dispute about this? If the CPU does not support certain features we cannot have an efficient system. It is like having a CPU which doesn't support switching off interrupt levels, like an 8-bit AVR. Then no matter how you twist it, you cannot postpone an interrupt to a software thread. Same goes for DMA support. If their DMA engine doesn't support byte granularity and possibility to flush/invalidate on a per-byte basis, then implement a global system lock to flush/invalidate data like I suggest, if this is not doable in the hardware by the CPU instruction set. The approach that I was recommended several years ago, is that I can pass a pointer to a buffer, which then can be transferred by the USB engine. This pointer can be any pointer except NULL. 3) As per my knowledge, using busdma to allocate a separate buffer for a 13- byte buffer, results in having a buffer of PAGE_SIZE bytes allocated. 4) BUSDMA experts: Please verify that the flags passed to bus_dmamap_sync() causes the exact behaviour has listed on top of this e-mail to occur in the following two functions in sys/dev/usb/usb_busdma.c void usb_pc_cpu_invalidate(struct usb_page_cache *pc) { if (pc->page_offset_end == pc->page_offset_buf) { /* nothing has been loaded into this page cache! */ return; } /* * TODO: We currently do XXX_POSTREAD and XXX_PREREAD at the * same time, but in the future we should try to isolate the * different cases to optimise the code. --HPS */ bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTREAD); bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD); } void usb_pc_cpu_flush(struct usb_page_cache *pc) { if (pc->page_offset_end == pc->page_offset_buf) { /* nothing has been loaded into this page cache! */ return; } bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE); } --HPS
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212190956.28609.hselasky>