1/* $NetBSD: locore_machdep.S,v 1.16 2009/11/27 03:23:04 rmind 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. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * Copyright (C) 1989 Digital Equipment Corporation. 36 * Permission to use, copy, modify, and distribute this software and 37 * its documentation for any purpose and without fee is hereby granted, 38 * provided that the above copyright notice appears in all copies. 39 * Digital Equipment Corporation makes no representations about the 40 * suitability of this software for any purpose. It is provided "as is" 41 * without express or implied warranty. 42 * 43 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s, 44 * v 1.1 89/07/11 17:55:04 nelson Exp SPRITE (DECWRL) 45 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s, 46 * v 9.2 90/01/29 18:00:39 shirriff Exp SPRITE (DECWRL) 47 * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s, 48 * v 1.1 89/07/10 14:27:41 nelson Exp SPRITE (DECWRL) 49 * 50 * from: @(#)locore.s 8.5 (Berkeley) 1/4/94 51 */ 52 53/* 54 * ARC-specific mips locore code 55 */ 56 57#include <mips/asm.h> 58#include <mips/cpuregs.h> /* XXX - misnomer? */ 59#include <machine/endian.h> 60 61 .set noreorder 62 63/* 64 * GCC2 seems to want to call __main in main() for some reason. 65 */ 66LEAF(__main) 67 j ra 68 nop 69END(__main) 70 71 72/* 73 * Block I/O routines mainly used by I/O drivers. 74 * 75 * Args as: a0 = port 76 * a1 = memory address 77 * a2 = count 78 */ 79LEAF(insb) 80 beq a2, zero, 2f 81 addu a2, a1 821: 83 lbu v0, 0(a0) 84 addiu a1, 1 85 bne a1, a2, 1b 86 sb v0, -1(a1) 872: 88 jr ra 89 nop 90END(insb) 91 92LEAF(insw) 93 beq a2, zero, 2f 94 addu a2, a2 95 addu a2, a1 961: 97 lhu v0, 0(a0) 98 addiu a1, 2 99 bne a1, a2, 1b 100 sh v0, -2(a1) 1012: 102 jr ra 103 nop 104END(insw) 105 106LEAF(insl) 107 beq a2, zero, 2f 108 sll a2, 2 109 addu a2, a1 1101: 111 lw v0, 0(a0) 112 addiu a1, 4 113 bne a1, a2, 1b 114 sw v0, -4(a1) 1152: 116 jr ra 117 nop 118END(insl) 119 120LEAF(outsb) 121 beq a2, zero, 2f 122 addu a2, a1 1231: 124 lbu v0, 0(a1) 125 addiu a1, 1 126 bne a1, a2, 1b 127 sb v0, 0(a0) 1282: 129 jr ra 130 nop 131END(outsb) 132 133LEAF(outsw) 134 beq a2, zero, 2f 135 addu a2, a2 136 li v0, 1 137 and v0, a1 138 bne v0, zero, 3f # arghh, unaligned. 139 addu a2, a1 1401: 141 lhu v0, 0(a1) 142 addiu a1, 2 143 bne a1, a2, 1b 144 sh v0, 0(a0) 1452: 146 jr ra 147 nop 1483: 149 LWHI v0, 0(a1) 150 LWLO v0, 3(a1) 151 addiu a1, 2 152 bne a1, a2, 3b 153 sh v0, 0(a0) 154 155 jr ra 156 nop 157END(outsw) 158 159LEAF(outsl) 160 beq a2, zero, 2f 161 sll a2, 2 162 li v0, 3 163 and v0, a1 164 bne v0, zero, 3f # arghh, unaligned. 165 addu a2, a1 1661: 167 lw v0, 0(a1) 168 addiu a1, 4 169 bne a1, a2, 1b 170 sw v0, 0(a0) 1712: 172 jr ra 173 nop 1743: 175 LWHI v0, 0(a1) 176 LWLO v0, 3(a1) 177 addiu a1, 4 178 bne a1, a2, 3b 179 sw v0, 0(a0) 180 181 jr ra 182 nop 183END(outsl) 184 185/* 186 * fillw(pat, addr, count) 187 */ 188LEAF(fillw) 1891: 190 addiu a2, a2, -1 191 sh a0, 0(a1) 192 bne a2,zero, 1b 193 addiu a1, a1, 2 194 195 jr ra 196 nop 197END(fillw) 198 199/*#ifdef DEBUG*/ /* for minidebug.c: fix trap() to use this */ 200#if 0 201/* 202 * Read a long and return it. 203 * Note: addresses can be unaligned! 204 * 205 * long 206L* mdbpeek(addr) 207L* caddt_t addr; 208L* { 209L* return (*(long *)addr); 210L* } 211 */ 212LEAF(mdbpeek) 213 li v0, MDBERR 214 sw v0, UADDR+PCB_ONFAULT 215 and v0, a0, 3 # unaligned address? 216 bne v0, zero, 1f 217 nop 218 b 2f 219 lw v0, (a0) # aligned access 2201: 221 LWHI v0, 0(a0) # get next 4 bytes (unaligned) 222 LWLO v0, 3(a0) 2232: 224 j ra # made it w/o errors 225 sw zero, UADDR+PCB_ONFAULT 226mdberr: 227 li v0, 1 # trap sends us here 228 sw v0, mdbmkfault 229 j ra 230 nop 231END(mdbpeek) 232 233/* 234 * Write a long to 'addr'. 235 * Note: addresses can be unaligned! 236 * 237L* void 238L* mdbpoke(addr, value) 239L* caddt_t addr; 240L* long value; 241L* { 242L* *(long *)addr = value; 243L* } 244 */ 245LEAF(mdbpoke) 246 li v0, MDBERR 247 sw v0, UADDR+PCB_ONFAULT 248 and v0, a0, 3 # unaligned address? 249 bne v0, zero, 1f 250 nop 251 b 2f 252 sw a1, (a0) # aligned access 2531: 254 SWHI a1, 0(a0) # store next 4 bytes (unaligned) 255 SWLO a1, 3(a0) 256 and a0, a0, ~3 # align address for cache flush 2572: 258 sw zero, UADDR+PCB_ONFAULT 259 b R4K_FlushICache # flush instruction cache 260 li a1, 8 261END(mdbpoke) 262 263/* 264 * Save registers and state so we can do a 'mdbreset' (like longjmp) later. 265 * Always returns zero. 266 * 267L* int mdb_savearea[11]; 268L* 269L* int 270L* mdbsetexit() 271L* { 272L* mdb_savearea[0] = 0; 273L* return (0); 274L* } 275 */ 276 .comm mdb_savearea, (11 * 4) 277 278LEAF(mdbsetexit) 279 la a0, mdb_savearea 280 sw s0, 0(a0) 281 sw s1, 4(a0) 282 sw s2, 8(a0) 283 sw s3, 12(a0) 284 sw s4, 16(a0) 285 sw s5, 20(a0) 286 sw s6, 24(a0) 287 sw s7, 28(a0) 288 sw sp, 32(a0) 289 sw s8, 36(a0) 290 sw ra, 40(a0) 291 j ra 292 move v0, zero 293END(mdbsetexit) 294 295/* 296 * Restore registers and state (like longjmp) and return x. 297 * 298L* int 299L* mdbreset(x) 300L* { 301L* return (x); 302L* } 303 */ 304LEAF(mdbreset) 305 la v0, mdb_savearea 306 lw ra, 40(v0) 307 lw s0, 0(v0) 308 lw s1, 4(v0) 309 lw s2, 8(v0) 310 lw s3, 12(v0) 311 lw s4, 16(v0) 312 lw s5, 20(v0) 313 lw s6, 24(v0) 314 lw s7, 28(v0) 315 lw sp, 32(v0) 316 lw s8, 36(v0) 317 j ra 318 move v0, a0 319END(mdbreset) 320 321/* 322 * Trap into the debugger. 323 * 324L* void 325L* mdbpanic() 326L* { 327L* } 328 */ 329LEAF(mdbpanic) 330 break BREAK_SOVER_VAL 331 j ra 332 nop 333END(mdbpanic) 334#endif /* DEBUG */ 335