16fc729afSOlivier Houchard /*- 26fc729afSOlivier Houchard * Copyright (c) 1990 The Regents of the University of California. 36fc729afSOlivier Houchard * All rights reserved. 46fc729afSOlivier Houchard * 56fc729afSOlivier Houchard * Redistribution and use in source and binary forms, with or without 66fc729afSOlivier Houchard * modification, are permitted provided that the following conditions 76fc729afSOlivier Houchard * are met: 86fc729afSOlivier Houchard * 1. Redistributions of source code must retain the above copyright 96fc729afSOlivier Houchard * notice, this list of conditions and the following disclaimer. 106fc729afSOlivier Houchard * 2. Redistributions in binary form must reproduce the above copyright 116fc729afSOlivier Houchard * notice, this list of conditions and the following disclaimer in the 126fc729afSOlivier Houchard * documentation and/or other materials provided with the distribution. 136fc729afSOlivier Houchard * 3. All advertising materials mentioning features or use of this software 146fc729afSOlivier Houchard * must display the following acknowledgement: 156fc729afSOlivier Houchard * This product includes software developed by the University of 166fc729afSOlivier Houchard * California, Berkeley and its contributors. 176fc729afSOlivier Houchard * 4. Neither the name of the University nor the names of its contributors 186fc729afSOlivier Houchard * may be used to endorse or promote products derived from this software 196fc729afSOlivier Houchard * without specific prior written permission. 206fc729afSOlivier Houchard * 216fc729afSOlivier Houchard * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 226fc729afSOlivier Houchard * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 236fc729afSOlivier Houchard * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 246fc729afSOlivier Houchard * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 256fc729afSOlivier Houchard * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 266fc729afSOlivier Houchard * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 276fc729afSOlivier Houchard * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 286fc729afSOlivier Houchard * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 296fc729afSOlivier Houchard * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 306fc729afSOlivier Houchard * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 316fc729afSOlivier Houchard * SUCH DAMAGE. 326fc729afSOlivier Houchard * 336fc729afSOlivier Houchard * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 346fc729afSOlivier Houchard */ 356fc729afSOlivier Houchard 366fc729afSOlivier Houchard #include <sys/cdefs.h> 376fc729afSOlivier Houchard __FBSDID("$FreeBSD$"); 386fc729afSOlivier Houchard 3924c1c3bfSJonathan Anderson #include "opt_capsicum.h" 4074b5505eSRobert Watson 416fc729afSOlivier Houchard #include <sys/param.h> 426fc729afSOlivier Houchard #include <sys/systm.h> 4374b5505eSRobert Watson #include <sys/capability.h> 446fc729afSOlivier Houchard #include <sys/proc.h> 456fc729afSOlivier Houchard #include <sys/sysproto.h> 466fc729afSOlivier Houchard #include <sys/syscall.h> 476fc729afSOlivier Houchard #include <sys/sysent.h> 486fc729afSOlivier Houchard 49371853e5SOlivier Houchard #include <machine/sysarch.h> 50371853e5SOlivier Houchard 516fc729afSOlivier Houchard #ifndef _SYS_SYSPROTO_H_ 526fc729afSOlivier Houchard struct sysarch_args { 536fc729afSOlivier Houchard int op; 546fc729afSOlivier Houchard char *parms; 556fc729afSOlivier Houchard }; 566fc729afSOlivier Houchard #endif 576fc729afSOlivier Houchard 58371853e5SOlivier Houchard /* Prototypes */ 59371853e5SOlivier Houchard static int arm32_sync_icache (struct thread *, void *); 60371853e5SOlivier Houchard static int arm32_drain_writebuf(struct thread *, void *); 61371853e5SOlivier Houchard 62371853e5SOlivier Houchard static int 63371853e5SOlivier Houchard arm32_sync_icache(struct thread *td, void *args) 64371853e5SOlivier Houchard { 65371853e5SOlivier Houchard struct arm_sync_icache_args ua; 66371853e5SOlivier Houchard int error; 67371853e5SOlivier Houchard 68371853e5SOlivier Houchard if ((error = copyin(args, &ua, sizeof(ua))) != 0) 69371853e5SOlivier Houchard return (error); 70371853e5SOlivier Houchard 71371853e5SOlivier Houchard cpu_icache_sync_range(ua.addr, ua.len); 72371853e5SOlivier Houchard 73371853e5SOlivier Houchard td->td_retval[0] = 0; 74371853e5SOlivier Houchard return (0); 75371853e5SOlivier Houchard } 76371853e5SOlivier Houchard 77371853e5SOlivier Houchard static int 78371853e5SOlivier Houchard arm32_drain_writebuf(struct thread *td, void *args) 79371853e5SOlivier Houchard { 80371853e5SOlivier Houchard /* No args. */ 81371853e5SOlivier Houchard 82371853e5SOlivier Houchard td->td_retval[0] = 0; 83371853e5SOlivier Houchard cpu_drain_writebuf(); 84371853e5SOlivier Houchard return (0); 85371853e5SOlivier Houchard } 86371853e5SOlivier Houchard 87a74985cdSOlivier Houchard static int 88a74985cdSOlivier Houchard arm32_set_tp(struct thread *td, void *args) 89a74985cdSOlivier Houchard { 90a74985cdSOlivier Houchard 91*cf1a573fSOleksandr Tymoshenko if (td != curthread) 92ae5b8077SWarner Losh td->td_md.md_tp = (register_t)args; 93*cf1a573fSOleksandr Tymoshenko else 94*cf1a573fSOleksandr Tymoshenko #ifndef ARM_TP_ADDRESS 95*cf1a573fSOleksandr Tymoshenko set_tls(args); 96*cf1a573fSOleksandr Tymoshenko #else 97*cf1a573fSOleksandr Tymoshenko *(register_t *)ARM_TP_ADDRESS = (register_t)args; 98*cf1a573fSOleksandr Tymoshenko #endif 99a74985cdSOlivier Houchard return (0); 100a74985cdSOlivier Houchard } 101a74985cdSOlivier Houchard 102a74985cdSOlivier Houchard static int 103a74985cdSOlivier Houchard arm32_get_tp(struct thread *td, void *args) 104a74985cdSOlivier Houchard { 105a74985cdSOlivier Houchard 106*cf1a573fSOleksandr Tymoshenko if (td != curthread) 107ae5b8077SWarner Losh td->td_retval[0] = td->td_md.md_tp; 108*cf1a573fSOleksandr Tymoshenko else 109*cf1a573fSOleksandr Tymoshenko #ifndef ARM_TP_ADDRESS 110*cf1a573fSOleksandr Tymoshenko td->td_retval[0] = (register_t)get_tls(); 111*cf1a573fSOleksandr Tymoshenko #else 112*cf1a573fSOleksandr Tymoshenko td->td_retval[0] = *(register_t *)ARM_TP_ADDRESS; 113*cf1a573fSOleksandr Tymoshenko #endif 114a74985cdSOlivier Houchard return (0); 115a74985cdSOlivier Houchard } 116a74985cdSOlivier Houchard 1176fc729afSOlivier Houchard int 1186fc729afSOlivier Houchard sysarch(td, uap) 1196fc729afSOlivier Houchard struct thread *td; 1206fc729afSOlivier Houchard register struct sysarch_args *uap; 1216fc729afSOlivier Houchard { 122371853e5SOlivier Houchard int error; 123371853e5SOlivier Houchard 12424c1c3bfSJonathan Anderson #ifdef CAPABILITY_MODE 12574b5505eSRobert Watson /* 12612bc222eSJonathan Anderson * When adding new operations, add a new case statement here to 12712bc222eSJonathan Anderson * explicitly indicate whether or not the operation is safe to 12812bc222eSJonathan Anderson * perform in capability mode. 12974b5505eSRobert Watson */ 13074b5505eSRobert Watson if (IN_CAPABILITY_MODE(td)) { 13174b5505eSRobert Watson switch (uap->op) { 13274b5505eSRobert Watson case ARM_SYNC_ICACHE: 13374b5505eSRobert Watson case ARM_DRAIN_WRITEBUF: 13474b5505eSRobert Watson case ARM_SET_TP: 13574b5505eSRobert Watson case ARM_GET_TP: 13674b5505eSRobert Watson break; 13774b5505eSRobert Watson 13874b5505eSRobert Watson default: 139a417d4a4SDag-Erling Smørgrav #ifdef KTRACE 140a417d4a4SDag-Erling Smørgrav if (KTRPOINT(td, KTR_CAPFAIL)) 141a417d4a4SDag-Erling Smørgrav ktrcapfail(CAPFAIL_SYSCALL, 0, 0); 142a417d4a4SDag-Erling Smørgrav #endif 14374b5505eSRobert Watson return (ECAPMODE); 14474b5505eSRobert Watson } 14574b5505eSRobert Watson } 14674b5505eSRobert Watson #endif 14774b5505eSRobert Watson 148371853e5SOlivier Houchard switch (uap->op) { 149371853e5SOlivier Houchard case ARM_SYNC_ICACHE: 150371853e5SOlivier Houchard error = arm32_sync_icache(td, uap->parms); 151371853e5SOlivier Houchard break; 152371853e5SOlivier Houchard case ARM_DRAIN_WRITEBUF: 153371853e5SOlivier Houchard error = arm32_drain_writebuf(td, uap->parms); 154371853e5SOlivier Houchard break; 155a74985cdSOlivier Houchard case ARM_SET_TP: 156a74985cdSOlivier Houchard error = arm32_set_tp(td, uap->parms); 157a74985cdSOlivier Houchard break; 158a74985cdSOlivier Houchard case ARM_GET_TP: 159a74985cdSOlivier Houchard error = arm32_get_tp(td, uap->parms); 160a74985cdSOlivier Houchard break; 161371853e5SOlivier Houchard default: 162371853e5SOlivier Houchard error = EINVAL; 163371853e5SOlivier Houchard break; 164371853e5SOlivier Houchard } 165371853e5SOlivier Houchard return (error); 1666fc729afSOlivier Houchard } 167