1129198Scognet/* $NetBSD: cpufunc_asm.S,v 1.12 2003/09/06 09:14:52 rearnsha Exp $ */ 2129198Scognet 3139735Simp/*- 4129198Scognet * Copyright (c) 1997,1998 Mark Brinicombe. 5129198Scognet * Copyright (c) 1997 Causality Limited 6129198Scognet * All rights reserved. 7129198Scognet * 8129198Scognet * Redistribution and use in source and binary forms, with or without 9129198Scognet * modification, are permitted provided that the following conditions 10129198Scognet * are met: 11129198Scognet * 1. Redistributions of source code must retain the above copyright 12129198Scognet * notice, this list of conditions and the following disclaimer. 13129198Scognet * 2. Redistributions in binary form must reproduce the above copyright 14129198Scognet * notice, this list of conditions and the following disclaimer in the 15129198Scognet * documentation and/or other materials provided with the distribution. 16129198Scognet * 3. All advertising materials mentioning features or use of this software 17129198Scognet * must display the following acknowledgement: 18129198Scognet * This product includes software developed by Causality Limited. 19129198Scognet * 4. The name of Causality Limited may not be used to endorse or promote 20129198Scognet * products derived from this software without specific prior written 21129198Scognet * permission. 22129198Scognet * 23129198Scognet * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS 24129198Scognet * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25129198Scognet * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26129198Scognet * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT, 27129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33129198Scognet * SUCH DAMAGE. 34129198Scognet * 35129198Scognet * RiscBSD kernel project 36129198Scognet * 37236991Simp * cpufunc.S 38129198Scognet * 39129198Scognet * Assembly functions for CPU / MMU / TLB specific operations 40129198Scognet * 41129198Scognet * Created : 30/01/97 42129198Scognet * 43129198Scognet */ 44236991Simp 45129198Scognet#include <machine/asm.h> 46129198Scognet__FBSDID("$FreeBSD$"); 47129198Scognet 48129198Scognet .text 49276596Sian .align 2 50129198Scognet 51129198ScognetENTRY(cpufunc_nullop) 52137463Scognet RET 53248361SandrewEND(cpufunc_nullop) 54129198Scognet 55129198Scognet/* 56129198Scognet * Generic functions to read the internal coprocessor registers 57129198Scognet * 58129198Scognet * Currently these registers are : 59129198Scognet * c0 - CPU ID 60129198Scognet * c5 - Fault status 61129198Scognet * c6 - Fault address 62129198Scognet * 63129198Scognet */ 64129198Scognet 65295096SmmelENTRY(cpu_ident) 66129198Scognet mrc p15, 0, r0, c0, c0, 0 67137463Scognet RET 68295097SmmelEND(cpu_ident) 69129198Scognet 70129198ScognetENTRY(cpu_get_control) 71300533Sian mrc CP15_SCTLR(r0) 72137463Scognet RET 73248361SandrewEND(cpu_get_control) 74129198Scognet 75129198ScognetENTRY(cpu_read_cache_config) 76129198Scognet mrc p15, 0, r0, c0, c0, 1 77137463Scognet RET 78248361SandrewEND(cpu_read_cache_config) 79129198Scognet 80295096SmmelENTRY(cpu_faultstatus) 81129198Scognet mrc p15, 0, r0, c5, c0, 0 82137463Scognet RET 83295096SmmelEND(cpu_faultstatus) 84129198Scognet 85295096SmmelENTRY(cpu_faultaddress) 86129198Scognet mrc p15, 0, r0, c6, c0, 0 87137463Scognet RET 88295096SmmelEND(cpu_faultaddress) 89129198Scognet 90129198Scognet/* 91129198Scognet * Generic functions to write the internal coprocessor registers 92129198Scognet * 93129198Scognet * 94236991Simp * Currently these registers are 95129198Scognet * c1 - CPU Control 96129198Scognet * c3 - Domain Access Control 97129198Scognet * 98129198Scognet * All other registers are CPU architecture specific 99129198Scognet */ 100236991Simp 101295096SmmelENTRY(cpu_domains) 102129198Scognet mcr p15, 0, r0, c3, c0, 0 103137463Scognet RET 104295096SmmelEND(cpu_domains) 105129198Scognet 106129198Scognet/* 107129198Scognet * Generic functions to read/modify/write the internal coprocessor registers 108129198Scognet * 109129198Scognet * 110236991Simp * Currently these registers are 111129198Scognet * c1 - CPU Control 112129198Scognet * 113129198Scognet * All other registers are CPU architecture specific 114129198Scognet */ 115236991Simp 116129198ScognetENTRY(cpufunc_control) 117300533Sian mrc CP15_SCTLR(r3) /* Read the control register */ 118129198Scognet bic r2, r3, r0 /* Clear bits */ 119129198Scognet eor r2, r2, r1 /* XOR bits */ 120129198Scognet 121129198Scognet 122129198Scognet teq r2, r3 /* Only write if there is a change */ 123300533Sian mcrne CP15_SCTLR(r2) /* Write new control register */ 124129198Scognet mov r0, r3 /* Return old value */ 125129198Scognet 126137463Scognet RET 127129198Scognet.Lglou: 128129198Scognet .asciz "plop %p\n" 129276596Sian .align 2 130248361SandrewEND(cpufunc_control) 131248361Sandrew 132129198Scognet/* 133129198Scognet * other potentially useful software functions are: 134129198Scognet * clean D cache entry and flush I cache entry 135129198Scognet * for the moment use cache_purgeID_E 136129198Scognet */ 137129198Scognet 138129198Scognet/* Random odd functions */ 139129198Scognet 140129198Scognet/* 141129198Scognet * Function to get the offset of a stored program counter from the 142129198Scognet * instruction doing the store. This offset is defined to be the same 143129198Scognet * for all STRs and STMs on a given implementation. Code based on 144129198Scognet * section 2.4.3 of the ARM ARM (2nd Ed.), with modifications to work 145129198Scognet * in 26-bit modes as well. 146129198Scognet */ 147129198ScognetENTRY(get_pc_str_offset) 148129198Scognet mov ip, sp 149129198Scognet stmfd sp!, {fp, ip, lr, pc} 150129198Scognet sub fp, ip, #4 151129198Scognet sub sp, sp, #4 152129198Scognet mov r1, pc /* R1 = addr of following STR */ 153129198Scognet mov r0, r0 154129198Scognet str pc, [sp] /* [SP] = . + offset */ 155129198Scognet ldr r0, [sp] 156129198Scognet sub r0, r0, r1 157129198Scognet ldmdb fp, {fp, sp, pc} 158248361SandrewEND(get_pc_str_offset) 159142570Scognet 160142570Scognet/* Allocate and lock a cacheline for the specified address. */ 161142570Scognet 162142570Scognet#define CPWAIT_BRANCH \ 163142570Scognet sub pc, pc, #4 164142570Scognet#define CPWAIT() \ 165142570Scognet mrc p15, 0, r2, c2, c0, 0; \ 166142570Scognet mov r2, r2; \ 167142570Scognet CPWAIT_BRANCH 168142570Scognet 169142570ScognetENTRY(arm_lock_cache_line) 170142570Scognet mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */ 171142570Scognet mov r1, #1 172142570Scognet mcr p15, 0, r1, c9, c2, 0 /* Enable data cache lock mode */ 173142570Scognet CPWAIT() 174142570Scognet mcr p15, 0, r0, c7, c2, 5 /* Allocate the cache line */ 175142570Scognet mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */ 176142570Scognet mov r1, #0 177142570Scognet str r1, [r0] 178142570Scognet mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */ 179142570Scognet mcr p15, 0, r1, c9, c2, 0 /* Disable data cache lock mode */ 180142570Scognet CPWAIT() 181142570Scognet RET 182248361SandrewEND(arm_lock_cache_line) 183248361Sandrew 184