1129198Scognet/*- 2129198Scognet * Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org> 3129198Scognet * All rights reserved. 4129198Scognet * 5129198Scognet * Redistribution and use in source and binary forms, with or without 6129198Scognet * modification, are permitted provided that the following conditions 7129198Scognet * are met: 8129198Scognet * 1. Redistributions of source code must retain the above copyright 9129198Scognet * notice, this list of conditions and the following disclaimer. 10129198Scognet * 2. Redistributions in binary form must reproduce the above copyright 11129198Scognet * notice, this list of conditions and the following disclaimer in the 12129198Scognet * documentation and/or other materials provided with the distribution. 13129198Scognet * 14129198Scognet * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15129198Scognet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16129198Scognet * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17129198Scognet * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18129198Scognet * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19129198Scognet * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20129198Scognet * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24129198Scognet * SUCH DAMAGE. 25129198Scognet * 26129198Scognet * from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27 27129198Scognet * $FreeBSD: stable/11/sys/arm/include/pcpu.h 331988 2018-04-04 06:11:05Z mmel $ 28129198Scognet */ 29129198Scognet 30129198Scognet#ifndef _MACHINE_PCPU_H_ 31129198Scognet#define _MACHINE_PCPU_H_ 32129198Scognet 33129198Scognet#ifdef _KERNEL 34129198Scognet 35313766Sjah#include <sys/_lock.h> 36313766Sjah#include <sys/_mutex.h> 37313766Sjah 38129198Scognet#define ALT_STACK_SIZE 128 39129198Scognet 40129198Scognetstruct vmspace; 41129198Scognet 42181875Sjhb#endif /* _KERNEL */ 43181875Sjhb 44284265Sandrew#if __ARM_ARCH >= 6 45331988Smmel/* Branch predictor hardening method */ 46331988Smmel#define PCPU_BP_HARDEN_KIND_NONE 0 47331988Smmel#define PCPU_BP_HARDEN_KIND_BPIALL 1 48331988Smmel#define PCPU_BP_HARDEN_KIND_ICIALLU 2 49313766Sjah 50239268Sgonzo#define PCPU_MD_FIELDS \ 51239268Sgonzo unsigned int pc_vfpsid; \ 52239268Sgonzo unsigned int pc_vfpmvfr0; \ 53239268Sgonzo unsigned int pc_vfpmvfr1; \ 54249265Sglebius struct pmap *pc_curpmap; \ 55313766Sjah struct mtx pc_cmap_lock; \ 56313766Sjah void *pc_cmap1_pte2p; \ 57313766Sjah void *pc_cmap2_pte2p; \ 58313766Sjah caddr_t pc_cmap1_addr; \ 59313766Sjah caddr_t pc_cmap2_addr; \ 60286296Sjah vm_offset_t pc_qmap_addr; \ 61313766Sjah void *pc_qmap_pte2p; \ 62294987Szbb unsigned int pc_dbreg[32]; \ 63294987Szbb int pc_dbreg_cmd; \ 64331988Smmel int pc_bp_harden_kind; \ 65331988Smmel uint32_t pc_original_actlr; \ 66331988Smmel char __pad[11] 67239268Sgonzo#else 68249265Sglebius#define PCPU_MD_FIELDS \ 69313766Sjah char __pad[157] 70239268Sgonzo#endif 71129198Scognet 72181875Sjhb#ifdef _KERNEL 73181875Sjhb 74294987Szbb#define PC_DBREG_CMD_NONE 0 75294987Szbb#define PC_DBREG_CMD_LOAD 1 76294987Szbb 77129198Scognetstruct pcb; 78129198Scognetstruct pcpu; 79129198Scognet 80129198Scognetextern struct pcpu *pcpup; 81261415Scognet 82284265Sandrew#if __ARM_ARCH >= 6 83261415Scognet#define CPU_MASK (0xf) 84261415Scognet 85261419Scognet#ifndef SMP 86261419Scognet#define get_pcpu() (pcpup) 87261419Scognet#else 88261415Scognet#define get_pcpu() __extension__ ({ \ 89261415Scognet int id; \ 90261415Scognet __asm __volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (id)); \ 91261415Scognet (pcpup + (id & CPU_MASK)); \ 92261415Scognet }) 93261419Scognet#endif 94290648Smmel 95261415Scognetstatic inline struct thread * 96261415Scognetget_curthread(void) 97239268Sgonzo{ 98261415Scognet void *ret; 99129198Scognet 100261415Scognet __asm __volatile("mrc p15, 0, %0, c13, c0, 4" : "=r" (ret)); 101261415Scognet return (ret); 102239268Sgonzo} 103167429Salc 104239268Sgonzostatic inline void 105261415Scognetset_curthread(struct thread *td) 106239268Sgonzo{ 107239268Sgonzo 108261415Scognet __asm __volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (td)); 109239268Sgonzo} 110239268Sgonzo 111261415Scognet 112239268Sgonzostatic inline void * 113239268Sgonzoget_tls(void) 114239268Sgonzo{ 115239268Sgonzo void *tls; 116239268Sgonzo 117307136Sed /* TPIDRURW contains the authoritative value. */ 118307136Sed __asm __volatile("mrc p15, 0, %0, c13, c0, 2" : "=r" (tls)); 119239268Sgonzo return (tls); 120239268Sgonzo} 121239268Sgonzo 122239268Sgonzostatic inline void 123239268Sgonzoset_tls(void *tls) 124239268Sgonzo{ 125239268Sgonzo 126307136Sed /* 127307136Sed * Update both TPIDRURW and TPIDRURO. TPIDRURW needs to be written 128307136Sed * first to ensure that a context switch between the two writes will 129307136Sed * still give the desired result of updating both. 130307136Sed */ 131307136Sed __asm __volatile( 132307136Sed "mcr p15, 0, %0, c13, c0, 2\n" 133307136Sed "mcr p15, 0, %0, c13, c0, 3\n" 134307136Sed : : "r" (tls)); 135239268Sgonzo} 136261415Scognet 137261415Scognet#define curthread get_curthread() 138261415Scognet 139239268Sgonzo#else 140239268Sgonzo#define get_pcpu() pcpup 141239268Sgonzo#endif 142239268Sgonzo 143239268Sgonzo#define PCPU_GET(member) (get_pcpu()->pc_ ## member) 144239268Sgonzo#define PCPU_ADD(member, value) (get_pcpu()->pc_ ## member += (value)) 145170388Sjeff#define PCPU_INC(member) PCPU_ADD(member, 1) 146245202Scognet#define PCPU_PTR(member) (&get_pcpu()->pc_ ## member) 147245202Scognet#define PCPU_SET(member,value) (get_pcpu()->pc_ ## member = (value)) 148129198Scognet 149239268Sgonzovoid pcpu0_init(void); 150129198Scognet#endif /* _KERNEL */ 151129198Scognet 152129198Scognet#endif /* !_MACHINE_PCPU_H_ */ 153