1/* $NetBSD: locore_machdep.S,v 1.8 2000/06/09 05:07:32 soda Exp $ */ 2/* $OpenBSD: locore.S,v 1.12 1997/04/19 17:19:43 pefo Exp $ */ 3 4/* 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Digital Equipment Corporation and Ralph Campbell. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * Copyright (C) 1989 Digital Equipment Corporation. 40 * Permission to use, copy, modify, and distribute this software and 41 * its documentation for any purpose and without fee is hereby granted, 42 * provided that the above copyright notice appears in all copies. 43 * Digital Equipment Corporation makes no representations about the 44 * suitability of this software for any purpose. It is provided "as is" 45 * without express or implied warranty. 46 * 47 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s, 48 * v 1.1 89/07/11 17:55:04 nelson Exp SPRITE (DECWRL) 49 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s, 50 * v 9.2 90/01/29 18:00:39 shirriff Exp SPRITE (DECWRL) 51 * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s, 52 * v 1.1 89/07/10 14:27:41 nelson Exp SPRITE (DECWRL) 53 * 54 * from: @(#)locore.s 8.5 (Berkeley) 1/4/94 55 */ 56 57/* 58 * ARC-specific mips locore code 59 */ 60 61#include <mips/asm.h> 62#include <mips/cpuregs.h> /* XXX - misnomer? */ 63#include <machine/endian.h> 64 65 .set noreorder 66 67/* 68 * GCC2 seems to want to call __main in main() for some reason. 69 */ 70LEAF(__main) 71 j ra 72 nop 73END(__main) 74 75 76/* 77 * Block I/O routines mainly used by I/O drivers. 78 * 79 * Args as: a0 = port 80 * a1 = memory address 81 * a2 = count 82 */ 83LEAF(insb) 84 beq a2, zero, 2f 85 addu a2, a1 861: 87 lbu v0, 0(a0) 88 addiu a1, 1 89 bne a1, a2, 1b 90 sb v0, -1(a1) 912: 92 jr ra 93 nop 94END(insb) 95 96LEAF(insw) 97 beq a2, zero, 2f 98 addu a2, a2 99 addu a2, a1 1001: 101 lhu v0, 0(a0) 102 addiu a1, 2 103 bne a1, a2, 1b 104 sh v0, -2(a1) 1052: 106 jr ra 107 nop 108END(insw) 109 110LEAF(insl) 111 beq a2, zero, 2f 112 sll a2, 2 113 addu a2, a1 1141: 115 lw v0, 0(a0) 116 addiu a1, 4 117 bne a1, a2, 1b 118 sw v0, -4(a1) 1192: 120 jr ra 121 nop 122END(insl) 123 124LEAF(outsb) 125 beq a2, zero, 2f 126 addu a2, a1 1271: 128 lbu v0, 0(a1) 129 addiu a1, 1 130 bne a1, a2, 1b 131 sb v0, 0(a0) 1322: 133 jr ra 134 nop 135END(outsb) 136 137LEAF(outsw) 138 beq a2, zero, 2f 139 addu a2, a2 140 li v0, 1 141 and v0, a1 142 bne v0, zero, 3f # arghh, unaligned. 143 addu a2, a1 1441: 145 lhu v0, 0(a1) 146 addiu a1, 2 147 bne a1, a2, 1b 148 sh v0, 0(a0) 1492: 150 jr ra 151 nop 1523: 153 LWHI v0, 0(a1) 154 LWLO v0, 3(a1) 155 addiu a1, 2 156 bne a1, a2, 3b 157 sh v0, 0(a0) 158 159 jr ra 160 nop 161END(outsw) 162 163LEAF(outsl) 164 beq a2, zero, 2f 165 sll a2, 2 166 li v0, 3 167 and v0, a1 168 bne v0, zero, 3f # arghh, unaligned. 169 addu a2, a1 1701: 171 lw v0, 0(a1) 172 addiu a1, 4 173 bne a1, a2, 1b 174 sw v0, 0(a0) 1752: 176 jr ra 177 nop 1783: 179 LWHI v0, 0(a1) 180 LWLO v0, 3(a1) 181 addiu a1, 4 182 bne a1, a2, 3b 183 sw v0, 0(a0) 184 185 jr ra 186 nop 187END(outsl) 188 189/* 190 * fillw(pat, addr, count) 191 */ 192LEAF(fillw) 1931: 194 addiu a2, a2, -1 195 sh a0, 0(a1) 196 bne a2,zero, 1b 197 addiu a1, a1, 2 198 199 jr ra 200 nop 201END(fillw) 202 203/*#ifdef DEBUG*/ /* for minidebug.c: fix trap() to use this */ 204#if 0 205/* 206 * Read a long and return it. 207 * Note: addresses can be unaligned! 208 * 209 * long 210L* mdbpeek(addr) 211L* caddt_t addr; 212L* { 213L* return (*(long *)addr); 214L* } 215 */ 216LEAF(mdbpeek) 217 li v0, MDBERR 218 sw v0, UADDR+U_PCB_ONFAULT 219 and v0, a0, 3 # unaligned address? 220 bne v0, zero, 1f 221 nop 222 b 2f 223 lw v0, (a0) # aligned access 2241: 225 LWHI v0, 0(a0) # get next 4 bytes (unaligned) 226 LWLO v0, 3(a0) 2272: 228 j ra # made it w/o errors 229 sw zero, UADDR+U_PCB_ONFAULT 230mdberr: 231 li v0, 1 # trap sends us here 232 sw v0, mdbmkfault 233 j ra 234 nop 235END(mdbpeek) 236 237/* 238 * Write a long to 'addr'. 239 * Note: addresses can be unaligned! 240 * 241L* void 242L* mdbpoke(addr, value) 243L* caddt_t addr; 244L* long value; 245L* { 246L* *(long *)addr = value; 247L* } 248 */ 249LEAF(mdbpoke) 250 li v0, MDBERR 251 sw v0, UADDR+U_PCB_ONFAULT 252 and v0, a0, 3 # unaligned address? 253 bne v0, zero, 1f 254 nop 255 b 2f 256 sw a1, (a0) # aligned access 2571: 258 SWHI a1, 0(a0) # store next 4 bytes (unaligned) 259 SWLO a1, 3(a0) 260 and a0, a0, ~3 # align address for cache flush 2612: 262 sw zero, UADDR+U_PCB_ONFAULT 263 b R4K_FlushICache # flush instruction cache 264 li a1, 8 265END(mdbpoke) 266 267/* 268 * Save registers and state so we can do a 'mdbreset' (like longjmp) later. 269 * Always returns zero. 270 * 271L* int mdb_savearea[11]; 272L* 273L* int 274L* mdbsetexit() 275L* { 276L* mdb_savearea[0] = 0; 277L* return (0); 278L* } 279 */ 280 .comm mdb_savearea, (11 * 4) 281 282LEAF(mdbsetexit) 283 la a0, mdb_savearea 284 sw s0, 0(a0) 285 sw s1, 4(a0) 286 sw s2, 8(a0) 287 sw s3, 12(a0) 288 sw s4, 16(a0) 289 sw s5, 20(a0) 290 sw s6, 24(a0) 291 sw s7, 28(a0) 292 sw sp, 32(a0) 293 sw s8, 36(a0) 294 sw ra, 40(a0) 295 j ra 296 move v0, zero 297END(mdbsetexit) 298 299/* 300 * Restore registers and state (like longjmp) and return x. 301 * 302L* int 303L* mdbreset(x) 304L* { 305L* return (x); 306L* } 307 */ 308LEAF(mdbreset) 309 la v0, mdb_savearea 310 lw ra, 40(v0) 311 lw s0, 0(v0) 312 lw s1, 4(v0) 313 lw s2, 8(v0) 314 lw s3, 12(v0) 315 lw s4, 16(v0) 316 lw s5, 20(v0) 317 lw s6, 24(v0) 318 lw s7, 28(v0) 319 lw sp, 32(v0) 320 lw s8, 36(v0) 321 j ra 322 move v0, a0 323END(mdbreset) 324 325/* 326 * Trap into the debugger. 327 * 328L* void 329L* mdbpanic() 330L* { 331L* } 332 */ 333LEAF(mdbpanic) 334 break BREAK_SOVER_VAL 335 j ra 336 nop 337END(mdbpanic) 338#endif /* DEBUG */ 339 340 .set mips3 341 342/*-------------------------------------------------------------------------- 343 * 344 * mips3_TLBWriteIndexedVPS -- 345 * 346 * Write the given entry into the TLB at the given index. 347 * Pass full r4000 tlb info including variable page size mask. 348 * 349 * mips3_TLBWriteIndexed(index, tlb) 350 * unsigned index; 351 * tlb *tlb; 352 * 353 * Results: 354 * None. 355 * 356 * Side effects: 357 * TLB entry set. 358 * 359 *-------------------------------------------------------------------------- 360 */ 361LEAF(mips3_TLBWriteIndexedVPS) 362 mfc0 v1, MIPS_COP_0_STATUS_REG # Save the status register. 363 mtc0 zero, MIPS_COP_0_STATUS_REG # Disable interrupts 364 nop 365 lw a2, 8(a1) 366 lw a3, 12(a1) 367 dmfc0 v0, MIPS_COP_0_TLB_PG_MASK # Save current page mask. 368 dmfc0 t0, MIPS_COP_0_TLB_HI # Save the current PID. 369 370 dmtc0 a2, MIPS_COP_0_TLB_LO0 # Set up entry low0. 371 dmtc0 a3, MIPS_COP_0_TLB_LO1 # Set up entry low1. 372 nop 373 lw a2, 0(a1) 374 lw a3, 4(a1) 375 nop 376 mtc0 a0, MIPS_COP_0_TLB_INDEX # Set the index. 377 dmtc0 a2, MIPS_COP_0_TLB_PG_MASK # Set up entry mask. 378 dmtc0 a3, MIPS_COP_0_TLB_HI # Set up entry high. 379 nop 380 tlbwi # Write the TLB 381 nop 382 nop 383 nop # Delay for effect 384 nop 385 386 dmtc0 t0, MIPS_COP_0_TLB_HI # Restore the PID. 387 nop 388 dmtc0 v0, MIPS_COP_0_TLB_PG_MASK # Restore page mask. 389 j ra 390 mtc0 v1, MIPS_COP_0_STATUS_REG # Restore the status register 391END(mips3_TLBWriteIndexedVPS) 392 393 394/* 395 * Interrupt counters for vmstat. 396 */ 397 .data 398 .globl _C_LABEL(intrcnt) 399 .globl _C_LABEL(eintrcnt) 400 .globl _C_LABEL(intrnames) 401 .globl _C_LABEL(eintrnames) 402_C_LABEL(intrnames): 403 .asciiz "softclock" 404 .asciiz "softnet" 405 .asciiz "fpu" 406_C_LABEL(eintrnames): 407 .align 3 408_C_LABEL(intrcnt): 409 .word 0,0,0 410_C_LABEL(eintrcnt): 411