From owner-svn-src-projects@FreeBSD.ORG Mon Dec 16 22:26:27 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 18A5AEA7; Mon, 16 Dec 2013 22:26:27 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id EC266147C; Mon, 16 Dec 2013 22:26:26 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rBGMQQH7048259; Mon, 16 Dec 2013 22:26:26 GMT (envelope-from andrew@svn.freebsd.org) Received: (from andrew@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id rBGMQPna048254; Mon, 16 Dec 2013 22:26:25 GMT (envelope-from andrew@svn.freebsd.org) Message-Id: <201312162226.rBGMQPna048254@svn.freebsd.org> From: Andrew Turner Date: Mon, 16 Dec 2013 22:26:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r259486 - in projects/specific_leg/sys/arm: arm include X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Dec 2013 22:26:27 -0000 Author: andrew Date: Mon Dec 16 22:26:25 2013 New Revision: 259486 URL: http://svnweb.freebsd.org/changeset/base/259486 Log: Add support for runtime l2 cache type detection. Currently only correct for SoCs with a pl310 l2 cache. Other armv6+ SoCs don't appear to have any l2 cache operations defined. Modified: projects/specific_leg/sys/arm/arm/busdma_machdep-v6.c projects/specific_leg/sys/arm/arm/cpufunc.c projects/specific_leg/sys/arm/arm/pl310.c projects/specific_leg/sys/arm/arm/pmap-v6.c projects/specific_leg/sys/arm/include/pmap.h Modified: projects/specific_leg/sys/arm/arm/busdma_machdep-v6.c ============================================================================== --- projects/specific_leg/sys/arm/arm/busdma_machdep-v6.c Mon Dec 16 22:07:49 2013 (r259485) +++ projects/specific_leg/sys/arm/arm/busdma_machdep-v6.c Mon Dec 16 22:26:25 2013 (r259486) @@ -1049,9 +1049,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm } else { sl = &map->slist[map->sync_count - 1]; if (map->sync_count == 0 || -#ifdef ARM_L2_PIPT - curaddr != sl->busaddr + sl->datacount || -#endif + (l2cache_type == L2CACHE_PIPT && + curaddr != sl->busaddr + sl->datacount) || vaddr != sl->vaddr + sl->datacount) { if (++map->sync_count > dmat->nsegments) goto cleanup; @@ -1171,15 +1170,38 @@ _bus_dmamap_fix_user(vm_offset_t buf, bu } #endif -#ifdef ARM_L2_PIPT -#define l2cache_wb_range(va, pa, size) cpu_l2cache_wb_range(pa, size) -#define l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range(pa, size) -#define l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range(pa, size) -#else -#define l2cache_wb_range(va, pa, size) cpu_l2cache_wb_range(va, size) -#define l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range(va, size) -#define l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range(va, size) -#endif +static inline void +l2cache_wb_range(vm_offset_t va, vm_offset_t pa, vm_size_t size) +{ + if (l2cache_type == L2CACHE_UNKNOWN) + return; + if (l2cache_type == L2CACHE_PIPT) + cpu_l2cache_wb_range(pa, size); + else + cpu_l2cache_wb_range(va, size); +} + +static inline void +l2cache_wbinv_range(vm_offset_t va, vm_offset_t pa, vm_size_t size) +{ + if (l2cache_type == L2CACHE_UNKNOWN) + return; + if (l2cache_type == L2CACHE_PIPT) + cpu_l2cache_wbinv_range(pa, size); + else + cpu_l2cache_wbinv_range(va, size); +} + +static inline void +l2cache_inv_range(vm_offset_t va, vm_offset_t pa, vm_size_t size) +{ + if (l2cache_type == L2CACHE_UNKNOWN) + return; + if (l2cache_type == L2CACHE_PIPT) + cpu_l2cache_inv_range(pa, size); + else + cpu_l2cache_inv_range(va, size); +} void _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) Modified: projects/specific_leg/sys/arm/arm/cpufunc.c ============================================================================== --- projects/specific_leg/sys/arm/arm/cpufunc.c Mon Dec 16 22:07:49 2013 (r259485) +++ projects/specific_leg/sys/arm/arm/cpufunc.c Mon Dec 16 22:26:25 2013 (r259486) @@ -1111,6 +1111,7 @@ struct cpu_functions cortexa_cpufuncs = struct cpu_functions cpufuncs; u_int cputype; u_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */ +l2cache l2cache_type = L2CACHE_UNKNOWN; #if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) || \ defined (CPU_ARM9E) || defined (CPU_ARM10) || defined (CPU_ARM1136) || \ Modified: projects/specific_leg/sys/arm/arm/pl310.c ============================================================================== --- projects/specific_leg/sys/arm/arm/pl310.c Mon Dec 16 22:07:49 2013 (r259485) +++ projects/specific_leg/sys/arm/arm/pl310.c Mon Dec 16 22:26:25 2013 (r259486) @@ -393,6 +393,7 @@ pl310_attach(device_t dev) cpufuncs.cf_l2cache_wbinv_range = pl310_wbinv_range; cpufuncs.cf_l2cache_inv_range = pl310_inv_range; cpufuncs.cf_l2cache_wb_range = pl310_wb_range; + l2cache_type = L2CACHE_PIPT; return (0); } Modified: projects/specific_leg/sys/arm/arm/pmap-v6.c ============================================================================== --- projects/specific_leg/sys/arm/arm/pmap-v6.c Mon Dec 16 22:07:49 2013 (r259485) +++ projects/specific_leg/sys/arm/arm/pmap-v6.c Mon Dec 16 22:26:25 2013 (r259486) @@ -206,13 +206,18 @@ int pmap_debug_level = 0; #define pa_to_pvh(pa) (&pv_table[pa_index(pa)]) -#ifdef ARM_L2_PIPT -#define pmap_l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range((pa), (size)) -#define pmap_l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range((pa), (size)) -#else -#define pmap_l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range((va), (size)) -#define pmap_l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range((va), (size)) -#endif +static void +pmap_l2cache_wbinv_range(vm_offset_t va, vm_offset_t pa, vm_size_t size) +{ + + if (l2cache_type == L2CACHE_UNKNOWN) + return; + + if (l2cache_type == L2CACHE_PIPT) + cpu_l2cache_wbinv_range(pa, size); + else + cpu_l2cache_wbinv_range(va, size); +} extern struct pv_addr systempage; Modified: projects/specific_leg/sys/arm/include/pmap.h ============================================================================== --- projects/specific_leg/sys/arm/include/pmap.h Mon Dec 16 22:07:49 2013 (r259485) +++ projects/specific_leg/sys/arm/include/pmap.h Mon Dec 16 22:26:25 2013 (r259486) @@ -52,6 +52,16 @@ #include #include + +typedef enum { + L2CACHE_UNKNOWN, + L2CACHE_VIVT, + L2CACHE_VIPT, + L2CACHE_PIPT, +} l2cache; + +extern l2cache l2cache_type; + /* * Pte related macros */ @@ -562,11 +572,14 @@ extern int pmap_needs_pte_sync; #define PMAP_INCLUDE_PTE_SYNC #endif -#ifdef ARM_L2_PIPT -#define _sync_l2(pte, size) cpu_l2cache_wb_range(vtophys(pte), size) -#else -#define _sync_l2(pte, size) cpu_l2cache_wb_range(pte, size) -#endif +#define _sync_l2(pte, size) \ +do { \ + vm_offset_t __pte = (pte); \ + \ + if (__pte == L2CACHE_PIPT) \ + __pte = vtophys(__pte); \ + cpu_l2cache_wb_range(__pte, size); \ +} while (0) #define PTE_SYNC(pte) \ do { \