locore_mips3.S revision 1.110
1/* $NetBSD: locore_mips3.S,v 1.110 2015/06/16 18:12:18 macallan 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 95#include "assym.h" 96 97/* 98 * XXX We need a cleaner way of handling the instruction hazards of 99 * the various processors. Here are the relevant rules for the QED 52XX: 100 * tlbw[ri] -- two integer ops beforehand 101 * tlbr -- two integer ops beforehand 102 * tlbp -- two integer ops beforehand 103 * mtc0 [PageMask,EntryHi,Cp0] -- two integer ops afterwards 104 * changing JTLB -- two integer ops afterwards 105 * mtc0 [EPC,ErrorEPC,Status] -- two int ops afterwards before eret 106 * config.k0 -- five int ops before kseg0, ckseg0 memref 107 * 108 * For the IDT R4000, some hazards are: 109 * mtc0/mfc0 one integer op before and after 110 * tlbp -- one integer op afterwards 111 * Obvious solution is to take least common denominator. 112 */ 113 114/* 115 *============================================================================ 116 * 117 * MIPS III ISA support, part 1: locore exception vectors. 118 * The following code is copied to the vector locations to which 119 * the CPU jumps in response to an exception or a TLB miss. 120 * 121 *============================================================================ 122 */ 123 .set noreorder 124#if (__mips < 3) || __mips_o32 125 .set mips3 126#endif 127 128#ifdef _LP64 129#define _MFC0 dmfc0 130#define _MTC0 dmtc0 131#else 132#define _MFC0 mfc0 133#define _MTC0 mtc0 134#endif 135 136 .text 137 138/*---------------------------------------------------------------------------- 139 * 140 * mips3_wbflush -- 141 * 142 * Return when the write buffer is empty. 143 * 144 * Common for all MIPS3 and greater ISAs 145 * 146 * Results: 147 * None. 148 * 149 * Side effects: 150 * None. 151 * 152 *---------------------------------------------------------------------------- 153 */ 154LEAF(mips3_wbflush) 155XLEAF(loongson2_wbflush) 156XLEAF(mips32_wbflush) 157XLEAF(mips32r2_wbflush) 158XLEAF(mips64_wbflush) 159XLEAF(mips64r2_wbflush) 160 nop 161 sync 162 jr ra 163 nop 164END(mips3_wbflush) 165 166 167/* 168 * mips_wait_idle: 169 * 170 * When no processes are on the runq, cpu_idle branches to 171 * mips_wait_idle to save power. 172 */ 173LEAF(mips_wait_idle) 174 mfc0 v0, MIPS_COP_0_STATUS 175 andi v1, v0, MIPS_SR_INT_IE 176#if __mips >= 32 177 teqi v1, 0 178#else 179 beqz v1, 1f 180 nop 181#endif 182 andi v1, v0, MIPS_INT_MASK 183#if __mips >= 32 184 teqi v1, 0 185#else 186 bnez v1, 2f 187 nop 1881: 189 move a1, v0 190 PANIC("mips_wait_idle: interrupts disabled status=%#x") 191#endif 192 1932: wait 194 nop 195 nop 196 nop 197 mfc0 v0, MIPS_COP_0_STATUS 198 andi v1, v0, MIPS_SR_INT_IE 199#if __mips >= 32 200 teqi v1, 0 201#else 202 beqz v1, 1b 203 nop 204#endif 205 andi v1, v0, MIPS_INT_MASK 206#if __mips >= 32 207 teqi v1, 0 208#else 209 bnez v1, 2b 210 nop 211#endif 212 jr ra 213 nop 214END(mips_wait_idle) 215 216/* 217 * uint32_t mips3_cp0_compare_read(void) 218 * 219 * Return the current value of the CP0 Compare register. 220 */ 221LEAF(mips3_cp0_compare_read) 222 mfc0 v0, MIPS_COP_0_COMPARE 223 jr ra 224 nop 225END(mips3_cp0_compare_read) 226 227/* 228 * void mips3_cp0_compare_write(uint32_t) 229 * 230 * Set the value of the CP0 Compare register. 231 */ 232LEAF(mips3_cp0_compare_write) 233 mtc0 a0, MIPS_COP_0_COMPARE 234 JR_HB_RA 235END(mips3_cp0_compare_write) 236 237/* 238 * uint32_t mips3_cp0_config_read(void) 239 * 240 * Return the current value of the CP0 Config register. 241 */ 242LEAF(mips3_cp0_config_read) 243 mfc0 v0, MIPS_COP_0_CONFIG 244 jr ra 245 nop 246END(mips3_cp0_config_read) 247 248/* 249 * void mips3_cp0_config_write(uint32_t) 250 * 251 * Set the value of the CP0 Config register. 252 */ 253LEAF(mips3_cp0_config_write) 254 mtc0 a0, MIPS_COP_0_CONFIG 255 JR_HB_RA 256END(mips3_cp0_config_write) 257 258#if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 259 .set push 260#ifdef __mips_o32 261 .set mips32 262#else 263 .set mips64 264#endif 265/* 266 * uint32_t mipsNN_cp0_config1_read(void) 267 * 268 * Return the current value of the CP0 Config (Select 1) register. 269 */ 270LEAF(mipsNN_cp0_config1_read) 271 mfc0 v0, MIPS_COP_0_CONFIG, 1 272 jr ra 273 nop 274END(mipsNN_cp0_config1_read) 275 276/* 277 * uint32_t mipsNN_cp0_config1_write(uint32_t) 278 * 279 * Set the current value of the CP0 Config (Select 1) register. 280 */ 281LEAF(mipsNN_cp0_config1_write) 282 mtc0 v0, MIPS_COP_0_CONFIG, 1 283 JR_HB_RA 284END(mipsNN_cp0_config1_write) 285 286/* 287 * uint32_t mipsNN_cp0_config2_read(void) 288 * 289 * Return the current value of the CP0 Config (Select 2) register. 290 */ 291LEAF(mipsNN_cp0_config2_read) 292 mfc0 v0, MIPS_COP_0_CONFIG, 2 293 jr ra 294 nop 295END(mipsNN_cp0_config2_read) 296 297/* 298 * uint32_t mipsNN_cp0_config3_read(void) 299 * 300 * Return the current value of the CP0 Config (Select 3) register. 301 */ 302LEAF(mipsNN_cp0_config3_read) 303 mfc0 v0, MIPS_COP_0_CONFIG, 3 304 jr ra 305 nop 306END(mipsNN_cp0_config3_read) 307 308/* 309 * uintptr_t mipsNN_cp0_watchlo_read(u_int sel) 310 * 311 * Return the current value of the selected CP0 Watchlo register. 312 */ 313LEAF(mipsNN_cp0_watchlo_read) 314 sll a0, 2 315 PTR_LA t9, 1f 316 PTR_ADDU t9, a0 317 jr t9 318 nop 3191: 320 jr ra 321 _MFC0 v0, MIPS_COP_0_WATCH_LO, 0 322 jr ra 323 _MFC0 v0, MIPS_COP_0_WATCH_LO, 1 324 jr ra 325 _MFC0 v0, MIPS_COP_0_WATCH_LO, 2 326 jr ra 327 _MFC0 v0, MIPS_COP_0_WATCH_LO, 3 328 jr ra 329 _MFC0 v0, MIPS_COP_0_WATCH_LO, 4 330 jr ra 331 _MFC0 v0, MIPS_COP_0_WATCH_LO, 5 332 jr ra 333 _MFC0 v0, MIPS_COP_0_WATCH_LO, 6 334 jr ra 335 _MFC0 v0, MIPS_COP_0_WATCH_LO, 7 336END(mipsNN_cp0_watchlo_read) 337 338/* 339 * void mipsNN_cp0_watchlo_write(u_int sel, uintptr_t val) 340 * 341 * Set the current value of the selected CP0 WatchLo register. 342 */ 343LEAF(mipsNN_cp0_watchlo_write) 344 sll a0, 2 345 PTR_LA t9, 1f 346 PTR_ADDU t9, a0 347 jr t9 348 nop 3491: 350 jr ra 351 _MTC0 a1, MIPS_COP_0_WATCH_LO, 0 352 jr ra 353 _MTC0 a1, MIPS_COP_0_WATCH_LO, 1 354 jr ra 355 _MTC0 a1, MIPS_COP_0_WATCH_LO, 2 356 jr ra 357 _MTC0 a1, MIPS_COP_0_WATCH_LO, 3 358 jr ra 359 _MTC0 a1, MIPS_COP_0_WATCH_LO, 4 360 jr ra 361 _MTC0 a1, MIPS_COP_0_WATCH_LO, 5 362 jr ra 363 _MTC0 a1, MIPS_COP_0_WATCH_LO, 6 364 jr ra 365 _MTC0 a1, MIPS_COP_0_WATCH_LO, 7 366END(mipsNN_cp0_watchlo_write) 367 368/* 369 * uint32_t mipsNN_cp0_watchhi_read(u_int sel) 370 * 371 * Return the current value of the selected CP0 WatchHi register. 372 */ 373LEAF(mipsNN_cp0_watchhi_read) 374 sll a0, 2 375 PTR_LA t9, 1f 376 PTR_ADDU t9, a0 377 jr t9 378 nop 3791: 380 jr ra 381 mfc0 v0, MIPS_COP_0_WATCH_HI, 0 382 jr ra 383 mfc0 v0, MIPS_COP_0_WATCH_HI, 1 384 jr ra 385 mfc0 v0, MIPS_COP_0_WATCH_HI, 2 386 jr ra 387 mfc0 v0, MIPS_COP_0_WATCH_HI, 3 388 jr ra 389 mfc0 v0, MIPS_COP_0_WATCH_HI, 4 390 jr ra 391 mfc0 v0, MIPS_COP_0_WATCH_HI, 5 392 jr ra 393 mfc0 v0, MIPS_COP_0_WATCH_HI, 6 394 jr ra 395 mfc0 v0, MIPS_COP_0_WATCH_HI, 7 396END(mipsNN_cp0_watchhi_read) 397 398/* 399 * void mipsNN_cp0_watchhi_write(u_int sel, uint32_t val) 400 * 401 * Set the current value of the selected CP0 WatchHi register. 402 */ 403LEAF(mipsNN_cp0_watchhi_write) 404 sll a0, 2 405 PTR_LA t9, 1f 406 PTR_ADDU t9, a0 407 jr t9 408 nop 4091: 410 jr ra 411 mtc0 a1, MIPS_COP_0_WATCH_HI, 0 412 jr ra 413 mtc0 a1, MIPS_COP_0_WATCH_HI, 1 414 jr ra 415 mtc0 a1, MIPS_COP_0_WATCH_HI, 2 416 jr ra 417 mtc0 a1, MIPS_COP_0_WATCH_HI, 3 418 jr ra 419 mtc0 a1, MIPS_COP_0_WATCH_HI, 4 420 jr ra 421 mtc0 a1, MIPS_COP_0_WATCH_HI, 5 422 jr ra 423 mtc0 a1, MIPS_COP_0_WATCH_HI, 6 424 jr ra 425 mtc0 a1, MIPS_COP_0_WATCH_HI, 7 426END(mipsNN_cp0_watchhi_write) 427 428/* 429 * void mipsNN_cp0_ebase_read(void *); 430 * Get the value of the CP0 EBASE (PRID, select 1) register. 431 */ 432LEAF(mipsNN_cp0_ebase_read) 433 jr ra 434 mfc0 v0, MIPS_COP_0_EBASE 435END(mipsNN_cp0_ebase_read) 436 437/* 438 * void mipsNN_cp0_ebase_write(void *); 439 * Set the value of the CP0 EBASE (PRID, select 1) register. 440 */ 441LEAF(mipsNN_cp0_ebase_write) 442 and v0, v0, 0x1ff 443 xor v0, v0, a0 444 jr ra 445 mtc0 v0, MIPS_COP_0_EBASE 446END(mipsNN_cp0_ebase_write) 447 448#if (MIPS32R2 + MIPS64R2) > 0 449/* 450 * void mipsNN_cp0_hwrena_write(void *); 451 * Set the value of the CP0 HWRENA register. 452 */ 453LEAF(mipsNN_cp0_hwrena_write) 454 jr ra 455 mtc0 a0, MIPS_COP_0_HWRENA 456END(mipsNN_cp0_hwrena_write) 457 458/* 459 * void mipsNN_cp0_userlocal_write(void *); 460 * Set the value of the CP0 USERLOCAL (TLB_CONTEXT, select 2) register. 461 */ 462LEAF(mipsNN_cp0_userlocal_write) 463 jr ra 464 _MTC0 a0, MIPS_COP_0_USERLOCAL 465END(mipsNN_cp0_userlocal_write) 466#endif /* (MIPS32R2 + MIPS64R2) > 0 */ 467 .set pop 468#endif /* (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 */ 469 470/* 471 * uint32_t mips3_cp0_count_read(void) 472 * 473 * Return the current value of the CP0 Count register. 474 */ 475LEAF(mips3_cp0_count_read) 476 mfc0 v0, MIPS_COP_0_COUNT 477 jr ra 478 nop 479END(mips3_cp0_count_read) 480WEAK_ALIAS(cpu_counter32, mips3_cp0_count_read) 481 482/* 483 * void mips3_cp0_count_write(uint32_t) 484 * 485 * Set the value of the CP0 Count register. 486 */ 487LEAF(mips3_cp0_count_write) 488 mtc0 a0, MIPS_COP_0_COUNT 489 JR_HB_RA 490END(mips3_cp0_count_write) 491 492/* 493 * uint32_t mips3_cp0_wired_read(void) 494 * 495 * Return the current value of the CP0 Wired register. 496 */ 497LEAF(mips3_cp0_wired_read) 498 mfc0 v0, MIPS_COP_0_TLB_WIRED 499 jr ra 500 nop 501END(mips3_cp0_wired_read) 502 503/* 504 * void mips3_cp0_wired_write(uint32_t) 505 * 506 * Set the value of the CP0 Wired register. 507 */ 508LEAF(mips3_cp0_wired_write) 509 mtc0 a0, MIPS_COP_0_TLB_WIRED 510 JR_HB_RA 511END(mips3_cp0_wired_write) 512 513/* 514 * void mips3_cp0_pg_mask_write(uint32_t) 515 * 516 * Set the value of the CP0 PG_MASK register. 517 */ 518LEAF(mips3_cp0_pg_mask_write) 519 mtc0 a0, MIPS_COP_0_TLB_PG_MASK 520 JR_HB_RA 521END(mips3_cp0_pg_mask_write) 522 523#if __mips != 32 524LEAF(mips3_ld) 525#if defined(__mips_o32) 526 mfc0 t0, MIPS_COP_0_STATUS # turn off interrupts 527 and t1, t0, ~(MIPS_SR_INT_IE) 528 mtc0 t1, MIPS_COP_0_STATUS 529 COP0_SYNC 530 531 ld v0, 0(a0) 532#if defined(_MIPS_BSD_API) && \ 533 (_MIPS_BSD_API == _MIPS_BSD_API_N32 || _MIPS_BSD_API == _MIPS_BSD_API_LP64) 534 # nothing to do 535#else 536#if _BYTE_ORDER == _BIG_ENDIAN 537 dsll v1, v0, 32 538 dsra v1, v1, 32 # low word in v1 539 dsra v0, v0, 32 # high word in v0 540#else 541 dsra v1, v0, 32 # high word in v1 542 dsll v0, v0, 32 543 dsra v0, v0, 32 # low word in v0 544#endif 545#endif 546 547 mtc0 t0, MIPS_COP_0_STATUS # restore intr status. 548 JR_HB_RA 549#else /* !__mips_o32 */ 550 ld v0, 0(a0) 551 jr ra 552 nop 553#endif /* !__mips_o32 */ 554END(mips3_ld) 555 556LEAF(mips3_sd) 557#if defined(__mips_o32) 558 mfc0 t0, MIPS_COP_0_STATUS # turn off interrupts 559 and t1, t0, ~(MIPS_SR_INT_IE) 560 mtc0 t1, MIPS_COP_0_STATUS 561 COP0_SYNC 562 563#if defined(_MIPS_BSD_API) && \ 564 (_MIPS_BSD_API == _MIPS_BSD_API_N32 || _MIPS_BSD_API == _MIPS_BSD_API_LP64) 565 # nothing to do 566#else 567 # NOTE: a1 is padding! 568 569#if _BYTE_ORDER == _BIG_ENDIAN 570 dsll a2, a2, 32 # high word in a2 571 dsll a3, a3, 32 # low word in a3 572 dsrl a3, a3, 32 573#else 574 dsll a2, a2, 32 # low word in a2 575 dsrl a2, a2, 32 576 dsll a3, a3, 32 # high word in a3 577#endif 578 or a1, a2, a3 579#endif 580 sd a1, 0(a0) 581 582 mtc0 t0, MIPS_COP_0_STATUS # restore intr status. 583 JR_HB_RA 584#else /* !__mips_o32 */ 585 sd a1, 0(a0) 586 jr ra 587 nop 588#endif /* !__mips_o32 */ 589 590END(mips3_sd) 591 592/* 593 * int badaddr64(uint64_t addr, int len) 594 * See if access to addr with a len type instruction causes a machine check. 595 * len is length of access in bytes (can be 1, 2, 4, or 8). 596 */ 597LEAF(badaddr64) 598 PTR_L v1, L_PCB(MIPS_CURLWP) 599 PTR_LA v0, _C_LABEL(baderr64) 600 601 /* Enable KX */ 602 mfc0 t0, MIPS_COP_0_STATUS 603 or t1, t0, MIPS3_SR_KX 604#ifdef __mips_o32 605 and t2, t0, MIPS_SR_INT_IE # disable interrupts 606 xor t1, t2 607#endif 608 mtc0 t1, MIPS_COP_0_STATUS 609 COP0_SYNC 610 611#ifdef __mips_o32 612#ifdef __MIPSEB__ 613 dsll a0, a0, 32 # MSW 614 dsll a1, a1, 32 # LSW 615 dsrl a1, a1, 32 616#else 617 dsll a1, a1, 32 # MSW 618 dsll a0, a0, 32 # LSW 619 dsrl a0, a0, 32 620#endif 621 or a0, a1 # combine 622 move a1, a2 # move up length argument 623#endif /* __mips_o32 */ 624 625 bne a1, 1, 2f 626 PTR_S v0, PCB_ONFAULT(v1) 627 b 9f 628 lbu v0, (a0) 6292: 630 bne a1, 2, 4f 631 nop 632 b 9f 633 lhu v0, (a0) 6344: 635 bne a1, 4, 8f 636 nop 637 b 9f 638 INT_L v0, (a0) 6398: 640 REG_L v0, (a0) 6419: 642 sync 643 mtc0 t0, MIPS_COP_0_STATUS # Restore KX 644 COP0_SYNC 645 PTR_S zero, PCB_ONFAULT(v1) 646 jr ra 647 move v0, zero # made it w/o errors 648END(badaddr64) 649 650LEAF(baderr64) 651 mtc0 t0, MIPS_COP_0_STATUS # Restore KX 652 COP0_SYNC 653 PTR_S zero, PCB_ONFAULT(v1) 654 jr ra 655 li v0, -1 656END(baderr64) 657 658/* 659 * uint64_t mips3_cp0_tlb_entry_hi_probe(void); 660 * 661 * Write 1s to the VPN and ASID fields of Entry_Hi0 to see how many VA bits 662 * and ASID bits are implemented. Assumes that interrupts are disabled. 663 */ 664LEAF(mips3_cp0_tlb_entry_hi_probe) 665 dmfc0 t0, MIPS_COP_0_TLB_HI 666 li v0, -1 /* all 1s */ 667#if defined(__mips_isa_rev) && __mips_isa_rev >= 2 668 dinsu v0, zero, 62, 2 669#else 670 dsll v0, v0, 2 /* except the top 2 */ 671 dsrl v0, v0, 2 672#endif 673 dmtc0 v0, MIPS_COP_0_TLB_HI 674 COP0_SYNC 675 dmfc0 v0, MIPS_COP_0_TLB_HI 676 dmtc0 t0, MIPS_COP_0_TLB_HI 677 COP0_SYNC 678 nop 679#ifdef __mips_o32 680 nop 681#if BYTE_ORDER == BIG_ENDIAN 682 srl v1, v0, 0 683 dsra v0, v0, 32 684#endif 685#if BYTE_ORDER == LITTLE_ENDIAN 686 dsra v1, v0, 32 687 srl v0, v0, 0 688#endif 689#endif /* __mips_o32 */ 690 jr ra 691 nop 692END(mips3_cp0_tlb_entry_hi_probe) 693 694/* 695 * uint64_t mips3_cp0_tlb_entry_lo_probe(void); 696 * 697 * Write 1s to the PFN field of Entry_Lo0 to see how many 698 * PA bits are implemented. Assumes that interrupts are disabled. 699 */ 700LEAF(mips3_cp0_tlb_entry_lo_probe) 701 dmfc0 t0, MIPS_COP_0_TLB_LO0 702 li v0, -64 /* all 1s except low 6 bits */ 703 dmtc0 v0, MIPS_COP_0_TLB_LO0 704 COP0_SYNC 705 dmfc0 v0, MIPS_COP_0_TLB_LO0 706 dmtc0 t0, MIPS_COP_0_TLB_LO0 707 COP0_SYNC 708#ifdef __mips_o32 709#if BYTE_ORDER == BIG_ENDIAN 710 srl v1, v0, 0 711 dsra v0, v0, 32 712#endif 713#if BYTE_ORDER == LITTLE_ENDIAN 714 dsra v1, v0, 32 715 srl v0, v0, 0 716#endif 717#endif /* __mips_o32 */ 718 jr ra 719 nop 720END(mips3_cp0_tlb_entry_lo_probe) 721#endif /* __mips != 32 */ 722 723/* 724 * uint32_t mips3_cp0_tlb_page_mask_probe(void); 725 * 726 * Write 1s to the RPN field of Entry_Lo0 to see how many PA bits are implemented. 727 * Assumes that interrupts are disabled. 728 */ 729LEAF(mips3_cp0_tlb_page_mask_probe) 730 mfc0 t0, MIPS_COP_0_TLB_PG_MASK 731 lui v0, 0xffff 732 srl v0, v0, 3 733 mtc0 v0, MIPS_COP_0_TLB_PG_MASK 734 COP0_SYNC 735 mfc0 v0, MIPS_COP_0_TLB_PG_MASK 736 mtc0 t0, MIPS_COP_0_TLB_PG_MASK 737 JR_HB_RA 738END(mips3_cp0_tlb_page_mask_probe) 739 740#ifdef MULTIPROCESSOR 741/* 742 * The presence of this routine here will causes MIPS1 MULTIPROCESSOR kernels 743 * to fail, as they should since we won't support such abominations. 744 * 745 * MD code calls/jumps to this with the pointer to this CPU's cpu_info in a1, 746 * sp set to ci->ci_data.cpu_idlelwp->l_md.md_utf. gp will be overridden so 747 * 0 can be supplied if needed. (This happens to match what CFE wants) 748 */ 749NESTED_NOPROFILE(cpu_trampoline, 0, ra) 750 /* 751 * We act as the idle lwp so make it CURLWP. When know 752 * that the cpu_info is a KSEG0 address. 753 */ 754 move a0, a1 755 // Loop until idlelwp is filled in. 7561: PTR_L MIPS_CURLWP, CPU_INFO_IDLELWP(a0) 757 nop 758 beqz MIPS_CURLWP, 1b 759 nop 760 PTR_S MIPS_CURLWP, CPU_INFO_CURLWP(a0) 761 762#ifdef _LP64 763 li v0, MIPS_SR_KX | MIPS_SR_UX # allow 64bit addressing 764#else 765 li v0, 0 766#endif 767 mtc0 v0, MIPS_COP_0_STATUS # reset to known state 768 COP0_SYNC 769 770 PTR_L sp, L_MD_UTF(MIPS_CURLWP) # fetch KSP 771 772 /* 773 * Indicate that no one has called us. 774 */ 775 move ra, zero 776 REG_S ra, CALLFRAME_RA(sp) 777 778#ifdef __GP_SUPPORT__ 779 /* 780 * New execution constant needs GP to be loaded. 781 */ 782 PTR_LA gp, _C_LABEL(_gp) 783#endif 784 785#if 0 786 LONG_L t0, CPU_INFO_FLAGS(a0) 787 or t0, t0, CPUF_PRESENT 788 LONG_S t0, CPU_INFO_FLAGS(a0) 789 sync 790#endif 791 792 /* 793 * and off we go. 794 */ 795 j _C_LABEL(cpu_hatch) # does everything 796 nop 797END(cpu_trampoline) 798#endif /* MULTIPROCESSOR */ 799