1/* $NetBSD: locore_mips3.S,v 1.116 2023/02/23 14:56:00 riastradh Exp $ */ 2 3/* 4 * Copyright (c) 1997 Jonathan Stone (hereinafter referred to as the author) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Jonathan R. Stone for 18 * the NetBSD Project. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35/* 36 * Copyright (c) 1992, 1993 37 * The Regents of the University of California. All rights reserved. 38 * 39 * This code is derived from software contributed to Berkeley by 40 * Digital Equipment Corporation and Ralph Campbell. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. Neither the name of the University nor the names of its contributors 51 * may be used to endorse or promote products derived from this software 52 * without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * SUCH DAMAGE. 65 * 66 * Copyright (C) 1989 Digital Equipment Corporation. 67 * Permission to use, copy, modify, and distribute this software and 68 * its documentation for any purpose and without fee is hereby granted, 69 * provided that the above copyright notice appears in all copies. 70 * Digital Equipment Corporation makes no representations about the 71 * suitability of this software for any purpose. It is provided "as is" 72 * without express or implied warranty. 73 * 74 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s, 75 * v 1.1 89/07/11 17:55:04 nelson Exp SPRITE (DECWRL) 76 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s, 77 * v 9.2 90/01/29 18:00:39 shirriff Exp SPRITE (DECWRL) 78 * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s, 79 * v 1.1 89/07/10 14:27:41 nelson Exp SPRITE (DECWRL) 80 * 81 * @(#)locore.s 8.5 (Berkeley) 1/4/94 82 */ 83#include "opt_cputype.h" 84#include "opt_ddb.h" 85#include "opt_lockdebug.h" 86#include "opt_multiprocessor.h" 87#include "opt_kgdb.h" 88 89#include <sys/cdefs.h> 90#include <sys/endian.h> 91 92#include <mips/asm.h> 93#include <mips/cpuregs.h> 94 95RCSID("$NetBSD: locore_mips3.S,v 1.116 2023/02/23 14:56:00 riastradh Exp $") 96 97#include "assym.h" 98 99/* 100 * XXX We need a cleaner way of handling the instruction hazards of 101 * the various processors. Here are the relevant rules for the QED 52XX: 102 * tlbw[ri] -- two integer ops beforehand 103 * tlbr -- two integer ops beforehand 104 * tlbp -- two integer ops beforehand 105 * mtc0 [PageMask,EntryHi,Cp0] -- two integer ops afterwards 106 * changing JTLB -- two integer ops afterwards 107 * mtc0 [EPC,ErrorEPC,Status] -- two int ops afterwards before eret 108 * config.k0 -- five int ops before kseg0, ckseg0 memref 109 * 110 * For the IDT R4000, some hazards are: 111 * mtc0/mfc0 one integer op before and after 112 * tlbp -- one integer op afterwards 113 * Obvious solution is to take least common denominator. 114 */ 115 116/* 117 *============================================================================ 118 * 119 * MIPS III ISA support, part 1: locore exception vectors. 120 * The following code is copied to the vector locations to which 121 * the CPU jumps in response to an exception or a TLB miss. 122 * 123 *============================================================================ 124 */ 125 .set noreorder 126#if (__mips < 3) || __mips_o32 127 .set mips3 128#endif 129 130#ifdef _LP64 131#define _MFC0 dmfc0 132#define _MTC0 dmtc0 133#else 134#define _MFC0 mfc0 135#define _MTC0 mtc0 136#endif 137 138 .text 139 140/*---------------------------------------------------------------------------- 141 * 142 * mips3_wbflush -- 143 * 144 * Return when the write buffer is empty. 145 * 146 * Common for all MIPS3 and greater ISAs 147 * 148 * Results: 149 * None. 150 * 151 * Side effects: 152 * None. 153 * 154 *---------------------------------------------------------------------------- 155 */ 156LEAF(mips3_wbflush) 157XLEAF(loongson2_wbflush) 158XLEAF(mips32_wbflush) 159XLEAF(mips32r2_wbflush) 160XLEAF(mips64_wbflush) 161XLEAF(mips64r2_wbflush) 162 nop 163 sync 164 jr ra 165 nop 166END(mips3_wbflush) 167 168 169/* 170 * mips_wait_idle: 171 * 172 * When no processes are on the runq, cpu_idle branches to 173 * mips_wait_idle to save power. 174 */ 175LEAF(mips_wait_idle) 176 mfc0 v0, MIPS_COP_0_STATUS 177 andi v1, v0, MIPS_SR_INT_IE 178#if __mips >= 32 179 teqi v1, 0 180#else 181 beqz v1, 1f 182 nop 183#endif 184 andi v1, v0, MIPS_INT_MASK 185#if __mips >= 32 186 teqi v1, 0 187#else 188 bnez v1, 2f 189 nop 1901: 191 move a1, v0 192 PANIC("mips_wait_idle: interrupts disabled status=%#x") 193#endif 194 1952: wait 196 nop 197 nop 198 nop 199 mfc0 v0, MIPS_COP_0_STATUS 200 andi v1, v0, MIPS_SR_INT_IE 201#if __mips >= 32 202 teqi v1, 0 203#else 204 beqz v1, 1b 205 nop 206#endif 207 andi v1, v0, MIPS_INT_MASK 208#if __mips >= 32 209 teqi v1, 0 210#else 211 beqz v1, 1b 212 nop 213#endif 214 jr ra 215 nop 216END(mips_wait_idle) 217 218/* 219 * uint32_t mips3_cp0_compare_read(void) 220 * 221 * Return the current value of the CP0 Compare register. 222 */ 223LEAF(mips3_cp0_compare_read) 224 mfc0 v0, MIPS_COP_0_COMPARE 225 jr ra 226 nop 227END(mips3_cp0_compare_read) 228 229/* 230 * void mips3_cp0_compare_write(uint32_t) 231 * 232 * Set the value of the CP0 Compare register. 233 */ 234LEAF(mips3_cp0_compare_write) 235 mtc0 a0, MIPS_COP_0_COMPARE 236 JR_HB_RA 237END(mips3_cp0_compare_write) 238 239/* 240 * uint32_t mips3_cp0_config_read(void) 241 * 242 * Return the current value of the CP0 Config register. 243 */ 244LEAF(mips3_cp0_config_read) 245 mfc0 v0, MIPS_COP_0_CONFIG 246 jr ra 247 nop 248END(mips3_cp0_config_read) 249 250/* 251 * void mips3_cp0_config_write(uint32_t) 252 * 253 * Set the value of the CP0 Config register. 254 */ 255LEAF(mips3_cp0_config_write) 256 mtc0 a0, MIPS_COP_0_CONFIG 257 JR_HB_RA 258END(mips3_cp0_config_write) 259 260#if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 261 .set push 262#ifdef __mips_o32 263 .set mips32 264#else 265 .set mips64 266#endif 267/* 268 * uint32_t mipsNN_cp0_config1_read(void) 269 * 270 * Return the current value of the CP0 Config (Select 1) register. 271 */ 272LEAF(mipsNN_cp0_config1_read) 273 mfc0 v0, MIPS_COP_0_CONFIG, 1 274 jr ra 275 nop 276END(mipsNN_cp0_config1_read) 277 278/* 279 * uint32_t mipsNN_cp0_config1_write(uint32_t) 280 * 281 * Set the current value of the CP0 Config (Select 1) register. 282 */ 283LEAF(mipsNN_cp0_config1_write) 284 mtc0 v0, MIPS_COP_0_CONFIG, 1 285 JR_HB_RA 286END(mipsNN_cp0_config1_write) 287 288/* 289 * uint32_t mipsNN_cp0_config2_read(void) 290 * 291 * Return the current value of the CP0 Config (Select 2) register. 292 */ 293LEAF(mipsNN_cp0_config2_read) 294 mfc0 v0, MIPS_COP_0_CONFIG, 2 295 jr ra 296 nop 297END(mipsNN_cp0_config2_read) 298 299/* 300 * uint32_t mipsNN_cp0_config3_read(void) 301 * 302 * Return the current value of the CP0 Config (Select 3) register. 303 */ 304LEAF(mipsNN_cp0_config3_read) 305 mfc0 v0, MIPS_COP_0_CONFIG, 3 306 jr ra 307 nop 308END(mipsNN_cp0_config3_read) 309 310/* 311 * uint32_t mipsNN_cp0_config4_read(void) 312 * 313 * Return the current value of the CP0 Config (Select 4) register. 314 */ 315LEAF(mipsNN_cp0_config4_read) 316 mfc0 v0, MIPS_COP_0_CONFIG, 4 317 jr ra 318 nop 319END(mipsNN_cp0_config4_read) 320 321/* 322 * uint32_t mipsNN_cp0_config5_read(void) 323 * 324 * Return the current value of the CP0 Config (Select 5) register. 325 */ 326LEAF(mipsNN_cp0_config5_read) 327 mfc0 v0, MIPS_COP_0_CONFIG, 5 328 jr ra 329 nop 330END(mipsNN_cp0_config5_read) 331 332/* 333 * uint32_t mipsNN_cp0_config6_read(void) 334 * 335 * Return the current value of the CP0 Config (Select 6) register. 336 */ 337LEAF(mipsNN_cp0_config6_read) 338 mfc0 v0, MIPS_COP_0_CONFIG, 6 339 jr ra 340 nop 341END(mipsNN_cp0_config6_read) 342 343/* 344 * uint32_t mipsNN_cp0_config7_read(void) 345 * 346 * Return the current value of the CP0 Config (Select 7) register. 347 */ 348LEAF(mipsNN_cp0_config7_read) 349 mfc0 v0, MIPS_COP_0_CONFIG, 7 350 jr ra 351 nop 352END(mipsNN_cp0_config7_read) 353 354/* 355 * uintptr_t mipsNN_cp0_watchlo_read(u_int sel) 356 * 357 * Return the current value of the selected CP0 Watchlo register. 358 */ 359LEAF(mipsNN_cp0_watchlo_read) 360 sll a0, 2 361 PTR_LA t9, 1f 362 PTR_ADDU t9, a0 363 jr t9 364 nop 3651: 366 jr ra 367 _MFC0 v0, MIPS_COP_0_WATCH_LO, 0 368 jr ra 369 _MFC0 v0, MIPS_COP_0_WATCH_LO, 1 370 jr ra 371 _MFC0 v0, MIPS_COP_0_WATCH_LO, 2 372 jr ra 373 _MFC0 v0, MIPS_COP_0_WATCH_LO, 3 374 jr ra 375 _MFC0 v0, MIPS_COP_0_WATCH_LO, 4 376 jr ra 377 _MFC0 v0, MIPS_COP_0_WATCH_LO, 5 378 jr ra 379 _MFC0 v0, MIPS_COP_0_WATCH_LO, 6 380 jr ra 381 _MFC0 v0, MIPS_COP_0_WATCH_LO, 7 382END(mipsNN_cp0_watchlo_read) 383 384/* 385 * void mipsNN_cp0_watchlo_write(u_int sel, uintptr_t val) 386 * 387 * Set the current value of the selected CP0 WatchLo register. 388 */ 389LEAF(mipsNN_cp0_watchlo_write) 390 sll a0, 2 391 PTR_LA t9, 1f 392 PTR_ADDU t9, a0 393 jr t9 394 nop 3951: 396 jr ra 397 _MTC0 a1, MIPS_COP_0_WATCH_LO, 0 398 jr ra 399 _MTC0 a1, MIPS_COP_0_WATCH_LO, 1 400 jr ra 401 _MTC0 a1, MIPS_COP_0_WATCH_LO, 2 402 jr ra 403 _MTC0 a1, MIPS_COP_0_WATCH_LO, 3 404 jr ra 405 _MTC0 a1, MIPS_COP_0_WATCH_LO, 4 406 jr ra 407 _MTC0 a1, MIPS_COP_0_WATCH_LO, 5 408 jr ra 409 _MTC0 a1, MIPS_COP_0_WATCH_LO, 6 410 jr ra 411 _MTC0 a1, MIPS_COP_0_WATCH_LO, 7 412END(mipsNN_cp0_watchlo_write) 413 414/* 415 * uint32_t mipsNN_cp0_watchhi_read(u_int sel) 416 * 417 * Return the current value of the selected CP0 WatchHi register. 418 */ 419LEAF(mipsNN_cp0_watchhi_read) 420 sll a0, 2 421 PTR_LA t9, 1f 422 PTR_ADDU t9, a0 423 jr t9 424 nop 4251: 426 jr ra 427 mfc0 v0, MIPS_COP_0_WATCH_HI, 0 428 jr ra 429 mfc0 v0, MIPS_COP_0_WATCH_HI, 1 430 jr ra 431 mfc0 v0, MIPS_COP_0_WATCH_HI, 2 432 jr ra 433 mfc0 v0, MIPS_COP_0_WATCH_HI, 3 434 jr ra 435 mfc0 v0, MIPS_COP_0_WATCH_HI, 4 436 jr ra 437 mfc0 v0, MIPS_COP_0_WATCH_HI, 5 438 jr ra 439 mfc0 v0, MIPS_COP_0_WATCH_HI, 6 440 jr ra 441 mfc0 v0, MIPS_COP_0_WATCH_HI, 7 442END(mipsNN_cp0_watchhi_read) 443 444/* 445 * void mipsNN_cp0_watchhi_write(u_int sel, uint32_t val) 446 * 447 * Set the current value of the selected CP0 WatchHi register. 448 */ 449LEAF(mipsNN_cp0_watchhi_write) 450 sll a0, 2 451 PTR_LA t9, 1f 452 PTR_ADDU t9, a0 453 jr t9 454 nop 4551: 456 jr ra 457 mtc0 a1, MIPS_COP_0_WATCH_HI, 0 458 jr ra 459 mtc0 a1, MIPS_COP_0_WATCH_HI, 1 460 jr ra 461 mtc0 a1, MIPS_COP_0_WATCH_HI, 2 462 jr ra 463 mtc0 a1, MIPS_COP_0_WATCH_HI, 3 464 jr ra 465 mtc0 a1, MIPS_COP_0_WATCH_HI, 4 466 jr ra 467 mtc0 a1, MIPS_COP_0_WATCH_HI, 5 468 jr ra 469 mtc0 a1, MIPS_COP_0_WATCH_HI, 6 470 jr ra 471 mtc0 a1, MIPS_COP_0_WATCH_HI, 7 472END(mipsNN_cp0_watchhi_write) 473 474/* 475 * void mipsNN_cp0_ebase_read(void *); 476 * Get the value of the CP0 EBASE (PRID, select 1) register. 477 */ 478LEAF(mipsNN_cp0_ebase_read) 479 jr ra 480 mfc0 v0, MIPS_COP_0_EBASE 481END(mipsNN_cp0_ebase_read) 482 483/* 484 * void mipsNN_cp0_ebase_write(void *); 485 * Set the value of the CP0 EBASE (PRID, select 1) register. 486 */ 487LEAF(mipsNN_cp0_ebase_write) 488 and v0, v0, 0x1ff 489 xor v0, v0, a0 490 jr ra 491 mtc0 v0, MIPS_COP_0_EBASE 492END(mipsNN_cp0_ebase_write) 493 494#if (MIPS32R2 + MIPS64R2) > 0 495/* 496 * uint32_t mipsNN_cp0_rdhwr_cpunum(void); 497 * Set the value of the CP0 HWRENA register. 498 */ 499LEAF(mipsNN_cp0_rdhwr_cpunum) 500 .set push 501#ifdef __mips_o32 502 .set mips32r2 503#else 504 .set mips64r2 505#endif 506 jr ra 507 rdhwr v0, MIPS_HWR_CPUNUM 508 .set pop 509END(mipsNN_cp0_rdhwr_cpunum) 510 511/* 512 * void mipsNN_cp0_hwrena_write(void *); 513 * Set the value of the CP0 HWRENA register. 514 */ 515LEAF(mipsNN_cp0_hwrena_write) 516 jr ra 517 mtc0 a0, MIPS_COP_0_HWRENA 518END(mipsNN_cp0_hwrena_write) 519 520/* 521 * void mipsNN_cp0_userlocal_write(void *); 522 * Set the value of the CP0 USERLOCAL (TLB_CONTEXT, select 2) register. 523 */ 524LEAF(mipsNN_cp0_userlocal_write) 525 jr ra 526 _MTC0 a0, MIPS_COP_0_USERLOCAL 527END(mipsNN_cp0_userlocal_write) 528#endif /* (MIPS32R2 + MIPS64R2) > 0 */ 529 .set pop 530#endif /* (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 */ 531 532/* 533 * uint32_t mips3_cp0_count_read(void) 534 * 535 * Return the current value of the CP0 Count register. 536 */ 537LEAF(mips3_cp0_count_read) 538 mfc0 v0, MIPS_COP_0_COUNT 539 jr ra 540 nop 541END(mips3_cp0_count_read) 542WEAK_ALIAS(cpu_counter32, mips3_cp0_count_read) 543 544/* 545 * void mips3_cp0_count_write(uint32_t) 546 * 547 * Set the value of the CP0 Count register. 548 */ 549LEAF(mips3_cp0_count_write) 550 mtc0 a0, MIPS_COP_0_COUNT 551 JR_HB_RA 552END(mips3_cp0_count_write) 553 554/* 555 * uint32_t mips3_cp0_wired_read(void) 556 * 557 * Return the current value of the CP0 Wired register. 558 */ 559LEAF(mips3_cp0_wired_read) 560 mfc0 v0, MIPS_COP_0_TLB_WIRED 561 jr ra 562 nop 563END(mips3_cp0_wired_read) 564 565/* 566 * void mips3_cp0_wired_write(uint32_t) 567 * 568 * Set the value of the CP0 Wired register. 569 */ 570LEAF(mips3_cp0_wired_write) 571 mtc0 a0, MIPS_COP_0_TLB_WIRED 572 JR_HB_RA 573END(mips3_cp0_wired_write) 574 575/* 576 * void mips3_cp0_pg_mask_write(uint32_t) 577 * 578 * Set the value of the CP0 PG_MASK register. 579 */ 580LEAF(mips3_cp0_pg_mask_write) 581 mtc0 a0, MIPS_COP_0_TLB_PG_MASK 582 JR_HB_RA 583END(mips3_cp0_pg_mask_write) 584 585#if __mips != 32 586LEAF(mips3_ld) 587#if defined(__mips_o32) 588#if (MIPS64R2) > 0 589 di t0 590#else 591 mfc0 t0, MIPS_COP_0_STATUS # turn off interrupts 592 and t1, t0, ~(MIPS_SR_INT_IE) 593 mtc0 t1, MIPS_COP_0_STATUS 594#endif 595 COP0_SYNC 596 597 ld v0, 0(a0) 598#if _BYTE_ORDER == _BIG_ENDIAN 599 dsll v1, v0, 32 600 dsra v1, v1, 32 # low word in v1 601#else 602 dsra v1, v0, 32 # high word in v1 603 dsll v0, v0, 32 604#endif 605 dsra v0, v0, 32 # low word in v0 606 607 mtc0 t0, MIPS_COP_0_STATUS # restore intr status. 608 JR_HB_RA 609#else /* !__mips_o32 */ 610 jr ra 611 ld v0, 0(a0) 612#endif /* !__mips_o32 */ 613END(mips3_ld) 614 615LEAF(mips3_sd) 616#if defined(__mips_o32) 617#if (MIPS64R2) > 0 618 di t0 619#else 620 mfc0 t0, MIPS_COP_0_STATUS # turn off interrupts 621 and t1, t0, ~(MIPS_SR_INT_IE) 622 mtc0 t1, MIPS_COP_0_STATUS 623#endif 624 COP0_SYNC 625 626 dsll a2, a2, 32 # high word in a2 627#if _BYTE_ORDER == _BIG_ENDIAN 628 dsll a3, a3, 32 # low word in a3 629 dsrl a3, a3, 32 630#else 631 dsrl a2, a2, 32 632 dsll a3, a3, 32 # high word in a3 633#endif 634 or a1, a2, a3 635 sd a1, 0(a0) 636 637 mtc0 t0, MIPS_COP_0_STATUS # restore intr status. 638 JR_HB_RA 639#else /* !__mips_o32 */ 640 jr ra 641 sd a1, 0(a0) 642#endif /* !__mips_o32 */ 643END(mips3_sd) 644 645/* 646 * int badaddr64(uint64_t addr, int len) 647 * See if access to addr with a len type instruction causes a machine check. 648 * len is length of access in bytes (can be 1, 2, 4, or 8). 649 */ 650LEAF(badaddr64) 651 PTR_L v1, L_PCB(MIPS_CURLWP) 652 PTR_LA v0, _C_LABEL(baderr64) 653 654#ifdef __mips_o32 655 /* Enable KX */ 656 mfc0 t0, MIPS_COP_0_STATUS 657 or t1, t0, MIPS3_SR_KX 658 and t2, t0, MIPS_SR_INT_IE # disable interrupts 659 xor t1, t2 660 mtc0 t1, MIPS_COP_0_STATUS 661 COP0_SYNC 662 663#ifdef __MIPSEB__ 664 dsll a0, a0, 32 # MSW 665 dsll a1, a1, 32 # LSW 666 dsrl a1, a1, 32 667#else 668 dsll a1, a1, 32 # MSW 669 dsll a0, a0, 32 # LSW 670 dsrl a0, a0, 32 671#endif 672 or a0, a1 # combine 673 move a1, a2 # move up length argument 674#endif /* __mips_o32 */ 675 676 bne a1, 1, 2f 677 PTR_S v0, PCB_ONFAULT(v1) 678 b 9f 679 lbu v0, (a0) 6802: 681 bne a1, 2, 4f 682 nop 683 b 9f 684 lhu v0, (a0) 6854: 686 bne a1, 4, 8f 687 nop 688 b 9f 689 INT_L v0, (a0) 6908: 691 REG_L v0, (a0) 6929: 693 sync 694#ifdef __mips_o32 695 mtc0 t0, MIPS_COP_0_STATUS # Restore KX 696 COP0_SYNC 697#endif 698 PTR_S zero, PCB_ONFAULT(v1) 699 jr ra 700 move v0, zero # made it w/o errors 701END(badaddr64) 702 703LEAF(baderr64) 704#ifdef __mips_o32 705 mtc0 t0, MIPS_COP_0_STATUS # Restore KX 706 COP0_SYNC 707#endif 708 PTR_S zero, PCB_ONFAULT(v1) 709 jr ra 710 li v0, -1 711END(baderr64) 712 713/* 714 * uint64_t mips3_cp0_tlb_entry_hi_probe(void); 715 * 716 * Write 1s to the VPN and ASID fields of Entry_Hi0 to see how many VA bits 717 * and ASID bits are implemented. Assumes that interrupts are disabled. 718 */ 719LEAF(mips3_cp0_tlb_entry_hi_probe) 720 dmfc0 t0, MIPS_COP_0_TLB_HI 721 li v0, -1 /* all 1s */ 722#if defined(__mips_isa_rev) && __mips_isa_rev >= 2 723 dinsu v0, zero, 62, 2 724#else 725 dsll v0, v0, 2 /* except the top 2 */ 726 dsrl v0, v0, 2 727#endif 728 dmtc0 v0, MIPS_COP_0_TLB_HI 729 COP0_SYNC 730 dmfc0 v0, MIPS_COP_0_TLB_HI 731 dmtc0 t0, MIPS_COP_0_TLB_HI 732 COP0_SYNC 733 nop 734#ifdef __mips_o32 735 nop 736#if BYTE_ORDER == BIG_ENDIAN 737 srl v1, v0, 0 738 dsra v0, v0, 32 739#endif 740#if BYTE_ORDER == LITTLE_ENDIAN 741 dsra v1, v0, 32 742 srl v0, v0, 0 743#endif 744#endif /* __mips_o32 */ 745 jr ra 746 nop 747END(mips3_cp0_tlb_entry_hi_probe) 748#endif /* __mips != 32 */ 749 750/* 751 * uint64_t mips3_cp0_tlb_entry_lo_probe(void); 752 * 753 * Write 1s to the PFN field of Entry_Lo0 to see how many 754 * PA bits are implemented. Assumes that interrupts are disabled. 755 */ 756LEAF(mips3_cp0_tlb_entry_lo_probe) 757 dmfc0 t0, MIPS_COP_0_TLB_LO0 758 li v0, -64 /* all 1s except low 6 bits */ 759 dmtc0 v0, MIPS_COP_0_TLB_LO0 760 COP0_SYNC 761 dmfc0 v0, MIPS_COP_0_TLB_LO0 762 dmtc0 t0, MIPS_COP_0_TLB_LO0 763 COP0_SYNC 764#ifdef __mips_o32 765#if BYTE_ORDER == BIG_ENDIAN 766 srl v1, v0, 0 767 dsra v0, v0, 32 768#endif 769#if BYTE_ORDER == LITTLE_ENDIAN 770 dsra v1, v0, 32 771 srl v0, v0, 0 772#endif 773#endif /* __mips_o32 */ 774 jr ra 775 nop 776END(mips3_cp0_tlb_entry_lo_probe) 777 778/* 779 * uint32_t mips3_cp0_tlb_page_mask_probe(void); 780 * 781 * Write 1s to the RPN field of Entry_Lo0 to see how many PA bits are implemented. 782 * Assumes that interrupts are disabled. 783 */ 784LEAF(mips3_cp0_tlb_page_mask_probe) 785 mfc0 t0, MIPS_COP_0_TLB_PG_MASK 786 lui v0, 0xffff 787 srl v0, v0, 3 788 mtc0 v0, MIPS_COP_0_TLB_PG_MASK 789 COP0_SYNC 790 mfc0 v0, MIPS_COP_0_TLB_PG_MASK 791 mtc0 t0, MIPS_COP_0_TLB_PG_MASK 792 JR_HB_RA 793END(mips3_cp0_tlb_page_mask_probe) 794 795#ifdef MULTIPROCESSOR 796/* 797 * MD code calls/jumps to this with the pointer to this CPU's cpu_info in a1, 798 * sp set to ci->ci_data.cpu_idlelwp->l_md.md_utf. gp will be overridden so 799 * 0 can be supplied if needed. (This happens to match what CFE wants) 800 */ 801NESTED_NOPROFILE(cpu_trampoline, 0, ra) 802 /* 803 * We act as the idle lwp so make it CURLWP. When know 804 * that the cpu_info is a KSEG0 address. 805 */ 806 move a0, a1 807 // Loop until idlelwp is filled in. 8081: PTR_L MIPS_CURLWP, CPU_INFO_IDLELWP(a0) 809 nop 810 beqz MIPS_CURLWP, 1b 811 nop 812 /* 813 * No membar needed because we're not switching from a 814 * previous lwp, and the idle lwp we're switching to can't be 815 * holding locks already; see cpu_switchto. 816 */ 817 PTR_S MIPS_CURLWP, CPU_INFO_CURLWP(a0) 818 819#ifdef _LP64 820 li v0, MIPS_SR_KX | MIPS_SR_UX # allow 64bit addressing 821#elif defined(__mips_n32) 822 li v0, MIPS_SR_KX # allow 64bit kernel addressing 823#else 824 li v0, 0 825#endif 826 mtc0 v0, MIPS_COP_0_STATUS # reset to known state 827 COP0_SYNC 828 829 PTR_L sp, L_MD_UTF(MIPS_CURLWP) # fetch KSP 830 831 /* 832 * Indicate that no one has called us. 833 */ 834 move ra, zero 835 REG_S ra, CALLFRAME_RA(sp) 836 837#ifdef __GP_SUPPORT__ 838 /* 839 * New execution constant needs GP to be loaded. 840 */ 841 PTR_LA gp, _C_LABEL(_gp) 842#endif 843 844#if 0 845 LONG_L t0, CPU_INFO_FLAGS(a0) 846 or t0, t0, CPUF_PRESENT 847 LONG_S t0, CPU_INFO_FLAGS(a0) 848 sync 849#endif 850 851 /* 852 * and off we go. 853 */ 854 j _C_LABEL(cpu_hatch) # does everything 855 nop 856END(cpu_trampoline) 857#endif /* MULTIPROCESSOR */ 858