From owner-freebsd-arm@FreeBSD.ORG Tue Jan 8 19:48:56 2008 Return-Path: Delivered-To: freebsd-arm@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7D1FA16A419 for ; Tue, 8 Jan 2008 19:48:56 +0000 (UTC) (envelope-from tinguely@casselton.net) Received: from casselton.net (casselton.net [63.165.140.2]) by mx1.freebsd.org (Postfix) with ESMTP id 1258A13C448 for ; Tue, 8 Jan 2008 19:48:55 +0000 (UTC) (envelope-from tinguely@casselton.net) Received: from casselton.net (localhost [127.0.0.1]) by casselton.net (8.13.8/8.13.8) with ESMTP id m08JmqZR006159; Tue, 8 Jan 2008 13:48:52 -0600 (CST) (envelope-from tinguely@casselton.net) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=casselton.net; s=ccnMail; t=1199821732; bh=lwIUTXnKD5hn+dUE4c/EUUeTKjGl0JbRcH6/FuE 06Lg=; h=Date:From:Message-Id:To:Subject; b=Z7laI0o7aSvCRjj1N/y4/Ci DMcDZJmjnUi0GsqfI4U/As/WvIeh7aTU6l7wEr05/T2tzn6NTobGP+Pn/9MzE/anL75 M/zV5YjnnZuQ0XhtATVRaBpNXjv6oD5IWzP2i2Qj8hoU8z8EXf82nw8uP74KaVQt+ZV m3Nej/I2FymDec= Received: (from tinguely@localhost) by casselton.net (8.13.8/8.13.8/Submit) id m08Jmpoa006156; Tue, 8 Jan 2008 13:48:51 -0600 (CST) (envelope-from tinguely) Date: Tue, 8 Jan 2008 13:48:51 -0600 (CST) From: Mark Tinguely Message-Id: <200801081948.m08Jmpoa006156@casselton.net> To: freebsd-arm@freebsd.org, mlfbsd@ci0.org Cc: Subject: ARM pmap cache flushed after PT modification. X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to the StrongARM Processor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Jan 2008 19:48:56 -0000 Since caches for ARM processor before version 6 use virtually indexed, virtual tagged caches, the cache should be written back (flushed) before altering the page table. See between the VVVV and ^^^^ the order is clear page tables, then write back the caches. void pmap_remove_pages(pmap_t pmap) { struct pv_entry *pv, *npv; struct l2_bucket *l2b = NULL; vm_page_t m; pt_entry_t *pt; vm_page_lock_queues(); PMAP_LOCK(pmap); for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) { if (pv->pv_flags & PVF_WIRED) { /* The page is wired, cannot remove it now. */ npv = TAILQ_NEXT(pv, pv_plist); continue; } pmap->pm_stats.resident_count--; l2b = pmap_get_l2_bucket(pmap, pv->pv_va); KASSERT(l2b != NULL, ("No L2 bucket in pmap_remove_pages")); pt = &l2b->l2b_kva[l2pte_index(pv->pv_va)]; m = PHYS_TO_VM_PAGE(*pt & L2_ADDR_MASK); #ifdef ARM_USE_SMALL_ALLOC KASSERT((vm_offset_t)m >= alloc_firstaddr, ("Trying to access non-existent page va %x pte %x", pv->pv_va, *pt)); #else KASSERT((vm_offset_t)m >= KERNBASE, ("Trying to access non-existent page va %x pte %x", pv->pv_va, *pt)); #endif VVVVVVVVVV page table cleared *pt = 0; ^^^^^^^^^^ page table cleared PTE_SYNC(pt); npv = TAILQ_NEXT(pv, pv_plist); pmap_nuke_pv(m, pmap, pv); if (TAILQ_EMPTY(&m->md.pv_list)) vm_page_flag_clear(m, PG_WRITEABLE); pmap_free_pv_entry(pv); pmap_free_l2_bucket(pmap, l2b, 1); } vm_page_unlock_queues(); VVVVVVVVVVVVVVVVVVVVVVVV cache written back cpu_idcache_wbinv_all(); ^^^^^^^^^^^^^^^^^^^^^^^^ cache written back cpu_tlb_flushID(); cpu_cpwait(); PMAP_UNLOCK(pmap); } --Mark Tinguely.