Date: Mon, 3 Apr 2006 07:14:48 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 94511 for review Message-ID: <200604030714.k337Emo4057962@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=94511 Change 94511 by kmacy@kmacy_storage:sun4v_work on 2006/04/03 07:13:54 add pmap_ipi add SMP support to page invalidate functions some cleanup fix bug where we weren't mapping part OFW space Affected files ... .. //depot/projects/kmacy_sun4v/src/sys/sun4v/include/pmap.h#9 edit .. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/pmap.c#35 edit Differences ... ==== //depot/projects/kmacy_sun4v/src/sys/sun4v/include/pmap.h#9 (text+ko) ==== @@ -69,7 +69,8 @@ struct tte_hash *pm_hash; TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */ struct hv_tsb_info pm_tsb; - cpumask_t pm_active; + cpumask_t pm_active; /* mask of cpus currently using pmap */ + cpumask_t pm_tlbactive; /* mask of cpus that have used this pmap */ struct pmap_statistics pm_stats; }; ==== //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/pmap.c#35 (text+ko) ==== @@ -113,8 +113,6 @@ vm_offset_t virtual_end; vm_offset_t kernel_vm_end; vm_offset_t vm_max_kernel_address; -vm_paddr_t kernel_phys; - #ifndef PMAP_SHPGPERPROC #define PMAP_SHPGPERPROC 200 @@ -127,7 +125,9 @@ static int pv_entry_count = 0, pv_entry_max = 0, pv_entry_high_water = 0; int pmap_debug = 0; static int context = 1; /* XXX */ - +static int permanent_mappings = 0; +static uint64_t nucleus_memory; +static uint64_t nucleus_mappings[2]; /* * Kernel pmap. */ @@ -359,7 +359,7 @@ pmap = vmspace_pmap(td->td_proc->p_vmspace); oldpmap = PCPU_GET(curpmap); #if defined(SMP) - atomic_clear_long(&oldpmap->pm_active, PCPU_GET(cpumask)); + atomic_clear_int(&oldpmap->pm_active, PCPU_GET(cpumask)); pmap->pm_active = PCPU_GET(cpumask); #else oldpmap->pm_active &= ~1; @@ -473,7 +473,6 @@ */ #ifdef notyet tsb_8k_size = virtsz >> (PAGE_SHIFT - TTE_SHIFT); - DPRINTF("tsb_8k_size is 0x%lx\n", tsb_8k_size); #else /* avoid alignment complaints from the hypervisor */ tsb_8k_size = PAGE_SIZE_4M; @@ -482,6 +481,7 @@ pa = pmap_bootstrap_alloc(tsb_8k_size); if (pa & PAGE_MASK_4M) panic("pmap_bootstrap: tsb unaligned\n"); + DPRINTF("tsb_8k_size is 0x%lx, tsb_8k_pa is 0x%lx\n", tsb_8k_size, pa); kernel_td[TSB8K_INDEX].hvtsb_idxpgsz = TTE8K; kernel_td[TSB8K_INDEX].hvtsb_assoc = 1; kernel_td[TSB8K_INDEX].hvtsb_ntte = (tsb_8k_size >> TTE_SHIFT); @@ -531,7 +531,7 @@ */ mmu_fault_status_area = pmap_bootstrap_alloc(MMFSA_SIZE*MAXCPU); - proc0_mem = pmap_bootstrap_alloc(PAGE_SIZE*4*40); + proc0_mem = pmap_bootstrap_alloc(PAGE_SIZE*4*400); /* * Allocate and map the message buffer. */ @@ -559,16 +559,6 @@ for (i = 0; phys_avail[i + 2] != 0; i += 2) ; Maxmem = sparc64_btop(phys_avail[i + 1]); - /* - * setup direct mappings - * - */ - pa = PAGE_SIZE_4M; - for (i = 0; phys_avail[i + 2] != 0; i += 2) - for (; pa < phys_avail[i + 1]; pa += PAGE_SIZE_4M) { - tsb_set_tte(&kernel_td[TSB4M_INDEX], TLB_PHYS_TO_DIRECT(pa), - pa | TTE_KERNEL | VTD_4M, 0); - } /* * Add the prom mappings to the kernel tsb. @@ -595,24 +585,28 @@ translations[i].om_size, translations[i].om_start, translations[i].om_tte); - if (translations[i].om_size == PAGE_SIZE_4M && - translations[i].om_start == KERNBASE) { - kernel_phys = pa = TTE_GET_PA(translations[i].om_tte); + (translations[i].om_start == KERNBASE || + translations[i].om_start == KERNBASE + PAGE_SIZE_4M)) { DPRINTF("mapping permanent translation\n"); - error = hv_mmu_map_perm_addr((char *)translations[i].om_start, KCONTEXT, - pa | TTE_KERNEL | VTD_4M, MAP_ITLB | MAP_DTLB); + pa = TTE_GET_PA(translations[i].om_tte); + error = hv_mmu_map_perm_addr((char *)translations[i].om_start, + KCONTEXT, pa | TTE_KERNEL | VTD_4M, MAP_ITLB | MAP_DTLB); + nucleus_mappings[permanent_mappings++] = pa; + nucleus_memory += PAGE_SIZE_4M; + +#ifdef SMP + mp_add_nucleus_mapping(translations[i].om_start, + pa | TTE_KERNEL | VTD_4M); +#endif + if (error != H_EOK) panic("map_perm_addr returned error=%ld", error); continue; - } -#if 1 - else if (translations[i].om_start < VM_MIN_PROM_ADDRESS || + } else if (translations[i].om_start < VM_MIN_PROM_ADDRESS || translations[i].om_start > VM_MAX_PROM_ADDRESS) { continue; - } -#endif - else { + } else { for (off = 0; off < translations[i].om_size; off += PAGE_SIZE) { va = translations[i].om_start + off; @@ -624,6 +618,18 @@ } } + + /* + * setup direct mappings + * + */ + pa = PAGE_SIZE_4M; + for (i = 0; phys_avail[i + 2] != 0; i += 2) + for (; pa < phys_avail[i + 1]; pa += PAGE_SIZE_4M) { + tsb_set_tte(&kernel_td[TSB4M_INDEX], TLB_PHYS_TO_DIRECT(pa), + pa | TTE_KERNEL | VTD_4M, 0); + } + /* * Get the available physical memory ranges from /memory/reg. These * are only used for kernel dumps, but it may not be wise to do prom @@ -639,6 +645,7 @@ pm = kernel_pmap; pm->pm_active = ~0; + pm->pm_tlbactive = ~0; PMAP_LOCK_INIT(kernel_pmap); TAILQ_INIT(&kernel_pmap->pm_pvlist); @@ -647,6 +654,10 @@ if (error != H_EOK) panic("failed to set ctx0 TSBs error: %ld", error); +#ifdef SMP + mp_set_tsb_desc_ra(vtophys((vm_offset_t)&kernel_td)); +#endif + /* * This could happen earlier - but I put it here to avoid * attempts to do updates until they're legal @@ -654,12 +665,16 @@ pm->pm_hash = tte_hash_kernel_create(TLB_PHYS_TO_DIRECT(kernel_hash_pa), PAGE_SIZE_4M); pm->pm_hashscratch = tte_hash_set_scratchpad_kernel(pm->pm_hash); - for (i = 0; i < sz; i++) { -#if 1 + for (i = 0; i < translations_size; i++) { + DPRINTF("om_size=%ld om_start=%lx om_tte=%lx\n", + translations[i].om_size, translations[i].om_start, + translations[i].om_tte); + if (translations[i].om_start < VM_MIN_PROM_ADDRESS || - translations[i].om_start > VM_MAX_PROM_ADDRESS) + translations[i].om_start > VM_MAX_PROM_ADDRESS) { + DPRINTF("skipping\n"); continue; -#endif + } for (off = 0; off < translations[i].om_size; off += PAGE_SIZE) { va = translations[i].om_start + off; pa = TTE_GET_PA(translations[i].om_tte) + off; @@ -767,8 +782,6 @@ pmap_insert_entry(dst_pmap, addr, m); } } - - } sched_unpin(); @@ -806,7 +819,8 @@ int invlva; if (pmap->pm_context) - DPRINTF("pmap_enter(va=%lx, pa=0x%lx, prot=%x)\n", va, VM_PAGE_TO_PHYS(m), prot); + DPRINTF("pmap_enter(va=%lx, pa=0x%lx, prot=%x)\n", va, + VM_PAGE_TO_PHYS(m), prot); om = NULL; @@ -929,7 +943,8 @@ uint64_t tte_data; if (pmap->pm_context) - DPRINTF("pmap_enter_quick(ctx=0x%lx va=%lx, pa=0x%lx prot=%x)\n", pmap->pm_context, va, VM_PAGE_TO_PHYS(m), prot); + DPRINTF("pmap_enter_quick(ctx=0x%lx va=%lx, pa=0x%lx prot=%x)\n", + pmap->pm_context, va, VM_PAGE_TO_PHYS(m), prot); mtx_assert(&vm_page_queue_mtx, MA_OWNED); VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); @@ -1049,12 +1064,6 @@ { pv_entry_t pv; -#if 0 - TAILQ_FOREACH(pv, &pmap->pm_pvlist, pv_plist) - if (pv->pv_va == va) - panic("va=0x%lx already in pmap for ctx=0x%lx\n", - va, pmap->pm_context); -#endif DPRINTF("pmap_insert_entry(va=0x%lx, pa=0x%lx)\n", va, VM_PAGE_TO_PHYS(m)); pv = get_pv_entry(pmap); pv->pv_va = va; @@ -1065,22 +1074,56 @@ TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist); TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list); m->md.pv_list_count++; +} + +#ifdef SMP +static void +pmap_ipi(pmap_t pmap, char *func, uint64_t arg1, uint64_t arg2) +{ + int active; + cpumask_t cpumask; - + if (!smp_started) + return; + + cpumask = PCPU_GET(cpumask); + +#ifndef CPUMASK_NOT_BEING_ERRONEOUSLY_CHANGED + /* by definition cpumask should have curcpu's bit set */ + if (cpumask != (1 << curcpu)) + panic("cpumask(0x%x) != (1 << curcpu) (0x%x)\n", + cpumask, (1 << curcpu)); + + /* tlbactive should be set if we're using a pmap */ + if ((cpumask & pmap->pm_tlbactive) == 0) + panic("cpumask(0x%x) & tlbactive (0x%x) == 0\n", + cpumask, pmap->pm_tlbactive); +#endif + + if (cpumask == pmap->pm_tlbactive) + return; + + if (pmap != kernel_pmap) + active = pmap->pm_tlbactive & ~cpumask; + else + active = PCPU_GET(other_cpus); + + cpu_ipi_selected(active, (uint64_t)func, (uint64_t)arg1, (uint64_t)arg2); } +#endif void pmap_invalidate_page(pmap_t pmap, vm_offset_t va) { -#ifdef SMP -#error __FUNCTION_ not implemented -#else tsb_clear_tte(&pmap->pm_tsb, va); DPRINTF("pmap_invalidate_page(va=0x%lx)\n", va); invlpg(va, pmap->pm_context); + +#ifdef SMP + pmap_ipi(pmap, (void *)tl_invlpg, (uint64_t)va, (uint64_t)pmap->pm_context); #endif } @@ -1088,43 +1131,58 @@ pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) { vm_offset_t tva; - /* XXX */ - invltlb(); + char *func; if (pmap != kernel_pmap) DPRINTF("pmap_invalidate_range(sva=%lx, eva=%lx)\n", sva, eva); - /* XXX SUN4V_FIXME - oversimplified logic */ if ((((eva - sva) >> PAGE_SHIFT) < MAX_TSB_CLEARS) || - (pmap->pm_context == 0)) + (pmap->pm_context == 0)) { tsb_clear_range(&pmap->pm_tsb, sva, eva); - else + func = tl_invltlb; + } else { tsb_clear(&pmap->pm_tsb); + func = tl_invlctx; + } + /* XXX */ + invltlb(); if ((((eva - sva) >> PAGE_SHIFT) < MAX_INVALIDATES)) { for (tva = sva; tva < eva; tva += PAGE_SIZE_8K) invlpg(tva, pmap->pm_context); - } else if (pmap->pm_context) + } else if (pmap->pm_context) { invlctx(pmap->pm_context); - else + } else invltlb(); +#ifdef SMP + pmap_ipi(pmap, (void *)func, 0, 0); + pmap->pm_tlbactive = pmap->pm_active; +#endif + + } - void pmap_invalidate_all(pmap_t pmap) { -#ifdef SMP -#error __FUNCTION_ not implemented -#else + char *func; tsb_clear(&pmap->pm_tsb); - if (pmap->pm_context) + + if (pmap->pm_context) { invlctx(pmap->pm_context); - else + func = tl_invlctx; + } else { invltlb(); + func = tl_invltlb; + } + +#ifdef SMP + pmap_ipi(pmap, func, pmap->pm_context, 0); + pmap->pm_tlbactive = pmap->pm_active; #endif + } boolean_t @@ -1163,9 +1221,11 @@ vm_paddr_t pa; pa = 0; - if (va > KERNBASE && va < KERNBASE + PAGE_SIZE_4M) - pa = kernel_phys + (va - KERNBASE); - + if (va > KERNBASE && va < KERNBASE + nucleus_memory) { + uint64_t offset; + offset = va - KERNBASE; + pa = nucleus_mappings[offset >> 22] + offset; + } if ((pa == 0) && (tte_data = tsb_lookup_tte(va, 0)) != 0) pa = TTE_GET_PA(tte_data) | (va & TTE_GET_PAGE_MASK(tte_data)); @@ -1662,23 +1722,6 @@ } /* - * Set the 2 global kernel TSBs - * - */ - -void -pmap_set_tsbs(void) -{ - uint64_t error; - - error = hv_set_ctx0(2, vtophys(&kernel_td)); - - if (error != H_EOK) - panic("failed to set ctx0 TSBs error: %ld", error); - -} - -/* * pmap_ts_referenced: * * Return a count of reference bits for a page, clearing those bits.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604030714.k337Emo4057962>