1/* $NetBSD: rmixl_subr.S,v 1.4 2011/04/14 05:20:08 cliff Exp $ */ 2 3/*- 4 * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Cliff Neighbors. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include "opt_cputype.h" 33#include "opt_multiprocessor.h" 34 35#include <sys/cdefs.h> 36 37#include <mips/asm.h> 38#include <mips/cpuregs.h> 39 40RCSID("$NetBSD: rmixl_subr.S,v 1.4 2011/04/14 05:20:08 cliff Exp $"); 41 42#include "assym.h" 43 44#define RMIXL_COP_0_EIRR _(9), 6 45#define RMIXL_COP_0_EIMR _(9), 7 46 47 .set noreorder 48 .set arch=xlr 49 .text 50 51/* 52 * read XLS Processor Control register 53 * 54 * uint64_t rmixl_mfcr(u_int cr); 55 */ 56LEAF(rmixl_mfcr) 57#if defined(__mips_o32) 58#error O32 not supported 59#endif 60 j ra 61 mfcr v0, a0 62END(rmixl_mfcr) 63 64/* 65 * write XLS Processor Control register 66 * 67 * void rmixl_mtcr(u_int cr, uint64_t val); 68 */ 69LEAF(rmixl_mtcr) 70#if defined(__mips_o32) 71#error O32 not supported 72#endif 73 j ra 74 mtcr a1, a0 75END(rmixl_mtcr) 76 77/* 78 * void rmixl_eirr_ack(uint64_t eimr, uint64_t vecbit, uint64_t preserve) 79 * 80 * ack in EIRR the irq we are about to handle 81 * disable all interrupts to prevent a race that would allow 82 * e.g. softints set from a higher interrupt getting 83 * clobbered by the EIRR read-modify-write 84 */ 85LEAF(rmixl_eirr_ack) 86 dmtc0 zero, RMIXL_COP_0_EIMR /* EIMR = 0 */ 87 COP0_SYNC 88 dmfc0 a3, RMIXL_COP_0_EIRR /* a3 = EIRR */ 89 and a3, a2 /* a3 &= preserve */ 90 or a3, a1 /* a3 |= vecbit */ 91 dmtc0 a3, RMIXL_COP_0_EIRR /* EIRR = a3 */ 92 COP0_SYNC 93 dmtc0 a0, RMIXL_COP_0_EIMR /* EIMR = eimr */ 94 JR_HB_RA 95END(rmixl_eirr_ack) 96 97#ifdef MULTIPROCESSOR 98/* 99 * rmixlfw_wakeup_cpu(func, args, mask, callback) 100 */ 101NESTED(rmixlfw_wakeup_cpu, CALLFRAME_SIZ+4*SZREG, ra) 102 PTR_ADDU sp, sp, -(CALLFRAME_SIZ+4*SZREG) 103 REG_S ra, CALLFRAME_RA(sp) 104 REG_S s0, CALLFRAME_S0(sp) 105 REG_S gp, CALLFRAME_SIZ+0*SZREG(sp) 106 REG_S t8, CALLFRAME_SIZ+1*SZREG(sp) 107 mfc0 t0, MIPS_COP_0_STATUS 108 REG_S t0, CALLFRAME_SIZ+2*SZREG(sp) 109 110 move s0, sp /* save sp */ 111#ifdef _LP64 112 dsll32 t0, sp, 0 /* nuke upper half */ 113 dsrl32 t0, t0, 0 /* " " " */ 114 li t1, MIPS_KSEG0_START 115 or sp, t0, t1 /* set MIPS_KSEG0_START */ 116#endif 117 jalr a3 /* callback to firmware */ 118 nop 119 move sp, s0 /* restore sp */ 120 121 REG_L t0, CALLFRAME_SIZ+2*SZREG(sp) 122 mtc0 t0, MIPS_COP_0_STATUS 123 REG_L t8, CALLFRAME_SIZ+1*SZREG(sp) 124 REG_L gp, CALLFRAME_SIZ+0*SZREG(sp) 125 REG_L s0, CALLFRAME_S0(sp) 126 REG_L ra, CALLFRAME_RA(sp) 127 jr ra 128 PTR_ADDU sp, sp, (CALLFRAME_SIZ+4*SZREG) 129END(rmixlfw_wakeup_cpu) 130 131/* 132 * rmixl_cpu_trampoline - entry point for subordinate (non-#0) CPU wakeup 133 */ 134NESTED(rmixl_cpu_trampoline, CALLFRAME_SIZ, ra) 135#ifdef _LP64 136 /* 137 * reconstruct trampoline args addr: 138 * sign-extend 32 bit KSEG0 address in a0 139 * to make proper 64 bit KSEG0 addr 140 */ 141 sll s0, a0, 0 142 li t0, MIPS_SR_KX 143#else 144 li t0, 0 145#endif 146 147 mtc0 zero, $9, 7 /* disable all in MIPS_COP_0_EIMR */ 148 149 mtc0 t0, MIPS_COP_0_STATUS 150 151 /* ensure COP_0_EBASE field 'EBASE' is 0 */ 152 mfc0 t0, $15, 1 /* MIPS_COP_0_EBASE */ 153 and t0, t0, 0x3ff 154 mtc0 t0, $15, 1 /* MIPS_COP_0_EBASE */ 155 156 /* 157 * load our stack pointer from trampoline args 158 */ 159 REG_L sp, 0*SZREG(s0) /* XXX ta_sp */ 160 161 /* 162 * load our (idle) lwp from trampoline args 163 * save in t8 reg dedicated as 'mips_curlwp' 164 */ 165 REG_L t8, 1*SZREG(s0) /* XXX ta_lwp */ 166 167 /* 168 * load our ta_cpuinfo from trampoline args and pass in a1 169 * jump to common mips cpu_trampoline 170 */ 171 REG_L a1, 2*SZREG(s0) /* XXX ta_cpuinfo */ 172 dmtc0 a1, $22, 0 /* MIPS_COP_0_OSSCRATCH */ 173 j cpu_trampoline 174 nop 175 176 /* NOTREACHED */ 177 178END(rmixl_cpu_trampoline) 179 180#endif /* MULTIPROCESSOR */ 181