1 1.5 matt /* $NetBSD: bonito_iobc.c,v 1.5 2011/07/10 23:13:22 matt Exp $ */ 2 1.1 thorpej 3 1.1 thorpej /*- 4 1.1 thorpej * Copyright (c) 2002 The NetBSD Foundation, Inc. 5 1.1 thorpej * All rights reserved. 6 1.1 thorpej * 7 1.1 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.1 thorpej * by Jason R. Thorpe. 9 1.1 thorpej * 10 1.1 thorpej * Redistribution and use in source and binary forms, with or without 11 1.1 thorpej * modification, are permitted provided that the following conditions 12 1.1 thorpej * are met: 13 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 14 1.1 thorpej * notice, this list of conditions and the following disclaimer. 15 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 17 1.1 thorpej * documentation and/or other materials provided with the distribution. 18 1.1 thorpej * 19 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 thorpej * POSSIBILITY OF SUCH DAMAGE. 30 1.1 thorpej */ 31 1.1 thorpej 32 1.1 thorpej /* 33 1.1 thorpej * Code to manipulate the I/O Buffer Cache on the BONITO. 34 1.1 thorpej * 35 1.1 thorpej * The BONITO snoops uncached access to memory (e.g. via KSEG1); we only 36 1.1 thorpej * need to deal with the IOBC for DMA to cached memory. 37 1.1 thorpej * 38 1.1 thorpej * Note: This only applies to the 32-bit BONITO; BONITO64's IOBC 39 1.1 thorpej * is coherent. 40 1.1 thorpej */ 41 1.2 lukem 42 1.2 lukem #include <sys/cdefs.h> 43 1.5 matt __KERNEL_RCSID(0, "$NetBSD: bonito_iobc.c,v 1.5 2011/07/10 23:13:22 matt Exp $"); 44 1.1 thorpej 45 1.1 thorpej #include <sys/param.h> 46 1.5 matt #include <sys/intr.h> 47 1.1 thorpej 48 1.5 matt #include <mips/locore.h> 49 1.1 thorpej 50 1.1 thorpej #include <mips/bonito/bonitoreg.h> 51 1.1 thorpej #include <mips/bonito/bonitovar.h> 52 1.1 thorpej 53 1.1 thorpej #define CACHECMD_INVAL 0 54 1.1 thorpej #define CACHECMD_WBINV 1 55 1.1 thorpej #define CACHECMD_RDTAG 2 56 1.1 thorpej #define CACHECMD_WQFLUSH 3 57 1.1 thorpej 58 1.1 thorpej #define IOBC_LINESIZE 32 59 1.1 thorpej #define IOBC_LINESHIFT 5 60 1.1 thorpej #define IOBC_NLINES 4 61 1.1 thorpej 62 1.1 thorpej #define TAG_LOCK 0x80000000 63 1.1 thorpej #define TAG_WBACK 0x40000000 64 1.1 thorpej #define TAG_PFPEND 0x20000000 65 1.1 thorpej #define TAG_PEND 0x10000000 66 1.1 thorpej #define TAG_MOD 0x08000000 67 1.1 thorpej #define TAG_PFDVAL 0x04000000 68 1.1 thorpej #define TAG_DVAL 0x02000000 69 1.1 thorpej #define TAG_AVAL 0x01000000 70 1.1 thorpej #define TAG_ADDR 0x00ffffff 71 1.1 thorpej 72 1.1 thorpej #define IOBC_LOCK(s) (s) = splhigh() 73 1.1 thorpej #define IOBC_UNLOCK(s) splx((s)) 74 1.1 thorpej 75 1.1 thorpej static void 76 1.1 thorpej bonito_iobc_cmd(uint32_t cmd, uint32_t line) 77 1.1 thorpej { 78 1.1 thorpej uint32_t ctrl; 79 1.1 thorpej 80 1.1 thorpej ctrl = (cmd << BONITO_PCICACHECTRL_CACHECMD_SHIFT) | 81 1.1 thorpej (line << BONITO_PCICACHECTRL_CACHECMDLINE_SHIFT); 82 1.1 thorpej 83 1.1 thorpej REGVAL(BONITO_PCICACHECTRL) = ctrl; 84 1.1 thorpej wbflush(); 85 1.1 thorpej 86 1.1 thorpej REGVAL(BONITO_PCICACHECTRL) = ctrl | BONITO_PCICACHECTRL_CMDEXEC; 87 1.1 thorpej wbflush(); 88 1.1 thorpej 89 1.1 thorpej while (REGVAL(BONITO_PCICACHECTRL) & BONITO_PCICACHECTRL_CMDEXEC) 90 1.1 thorpej /* spin */ ; 91 1.1 thorpej 92 1.1 thorpej REGVAL(BONITO_PCICACHECTRL) = ctrl; 93 1.1 thorpej wbflush(); 94 1.1 thorpej } 95 1.1 thorpej 96 1.1 thorpej /* 97 1.1 thorpej * bonito_iobc_wbinv_range: 98 1.1 thorpej * 99 1.1 thorpej * Write-back and invalidate the specified range in 100 1.1 thorpej * the BONITO IOBC. 101 1.1 thorpej */ 102 1.1 thorpej void 103 1.1 thorpej bonito_iobc_wbinv_range(paddr_t pa, psize_t size) 104 1.1 thorpej { 105 1.1 thorpej uint32_t line, tag; 106 1.1 thorpej paddr_t tagaddr; 107 1.1 thorpej int s; 108 1.1 thorpej 109 1.1 thorpej IOBC_LOCK(s); 110 1.1 thorpej 111 1.1 thorpej for (line = 0; line < IOBC_NLINES; line++) { 112 1.1 thorpej bonito_iobc_cmd(CACHECMD_RDTAG, line); 113 1.1 thorpej tag = REGVAL(BONITO_PCICACHETAG); 114 1.1 thorpej if (tag & TAG_AVAL) { 115 1.1 thorpej tagaddr = (tag & TAG_ADDR) << IOBC_LINESHIFT; 116 1.1 thorpej if (tagaddr < (pa + size) && 117 1.1 thorpej (tagaddr + IOBC_LINESIZE) > pa) 118 1.1 thorpej bonito_iobc_cmd(CACHECMD_WBINV, line); 119 1.1 thorpej } 120 1.1 thorpej } 121 1.1 thorpej bonito_iobc_cmd(CACHECMD_WQFLUSH, 0); 122 1.1 thorpej 123 1.1 thorpej IOBC_UNLOCK(s); 124 1.1 thorpej } 125 1.1 thorpej 126 1.1 thorpej /* 127 1.1 thorpej * bonito_iobc_inv_range: 128 1.1 thorpej * 129 1.1 thorpej * Invalidate the specified range in the BONITO IOBC. 130 1.1 thorpej */ 131 1.1 thorpej void 132 1.1 thorpej bonito_iobc_inv_range(paddr_t pa, psize_t size) 133 1.1 thorpej { 134 1.1 thorpej uint32_t line, tag; 135 1.1 thorpej paddr_t tagaddr; 136 1.1 thorpej int s; 137 1.1 thorpej 138 1.1 thorpej IOBC_LOCK(s); 139 1.1 thorpej 140 1.1 thorpej for (line = 0; line < IOBC_NLINES; line++) { 141 1.1 thorpej bonito_iobc_cmd(CACHECMD_RDTAG, line); 142 1.1 thorpej tag = REGVAL(BONITO_PCICACHETAG); 143 1.1 thorpej if (tag & TAG_AVAL) { 144 1.1 thorpej tagaddr = (tag & TAG_ADDR) << IOBC_LINESHIFT; 145 1.1 thorpej if (tagaddr < (pa + size) && 146 1.1 thorpej (tagaddr + IOBC_LINESIZE) > pa) 147 1.1 thorpej bonito_iobc_cmd(CACHECMD_INVAL, line); 148 1.1 thorpej } 149 1.1 thorpej } 150 1.1 thorpej bonito_iobc_cmd(CACHECMD_WQFLUSH, 0); 151 1.1 thorpej 152 1.1 thorpej IOBC_UNLOCK(s); 153 1.1 thorpej } 154