/* * Prepare kernel stack PTE table. sh4_switch_resume wires these PTEs. */ void sh4_switch_setup(struct lwp *l) { struct md_upte *md_upte; uint32_t vpn; pt_entry_t *pte; int i, e; md_upte = l->l_md.md_upte; vpn = sh3_trunc_page(uvm_lwp_getuarea(l)); e = SH4_UTLB_ENTRY - UPAGES; for (i = 0; i < UPAGES; ++i) { pte = __pmap_kpte_lookup(vpn); KDASSERT(pte && *pte != 0); /* Address array */ md_upte->addr = SH4_UTLB_AA | (e << SH4_UTLB_E_SHIFT); md_upte->data = vpn | SH4_UTLB_AA_D | SH4_UTLB_AA_V; ++md_upte; /* Data array */ md_upte->addr = SH4_UTLB_DA1 | (e << SH4_UTLB_E_SHIFT); md_upte->data = (*pte & PG_HW_BITS) | SH4_UTLB_DA1_D | SH4_UTLB_DA1_V; ++md_upte; vpn += PAGE_SIZE; ++e; } }
/* * void sh4_switch_setup(struct proc *p): * prepare kernel stack PTE table. sh4_switch_resume wired this PTE. */ void sh4_switch_setup(struct proc *p) { pt_entry_t *pte; struct md_upte *md_upte = p->p_md.md_upte; uint32_t vpn; int i, e; vpn = (uint32_t)p->p_addr; vpn &= ~PGOFSET; e = SH4_UTLB_ENTRY - UPAGES; for (i = 0; i < UPAGES; i++, e++, vpn += PAGE_SIZE) { pte = __pmap_kpte_lookup(vpn); KDASSERT(pte && *pte != 0); /* Address array */ md_upte->addr = SH4_UTLB_AA | (e << SH4_UTLB_E_SHIFT); md_upte->data = vpn | SH4_UTLB_AA_D | SH4_UTLB_AA_V; md_upte++; /* Data array */ md_upte->addr = SH4_UTLB_DA1 | (e << SH4_UTLB_E_SHIFT); md_upte->data = (*pte & PG_HW_BITS) | SH4_UTLB_DA1_D | SH4_UTLB_DA1_V; md_upte++; } }
int obio_iomem_add_mapping(bus_addr_t bpa, bus_size_t size, int type, bus_space_handle_t *bshp) { u_long pa, endpa; vaddr_t va; pt_entry_t *pte; unsigned int m = 0; int io_type = type & ~OBIO_IOMEM_PCMCIA_8BIT; pa = trunc_page(bpa); endpa = round_page(bpa + size); #ifdef DIAGNOSTIC if (endpa <= pa) panic("obio_iomem_add_mapping: overflow"); #endif va = uvm_km_valloc(kernel_map, endpa - pa); if (va == 0) return (ENOMEM); *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET)); #define MODE(t, s) \ ((t) & OBIO_IOMEM_PCMCIA_8BIT) ? \ _PG_PCMCIA_ ## s ## 8 : \ _PG_PCMCIA_ ## s ## 16 switch (io_type) { default: panic("unknown pcmcia space."); /* NOTREACHED */ case OBIO_IOMEM_PCMCIA_IO: m = MODE(type, IO); break; case OBIO_IOMEM_PCMCIA_MEM: m = MODE(type, MEM); break; case OBIO_IOMEM_PCMCIA_ATT: m = MODE(type, ATTR); break; } #undef MODE for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) { pmap_kenter_pa(va, pa, PROT_READ | PROT_WRITE); pte = __pmap_kpte_lookup(va); KDASSERT(pte); *pte |= m; /* PTEA PCMCIA assistant bit */ sh_tlb_update(0, va, *pte); } return (0); }
/* * void sh3_switch_setup(struct proc *p): * prepare kernel stack PTE table. TLB miss handler check these. */ void sh3_switch_setup(struct proc *p) { pt_entry_t *pte; struct md_upte *md_upte = p->p_md.md_upte; uint32_t vpn; int i; vpn = (uint32_t)p->p_addr; vpn &= ~PGOFSET; for (i = 0; i < UPAGES; i++, vpn += PAGE_SIZE, md_upte++) { pte = __pmap_kpte_lookup(vpn); KDASSERT(pte && *pte != 0); md_upte->addr = vpn; md_upte->data = (*pte & PG_HW_BITS) | PG_D | PG_V; } }