cpufunc_asm.S revision 295096
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: head/sys/arm/arm/cpufunc_asm.S 295096 2016-01-31 16:34:06Z mmel $"); 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 68248361SandrewEND(cpufunc_id) 69129198Scognet 70129198ScognetENTRY(cpu_get_control) 71129198Scognet mrc p15, 0, r0, c1, c0, 0 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 101129198Scognet#if 0 /* See below. */ 102129198ScognetENTRY(cpufunc_control) 103129198Scognet mcr p15, 0, r0, c1, c0, 0 104137463Scognet RET 105248361SandrewEND(cpufunc_control) 106129198Scognet#endif 107129198Scognet 108295096SmmelENTRY(cpu_domains) 109129198Scognet mcr p15, 0, r0, c3, c0, 0 110137463Scognet RET 111295096SmmelEND(cpu_domains) 112129198Scognet 113129198Scognet/* 114129198Scognet * Generic functions to read/modify/write the internal coprocessor registers 115129198Scognet * 116129198Scognet * 117236991Simp * Currently these registers are 118129198Scognet * c1 - CPU Control 119129198Scognet * 120129198Scognet * All other registers are CPU architecture specific 121129198Scognet */ 122236991Simp 123129198ScognetENTRY(cpufunc_control) 124129198Scognet mrc p15, 0, r3, c1, c0, 0 /* Read the control register */ 125129198Scognet bic r2, r3, r0 /* Clear bits */ 126129198Scognet eor r2, r2, r1 /* XOR bits */ 127129198Scognet 128129198Scognet 129129198Scognet teq r2, r3 /* Only write if there is a change */ 130129198Scognet mcrne p15, 0, r2, c1, c0, 0 /* Write new control register */ 131129198Scognet mov r0, r3 /* Return old value */ 132129198Scognet 133137463Scognet RET 134129198Scognet.Lglou: 135129198Scognet .asciz "plop %p\n" 136276596Sian .align 2 137248361SandrewEND(cpufunc_control) 138248361Sandrew 139129198Scognet/* 140129198Scognet * other potentially useful software functions are: 141129198Scognet * clean D cache entry and flush I cache entry 142129198Scognet * for the moment use cache_purgeID_E 143129198Scognet */ 144129198Scognet 145129198Scognet/* Random odd functions */ 146129198Scognet 147129198Scognet/* 148129198Scognet * Function to get the offset of a stored program counter from the 149129198Scognet * instruction doing the store. This offset is defined to be the same 150129198Scognet * for all STRs and STMs on a given implementation. Code based on 151129198Scognet * section 2.4.3 of the ARM ARM (2nd Ed.), with modifications to work 152129198Scognet * in 26-bit modes as well. 153129198Scognet */ 154129198ScognetENTRY(get_pc_str_offset) 155129198Scognet mov ip, sp 156129198Scognet stmfd sp!, {fp, ip, lr, pc} 157129198Scognet sub fp, ip, #4 158129198Scognet sub sp, sp, #4 159129198Scognet mov r1, pc /* R1 = addr of following STR */ 160129198Scognet mov r0, r0 161129198Scognet str pc, [sp] /* [SP] = . + offset */ 162129198Scognet ldr r0, [sp] 163129198Scognet sub r0, r0, r1 164129198Scognet ldmdb fp, {fp, sp, pc} 165248361SandrewEND(get_pc_str_offset) 166142570Scognet 167142570Scognet/* Allocate and lock a cacheline for the specified address. */ 168142570Scognet 169142570Scognet#define CPWAIT_BRANCH \ 170142570Scognet sub pc, pc, #4 171142570Scognet#define CPWAIT() \ 172142570Scognet mrc p15, 0, r2, c2, c0, 0; \ 173142570Scognet mov r2, r2; \ 174142570Scognet CPWAIT_BRANCH 175142570Scognet 176142570ScognetENTRY(arm_lock_cache_line) 177142570Scognet mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */ 178142570Scognet mov r1, #1 179142570Scognet mcr p15, 0, r1, c9, c2, 0 /* Enable data cache lock mode */ 180142570Scognet CPWAIT() 181142570Scognet mcr p15, 0, r0, c7, c2, 5 /* Allocate the cache line */ 182142570Scognet mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */ 183142570Scognet mov r1, #0 184142570Scognet str r1, [r0] 185142570Scognet mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */ 186142570Scognet mcr p15, 0, r1, c9, c2, 0 /* Disable data cache lock mode */ 187142570Scognet CPWAIT() 188142570Scognet RET 189248361SandrewEND(arm_lock_cache_line) 190248361Sandrew 191