diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2003-11-24 19:27:04 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2003-11-24 19:27:04 +0000 |
commit | 23f6b300e126827f7fc68c370d8e4c304b002edc (patch) | |
tree | aa367a26536af76cfec4e979d896afd0e5fc698c /sys/arch/hppa | |
parent | 4171f47595321ea0aedd6616b0189c33d0b875bb (diff) |
experimental support for HVT as a 2nd level tlb
Diffstat (limited to 'sys/arch/hppa')
-rw-r--r-- | sys/arch/hppa/hppa/locore.S | 59 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/machdep.c | 14 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/pmap.c | 95 |
3 files changed, 115 insertions, 53 deletions
diff --git a/sys/arch/hppa/hppa/locore.S b/sys/arch/hppa/hppa/locore.S index 82f46aeb661..721c0c31f45 100644 --- a/sys/arch/hppa/hppa/locore.S +++ b/sys/arch/hppa/hppa/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.119 2003/11/07 18:43:25 mickey Exp $ */ +/* $OpenBSD: locore.S,v 1.120 2003/11/24 19:27:03 mickey Exp $ */ /* * Copyright (c) 1998-2003 Michael Shalayeff @@ -1363,6 +1363,14 @@ $tlbd_l TLB_PULL_L(1) IDTLBAF(17) IDTLBPF(25) +#ifdef USE_HPT + /* invalidate instead of update */ + mfctl cr28, r17 + ldw 0(r17), r24 + VTAG + sub,<> r16, r24, r0 + stw r25, 4(r17) +#endif TLB_STATS_AFT(tlbd) rfir nop @@ -1384,11 +1392,60 @@ $itlbna_l rfir nop $dtlbna_l + TLB_STATS_PRE(dtlb) + TLB_PULL_L(0) + IDTLBAF(17) + IDTLBPF(25) + /* figure out later if it's worth caching mappings here as well */ + TLB_STATS_AFT(dtlb) + rfir + nop $dtlb_l TLB_STATS_PRE(dtlb) TLB_PULL_L(0) IDTLBAF(17) IDTLBPF(25) +#ifdef USE_HPT + /* + * cache the next page mapping in the hpt. + * + * mapping for a page at the end of each 128k is uncachable + * in the hvt since it'd be in the tlb itself and thus there + * is no reason to cache it! + * as a side effect this avoids recomputing hpt entry and + * retraversing the whole page table each time. + */ + + ldo PAGE_SIZE(r9), r9 + extru,<> r9, 20, 5, r0 + b,n $dtlb_done_l /* skip if no simple advance */ + /* do not check the PT overlap since the above + * check already guaranties that */ + + /* ripped from TLB_PULL_L(0) */ + extru r9, 19, 10, r16 /* r24 was loaded in the TLB_PULL_L */ + ldwx,s r16(r24), r17 /* va -> pa:prot */ + sh2addl r16, r24, r25 + combt,=,n r0, r17, $dtlb_done_l + copy r17, r16 + depi 0, 21, 1, r17 + sub,= r16, r17, r0 /* do not store if unchanged */ + stws r17, 0(r25) /* store back w/ the bits */ + shd r17, r0, 13, r25 + dep r8, 30, 15, r25 /* mix0r the pid from the sid */ + dep r0, 31, 12, r17 /* needed ? */ + addi 2, r25, r25 + extru r17, 24, 25, r17 + sync + + mfctl cr28, r24 + VTAG + ldo 16(r24), r24 + stw r16, 0(r24) + stw r25, 4(r24) + stw r17, 8(r24) +$dtlb_done_l +#endif TLB_STATS_AFT(dtlb) rfir nop diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index b182b6399b8..1f97c718a39 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.116 2003/10/15 18:54:55 mickey Exp $ */ +/* $OpenBSD: machdep.c,v 1.117 2003/11/24 19:27:03 mickey Exp $ */ /* * Copyright (c) 1999-2002 Michael Shalayeff @@ -250,12 +250,12 @@ const struct hppa_cpu_typed { #ifdef HP7100LC_CPU { "PCXL", hpcxl, HPPA_CPU_PCXL, HPPA_FTRS_BTLBU|HPPA_FTRS_HVT, desidhash_l, itlb_l, itlbna_l, dtlb_l, dtlbna_l, tlbd_l, - ibtlb_g, NULL, pbtlb_g, hpti_l}, + ibtlb_g, NULL, pbtlb_g, hpti_g}, #endif #ifdef HP7300LC_CPU { "PCXL2", hpcxl2,HPPA_CPU_PCXL2, HPPA_FTRS_BTLBU|HPPA_FTRS_HVT, desidhash_l, itlb_l, itlbna_l, dtlb_l, dtlbna_l, tlbd_l, - ibtlb_g, NULL, pbtlb_g, hpti_l}, + ibtlb_g, NULL, pbtlb_g, hpti_g}, #endif #ifdef HP8000_CPU { "PCXU", hpcxu, HPPA_CPU_PCXU, HPPA_FTRS_W32B|HPPA_FTRS_BTLBU|HPPA_FTRS_HVT, @@ -511,9 +511,13 @@ cpuid() } if (!pdc_call((iodcio_t)pdc, 0, PDC_TLB, PDC_TLB_INFO, &pdc_hwtlb) && - pdc_hwtlb.min_size && pdc_hwtlb.max_size) + pdc_hwtlb.min_size && pdc_hwtlb.max_size) { cpu_features |= HPPA_FTRS_HVT; - else { + if (pmap_hptsize > pdc_hwtlb.max_size) + pmap_hptsize = pdc_hwtlb.max_size; + else if (pmap_hptsize && pmap_hptsize < pdc_hwtlb.min_size) + pmap_hptsize = pdc_hwtlb.min_size; + } else { printf("WARNING: no HPT support, fine!\n"); pmap_hptsize = 0; } diff --git a/sys/arch/hppa/hppa/pmap.c b/sys/arch/hppa/hppa/pmap.c index e406f0632d4..14a27cc5308 100644 --- a/sys/arch/hppa/hppa/pmap.c +++ b/sys/arch/hppa/hppa/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.103 2003/10/31 21:24:19 mickey Exp $ */ +/* $OpenBSD: pmap.c,v 1.104 2003/11/24 19:27:03 mickey Exp $ */ /* * Copyright (c) 1998-2003 Michael Shalayeff @@ -91,9 +91,8 @@ int pmapdebug = 0 paddr_t physical_steal, physical_end; -#if defined(HP7100LC_CPU) || defined(HP7300LC_CPU) -int pmap_hptsize = 256; /* patchable */ -#endif +int pmap_hptsize = 16 * PAGE_SIZE; /* patchable */ +vaddr_t pmap_hpt; struct pmap kernel_pmap_store; int hppa_sid_max = HPPA_SID_MAX; @@ -122,24 +121,22 @@ pmap_pagealloc(struct uvm_object *obj, voff_t off) return (pg); } -#if defined(HP7100LC_CPU) || defined(HP7300LC_CPU) +#ifdef USE_HPT /* * This hash function is the one used by the hardware TLB walker on the 7100LC. */ -static inline struct hpt_entry * -pmap_hash(pa_space_t sp, vaddr_t va) +static __inline struct vp_entry * +pmap_hash(struct pmap *pmap, vaddr_t va) +{ + return (struct vp_entry *)(pmap_hpt + + (((va >> 8) ^ (pmap->pm_space << 9)) & (pmap_hptsize - 1))); +} + +static __inline u_int32_t +pmap_vtag(struct pmap *pmap, vaddr_t va) { - struct hpt_entry *hpt; - __asm __volatile ( - "extru %2, 23, 20, %%r22\n\t" /* r22 = (va >> 8) */ - "zdep %1, 22, 16, %%r23\n\t" /* r23 = (sp << 9) */ - "xor %%r22,%%r23, %%r23\n\t" /* r23 ^= r22 */ - "mfctl %%cr24, %%r22\n\t" /* r22 = sizeof(HPT)-1 */ - "and %%r22,%%r23, %%r23\n\t" /* r23 &= r22 */ - "mfctl %%cr25, %%r22\n\t" /* r22 = addr of HPT table */ - "or %%r23, %%r22, %0" /* %0 = HPT entry */ - : "=r" (hpt) : "r" (sp), "r" (va) : "r22", "r23"); - return hpt; + return (0x80000000 | (pmap->pm_space & 0xffff) | + ((va >> 1) & 0x7fff0000)); } #endif @@ -275,6 +272,14 @@ pmap_pte_flush(struct pmap *pmap, vaddr_t va, pt_entry_t pte) } fdcache(pmap->pm_space, va, PAGE_SIZE); pdtlb(pmap->pm_space, va); +#ifdef USE_HPT + if (pmap_hpt) { + struct vp_entry *hpt; + hpt = pmap_hash(pmap, va); + if (hpt->vp_tag == pmap_vtag(pmap, va)) + hpt->vp_tag = 0xffff; + } +#endif } static __inline pt_entry_t @@ -434,9 +439,6 @@ pmap_bootstrap(vstart) extern paddr_t hppa_vtop; vaddr_t va, addr = hppa_round_page(vstart), t; vsize_t size; -#if 0 && (defined(HP7100LC_CPU) || defined(HP7300LC_CPU)) - struct vp_entry *hptp; -#endif struct pmap *kpm; int npdes, nkpdes; @@ -487,36 +489,35 @@ pmap_bootstrap(vstart) ie_mem = (u_int *)addr; addr += 0x8000; -#if 0 && (defined(HP7100LC_CPU) || defined(HP7300LC_CPU)) - if (pmap_hptsize && (cpu_type == hpcxl || cpu_type == hpcxl2)) { - int error; +#ifdef USE_HPT + if (pmap_hptsize) { + struct vp_entry *hptp; + int i, error; - if (pmap_hptsize > pdc_hwtlb.max_size) - pmap_hptsize = pdc_hwtlb.max_size; - else if (pmap_hptsize < pdc_hwtlb.min_size) - pmap_hptsize = pdc_hwtlb.min_size; + /* must be aligned to the size XXX */ + if (addr & (pmap_hptsize - 1)) + addr += pmap_hptsize; + addr &= ~(pmap_hptsize - 1); - size = pmap_hptsize * sizeof(*hptp); - bzero((void *)addr, size); - /* Allocate the HPT */ - for (hptp = (struct vp_entry *)addr, i = pmap_hptsize; i--;) + bzero((void *)addr, pmap_hptsize); + for (hptp = (struct vp_entry *)addr, i = pmap_hptsize / 16; i--;) hptp[i].vp_tag = 0xffff; - - DPRINTF(PDB_INIT, ("hpt_table: 0x%x @ %p\n", size, addr)); - - if ((error = (cpu_hpt_init)(addr, size)) < 0) { - printf("WARNING: HPT init error %d\n", error); - } else { - printf("HPT: %d entries @ 0x%x\n", - pmap_hptsize / sizeof(struct vp_entry), addr); - } - - /* TODO find a way to avoid using cr*, use cpu regs instead */ - mtctl(addr, CR_VTOP); - mtctl(size - 1, CR_HPTMASK); - addr += size; /* should keep the alignment right */ + pmap_hpt = addr; + addr += pmap_hptsize; + + DPRINTF(PDB_INIT, ("hpt_table: 0x%x @ %p\n", + pmap_hptsize, addr)); + + if ((error = (cpu_hpt_init)(pmap_hpt, pmap_hptsize)) < 0) { + printf("WARNING: HPT init error %d -- DISABLED\n", + error); + pmap_hpt = 0; + } else + DPRINTF(PDB_INIT, + ("HPT: installed for %d entries @ 0x%x\n", + pmap_hptsize / sizeof(struct vp_entry), addr)); } -#endif /* HP7100LC_CPU | HP7300LC_CPU */ +#endif /* XXX PCXS needs this inserted into an IBTLB */ /* and can block-map the whole phys w/ another */ |