1217044Snwhitehorn/*- 2217044Snwhitehorn * Copyright (C) 2010 Nathan Whitehorn 3217044Snwhitehorn * All rights reserved. 4217044Snwhitehorn * 5217044Snwhitehorn * Redistribution and use in source and binary forms, with or without 6217044Snwhitehorn * modification, are permitted provided that the following conditions 7217044Snwhitehorn * are met: 8217044Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9217044Snwhitehorn * notice, this list of conditions and the following disclaimer. 10217044Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11217044Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12217044Snwhitehorn * documentation and/or other materials provided with the distribution. 13217044Snwhitehorn * 14217044Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15217044Snwhitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16217044Snwhitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17217044Snwhitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18217044Snwhitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19217044Snwhitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20217044Snwhitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21217044Snwhitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22217044Snwhitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23217044Snwhitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24217044Snwhitehorn */ 25217044Snwhitehorn 26217044Snwhitehorn#include <sys/cdefs.h> 27217044Snwhitehorn__FBSDID("$FreeBSD$"); 28217044Snwhitehorn 29217044Snwhitehorn#include <stand.h> 30217044Snwhitehorn#include <stdint.h> 31217044Snwhitehorn 32217044Snwhitehorn#define _KERNEL 33217044Snwhitehorn#include <machine/cpufunc.h> 34217044Snwhitehorn#include <machine/psl.h> 35217044Snwhitehorn#include <machine/pte.h> 36217044Snwhitehorn#include <machine/slb.h> 37217044Snwhitehorn#include <machine/param.h> 38217044Snwhitehorn 39217044Snwhitehorn#include "bootstrap.h" 40217044Snwhitehorn#include "lv1call.h" 41217044Snwhitehorn#include "ps3.h" 42217044Snwhitehorn 43217044Snwhitehornregister_t pteg_count, pteg_mask; 44217044Snwhitehornuint64_t as_id; 45217044Snwhitehornuint64_t virtual_avail; 46217044Snwhitehorn 47217044Snwhitehornint 48217044Snwhitehornps3mmu_map(uint64_t va, uint64_t pa) 49217044Snwhitehorn{ 50217044Snwhitehorn struct lpte pt; 51217044Snwhitehorn int shift; 52217044Snwhitehorn uint64_t vsid, ptegidx; 53217044Snwhitehorn 54217044Snwhitehorn if (pa < 0x8000000) { /* Phys mem? */ 55217044Snwhitehorn pt.pte_hi = LPTE_BIG; 56217044Snwhitehorn pt.pte_lo = LPTE_M; 57217044Snwhitehorn shift = 24; 58217044Snwhitehorn vsid = 0; 59217044Snwhitehorn } else { 60217044Snwhitehorn pt.pte_hi = 0; 61217044Snwhitehorn pt.pte_lo = LPTE_I | LPTE_G | LPTE_M | LPTE_NOEXEC; 62217044Snwhitehorn shift = ADDR_PIDX_SHFT; 63217044Snwhitehorn vsid = 1; 64217044Snwhitehorn } 65217044Snwhitehorn 66217044Snwhitehorn pt.pte_hi |= (vsid << LPTE_VSID_SHIFT) | 67217044Snwhitehorn (((uint64_t)(va & ADDR_PIDX) >> ADDR_API_SHFT64) & LPTE_API); 68217044Snwhitehorn pt.pte_lo |= pa; 69217044Snwhitehorn ptegidx = vsid ^ (((uint64_t)va & ADDR_PIDX) >> shift); 70217044Snwhitehorn 71217044Snwhitehorn pt.pte_hi |= LPTE_LOCKED | LPTE_VALID; 72217044Snwhitehorn ptegidx &= pteg_mask; 73217044Snwhitehorn 74217044Snwhitehorn return (lv1_insert_pte(ptegidx, &pt, LPTE_LOCKED)); 75217044Snwhitehorn} 76217044Snwhitehorn 77217044Snwhitehornvoid * 78217044Snwhitehornps3mmu_mapdev(uint64_t pa, size_t length) 79217044Snwhitehorn{ 80217044Snwhitehorn uint64_t spa; 81217044Snwhitehorn void *mapstart; 82217044Snwhitehorn int err; 83217044Snwhitehorn 84217044Snwhitehorn mapstart = (void *)(uintptr_t)virtual_avail; 85217044Snwhitehorn 86217044Snwhitehorn for (spa = pa; spa < pa + length; spa += PAGE_SIZE) { 87217044Snwhitehorn err = ps3mmu_map(virtual_avail, spa); 88217044Snwhitehorn virtual_avail += PAGE_SIZE; 89217044Snwhitehorn if (err != 0) 90217044Snwhitehorn return (NULL); 91217044Snwhitehorn } 92217044Snwhitehorn 93217044Snwhitehorn return (mapstart); 94217044Snwhitehorn} 95217044Snwhitehorn 96217044Snwhitehornint 97217044Snwhitehornps3mmu_init(int maxmem) 98217044Snwhitehorn{ 99217044Snwhitehorn uint64_t ptsize; 100217044Snwhitehorn int i; 101217044Snwhitehorn 102217044Snwhitehorn i = lv1_setup_address_space(&as_id, &ptsize); 103217044Snwhitehorn pteg_count = ptsize / sizeof(struct lpteg); 104217044Snwhitehorn pteg_mask = pteg_count - 1; 105217044Snwhitehorn 106217044Snwhitehorn for (i = 0; i < maxmem; i += 16*1024*1024) 107217044Snwhitehorn ps3mmu_map(i,i); 108217044Snwhitehorn 109217044Snwhitehorn virtual_avail = 0x10000000; 110217044Snwhitehorn 111217044Snwhitehorn __asm __volatile ("slbia; slbmte %0, %1; slbmte %2,%3" :: 112217044Snwhitehorn "r"((0 << SLBV_VSID_SHIFT) | SLBV_L), "r"(0 | SLBE_VALID), 113217044Snwhitehorn "r"(1 << SLBV_VSID_SHIFT), 114217044Snwhitehorn "r"((1 << SLBE_ESID_SHIFT) | SLBE_VALID | 1)); 115217044Snwhitehorn 116230140Snwhitehorn mtmsr(PSL_IR | PSL_DR | PSL_RI | PSL_ME); 117217044Snwhitehorn 118217044Snwhitehorn return (0); 119217044Snwhitehorn} 120217044Snwhitehorn 121