locore.S (b8160b5af4c6bf9c4cbc65653fdeaea37c927253) | locore.S (b57e802a8521cd90a2f8e3f2612ac107ac9a3591) |
---|---|
1/* $FreeBSD$ */ 2/* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */ 3 4/* 5 * Copyright (C) 2001 Benno Rice 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 51 unchanged lines hidden (view full) --- 60#include "opt_ipkdb.h" 61#include "assym.s" 62 63#include <sys/syscall.h> 64 65#include <machine/trap.h> 66#include <machine/param.h> 67#include <machine/sr.h> | 1/* $FreeBSD$ */ 2/* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */ 3 4/* 5 * Copyright (C) 2001 Benno Rice 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 51 unchanged lines hidden (view full) --- 60#include "opt_ipkdb.h" 61#include "assym.s" 62 63#include <sys/syscall.h> 64 65#include <machine/trap.h> 66#include <machine/param.h> 67#include <machine/sr.h> |
68#include <machine/spr.h> |
|
68#include <machine/psl.h> 69#include <machine/asm.h> 70 71/* 72 * Some instructions gas doesn't understand (yet?) 73 */ 74#define bdneq bdnzf 2, 75 --- 41 unchanged lines hidden (view full) --- 117GLOBAL(eintrcnt) 118 119GLOBAL(ofmsr) 120 .long 0 /* msr used in Open Firmware */ 121 122GLOBAL(powersave) 123 .long 0 124 | 69#include <machine/psl.h> 70#include <machine/asm.h> 71 72/* 73 * Some instructions gas doesn't understand (yet?) 74 */ 75#define bdneq bdnzf 2, 76 --- 41 unchanged lines hidden (view full) --- 118GLOBAL(eintrcnt) 119 120GLOBAL(ofmsr) 121 .long 0 /* msr used in Open Firmware */ 122 123GLOBAL(powersave) 124 .long 0 125 |
126#define INTSTK 8192 /* 8K interrupt stack */ 127#define SPILLSTK 4096 /* 4K spill stack */ 128 |
|
125/* 126 * File-scope for locore.S 127 */ 128idle_u: 129 .long 0 /* fake uarea during idle after exit */ 130openfirmware_entry: 131 .long 0 /* openfirmware entry point */ 132srsave: --- 253 unchanged lines hidden (view full) --- 386 mtmsr 0 387 388 lwz 1,0(1) /* return */ 389 lwz 0,4(1) 390 mtlr 0 391 blr 392 393/* | 129/* 130 * File-scope for locore.S 131 */ 132idle_u: 133 .long 0 /* fake uarea during idle after exit */ 134openfirmware_entry: 135 .long 0 /* openfirmware entry point */ 136srsave: --- 253 unchanged lines hidden (view full) --- 390 mtmsr 0 391 392 lwz 1,0(1) /* return */ 393 lwz 0,4(1) 394 mtlr 0 395 blr 396 397/* |
394 * Data used during primary/secondary traps/interrupts 395 */ 396#define tempsave 0x2e0 /* primary save area for trap handling */ 397#define disisave 0x3e0 /* primary save area for dsi/isi traps */ 398 399#define INTSTK (8*1024) /* 8K interrupt stack */ 400 .data 401 .align 4 402intstk: 403 .space INTSTK /* interrupt stack */ 404 405GLOBAL(intr_depth) 406 .long -1 /* in-use marker */ 407 408#define SPILLSTK 1024 /* 1K spill stack */ 409 410 .comm spillstk,SPILLSTK,8 411 412/* 413 * This code gets copied to all the trap vectors 414 * (except ISI/DSI, ALI, the interrupts, and possibly the debugging 415 * traps when using IPKDB). 416 */ 417 .text 418 .globl trapcode,trapsize 419trapcode: 420 mtsprg 1,1 /* save SP */ 421 stmw 28,tempsave(0) /* free r28-r31 */ 422 mflr 28 /* save LR */ 423 mfcr 29 /* save CR */ 424/* Test whether we already had PR set */ 425 mfsrr1 31 426 mtcr 31 427 bc 4,17,1f /* branch if PSL_PR is clear */ 428 mfsprg 1,0 429 lwz 1,PC_CURPCB(1) 430 addi 1,1,USPACE /* stack is top of user struct */ 4311: 432 bla s_trap 433trapsize = .-trapcode 434 435/* 436 * For ALI: has to save DSISR and DAR 437 */ 438 .globl alitrap,alisize 439alitrap: 440 mtsprg 1,1 /* save SP */ 441 stmw 28,tempsave(0) /* free r28-r31 */ 442 mfdar 30 443 mfdsisr 31 444 stmw 30,tempsave+16(0) 445 mflr 28 /* save LR */ 446 mfcr 29 /* save CR */ 447/* Test whether we already had PR set */ 448 mfsrr1 31 449 mtcr 31 450 bc 4,17,1f /* branch if PSL_PR is clear */ 451 mfsprg 1,0 452 lwz 1,PC_CURPCB(1) 453 addi 1,1,USPACE /* stack is top of user struct */ 4541: 455 bla s_trap 456alisize = .-alitrap 457 458/* 459 * Similar to the above for DSI 460 * Has to handle BAT spills 461 * and standard pagetable spills 462 */ 463 .globl dsitrap,dsisize 464dsitrap: 465 stmw 28,disisave(0) /* free r28-r31 */ 466 mfcr 29 /* save CR */ 467 mfxer 30 /* save XER */ 468 mtsprg 2,30 /* in SPRG2 */ 469 mfsrr1 31 /* test kernel mode */ 470 mtcr 31 471 bc 12,17,1f /* branch if PSL_PR is set */ 472 mfdar 31 /* get fault address */ 473 rlwinm 31,31,7,25,28 /* get segment * 8 */ 474 475 /* get batu */ 476 addis 31,31,battable@ha 477 lwz 30,battable@l(31) 478 mtcr 30 479 bc 4,30,1f /* branch if supervisor valid is 480 false */ 481 /* get batl */ 482 lwz 31,battable+4@l(31) 483/* We randomly use the highest two bat registers here */ 484 mftb 28 485 andi. 28,28,1 486 bne 2f 487 mtdbatu 2,30 488 mtdbatl 2,31 489 b 3f 4902: 491 mtdbatu 3,30 492 mtdbatl 3,31 4933: 494 mfsprg 30,2 /* restore XER */ 495 mtxer 30 496 mtcr 29 /* restore CR */ 497 lmw 28,disisave(0) /* restore r28-r31 */ 498 rfi /* return to trapped code */ 4991: 500 mflr 28 /* save LR */ 501 bla s_dsitrap 502dsisize = .-dsitrap 503 504/* 505 * Similar to the above for ISI 506 */ 507 .globl isitrap,isisize 508isitrap: 509 stmw 28,disisave(0) /* free r28-r31 */ 510 mflr 28 /* save LR */ 511 mfcr 29 /* save CR */ 512 mfsrr1 31 /* test kernel mode */ 513 mtcr 31 514 bc 12,17,1f /* branch if PSL_PR is set */ 515 mfsrr0 31 /* get fault address */ 516 rlwinm 31,31,7,25,28 /* get segment * 8 */ 517 518 /* get batu */ 519 addis 31,31,battable@ha 520 lwz 30,battable@l(31) 521 mtcr 30 522 bc 4,30,1f /* branch if supervisor valid is 523 false */ 524 mtibatu 3,30 525 526 /* get batl */ 527 lwz 30,battable+4@l(31) 528 mtibatl 3,30 529 530 mtcr 29 /* restore CR */ 531 lmw 28,disisave(0) /* restore r28-r31 */ 532 rfi /* return to trapped code */ 5331: 534 bla s_isitrap 535isisize = .-isitrap 536 537/* 538 * This one for the external interrupt handler. 539 */ 540 .globl extint,extsize 541extint: 542 mtsprg 1,1 /* save SP */ 543 stmw 28,tempsave(0) /* free r28-r31 */ 544 mflr 28 /* save LR */ 545 mfcr 29 /* save CR */ 546 mfxer 30 /* save XER */ 547 lis 1,intstk+INTSTK@ha /* get interrupt stack */ 548 addi 1,1,intstk+INTSTK@l 549 lwz 31,0(1) /* were we already running on intstk? */ 550 addic. 31,31,1 551 stw 31,0(1) 552 beq 1f 553 mfsprg 1,1 /* yes, get old SP */ 5541: 555 ba extintr 556extsize = .-extint 557 558/* 559 * And this one for the decrementer interrupt handler. 560 */ 561 .globl decrint,decrsize 562decrint: 563 mtsprg 1,1 /* save SP */ 564 stmw 28,tempsave(0) /* free r28-r31 */ 565 lis 28,decrnest@ha 566 lwz 29,decrnest@l(28) 567 cmplwi 0,29,0 568 bne 2f 569 li 29,1 570 stw 29,decrnest@l(28) 571 mflr 28 /* save LR */ 572 mfcr 29 /* save CR */ 573 mfxer 30 /* save XER */ 574 lis 1,intstk+INTSTK@ha /* get interrupt stack */ 575 addi 1,1,intstk+INTSTK@l 576 lwz 31,0(1) /* were we already running on intstk? */ 577 addic. 31,31,1 578 stw 31,0(1) 579 beq 1f 580 mfsprg 1,1 /* yes, get old SP */ 5811: 582 ba decrintr 5832: 584 lmw 28,tempsave(0) 585 rfi 586decrsize = .-decrint 587 588/* 589 * Now the tlb software load for 603 processors: 590 * (Code essentially from the 603e User Manual, Chapter 5, but 591 * corrected a lot.) 592 */ 593#define DMISS 976 594#define DCMP 977 595#define HASH1 978 596#define HASH2 979 597#define IMISS 980 598#define ICMP 981 599#define RPA 982 600 601 .globl tlbimiss,tlbimsize 602tlbimiss: 603 mfspr 2,HASH1 /* get first pointer */ 604 li 1,8 605 mfctr 0 /* save counter */ 606 mfspr 3,ICMP /* get first compare value */ 607 addi 2,2,-8 /* predec pointer */ 6081: 609 mtctr 1 /* load counter */ 6102: 611 lwzu 1,8(2) /* get next pte */ 612 cmpl 0,1,3 /* see if found pte */ 613 bdneq 2b /* loop if not eq */ 614 bne 3f /* not found */ 615 lwz 1,4(2) /* load tlb entry lower word */ 616 andi. 3,1,8 /* check G-bit */ 617 bne 4f /* if guarded, take ISI */ 618 mtctr 0 /* restore counter */ 619 mfspr 0,IMISS /* get the miss address for the tlbli */ 620 mfsrr1 3 /* get the saved cr0 bits */ 621 mtcrf 0x80,3 /* and restore */ 622 ori 1,1,0x100 /* set the reference bit */ 623 mtspr RPA,1 /* set the pte */ 624 srwi 1,1,8 /* get byte 7 of pte */ 625 tlbli 0 /* load the itlb */ 626 stb 1,6(2) /* update page table */ 627 rfi 628 6293: /* not found in pteg */ 630 andi. 1,3,0x40 /* have we already done second hash? */ 631 bne 5f 632 mfspr 2,HASH2 /* get the second pointer */ 633 ori 3,3,0x40 /* change the compare value */ 634 li 1,8 635 addi 2,2,-8 /* predec pointer */ 636 b 1b 6374: /* guarded */ 638 mfsrr1 3 639 andi. 2,3,0xffff /* clean upper srr1 */ 640 oris 2,2,0x8000000@h /* set srr<4> to flag prot violation */ 641 b 6f 6425: /* not found anywhere */ 643 mfsrr1 3 644 andi. 2,3,0xffff /* clean upper srr1 */ 645 oris 2,2,0x40000000@h /* set srr1<1> to flag pte not found */ 6466: 647 mtctr 0 /* restore counter */ 648 mtsrr1 2 649 mfmsr 0 650 xoris 0,0,0x20000@h /* flip the msr<tgpr> bit */ 651 mtcrf 0x80,3 /* restore cr0 */ 652 mtmsr 0 /* now with native gprs */ 653 isync 654 ba EXC_ISI 655tlbimsize = .-tlbimiss 656 657 .globl tlbdlmiss,tlbdlmsize 658tlbdlmiss: 659 mfspr 2,HASH1 /* get first pointer */ 660 li 1,8 661 mfctr 0 /* save counter */ 662 mfspr 3,DCMP /* get first compare value */ 663 addi 2,2,-8 /* predec pointer */ 6641: 665 mtctr 1 /* load counter */ 6662: 667 lwzu 1,8(2) /* get next pte */ 668 cmpl 0,1,3 /* see if found pte */ 669 bdneq 2b /* loop if not eq */ 670 bne 3f /* not found */ 671 lwz 1,4(2) /* load tlb entry lower word */ 672 mtctr 0 /* restore counter */ 673 mfspr 0,DMISS /* get the miss address for the tlbld */ 674 mfsrr1 3 /* get the saved cr0 bits */ 675 mtcrf 0x80,3 /* and restore */ 676 ori 1,1,0x100 /* set the reference bit */ 677 mtspr RPA,1 /* set the pte */ 678 srwi 1,1,8 /* get byte 7 of pte */ 679 tlbld 0 /* load the dtlb */ 680 stb 1,6(2) /* update page table */ 681 rfi 682 6833: /* not found in pteg */ 684 andi. 1,3,0x40 /* have we already done second hash? */ 685 bne 5f 686 mfspr 2,HASH2 /* get the second pointer */ 687 ori 3,3,0x40 /* change the compare value */ 688 li 1,8 689 addi 2,2,-8 /* predec pointer */ 690 b 1b 6915: /* not found anywhere */ 692 mfsrr1 3 693 lis 1,0x40000000@h /* set dsisr<1> to flag pte not found */ 694 mtctr 0 /* restore counter */ 695 andi. 2,3,0xffff /* clean upper srr1 */ 696 mtsrr1 2 697 mtdsisr 1 /* load the dsisr */ 698 mfspr 1,DMISS /* get the miss address */ 699 mtdar 1 /* put in dar */ 700 mfmsr 0 701 xoris 0,0,0x20000@h /* flip the msr<tgpr> bit */ 702 mtcrf 0x80,3 /* restore cr0 */ 703 mtmsr 0 /* now with native gprs */ 704 isync 705 ba EXC_DSI 706tlbdlmsize = .-tlbdlmiss 707 708 .globl tlbdsmiss,tlbdsmsize 709tlbdsmiss: 710 mfspr 2,HASH1 /* get first pointer */ 711 li 1,8 712 mfctr 0 /* save counter */ 713 mfspr 3,DCMP /* get first compare value */ 714 addi 2,2,-8 /* predec pointer */ 7151: 716 mtctr 1 /* load counter */ 7172: 718 lwzu 1,8(2) /* get next pte */ 719 cmpl 0,1,3 /* see if found pte */ 720 bdneq 2b /* loop if not eq */ 721 bne 3f /* not found */ 722 lwz 1,4(2) /* load tlb entry lower word */ 723 andi. 3,1,0x80 /* check the C-bit */ 724 beq 4f 7255: 726 mtctr 0 /* restore counter */ 727 mfspr 0,DMISS /* get the miss address for the tlbld */ 728 mfsrr1 3 /* get the saved cr0 bits */ 729 mtcrf 0x80,3 /* and restore */ 730 mtspr RPA,1 /* set the pte */ 731 tlbld 0 /* load the dtlb */ 732 rfi 733 7343: /* not found in pteg */ 735 andi. 1,3,0x40 /* have we already done second hash? */ 736 bne 5f 737 mfspr 2,HASH2 /* get the second pointer */ 738 ori 3,3,0x40 /* change the compare value */ 739 li 1,8 740 addi 2,2,-8 /* predec pointer */ 741 b 1b 7424: /* found, but C-bit = 0 */ 743 rlwinm. 3,1,30,0,1 /* test PP */ 744 bge- 7f 745 andi. 3,1,1 746 beq+ 8f 7479: /* found, but protection violation (PP==00)*/ 748 mfsrr1 3 749 lis 1,0xa000000@h /* indicate protection violation 750 on store */ 751 b 1f 7527: /* found, PP=1x */ 753 mfspr 3,DMISS /* get the miss address */ 754 mfsrin 1,3 /* get the segment register */ 755 mfsrr1 3 756 rlwinm 3,3,18,31,31 /* get PR-bit */ 757 rlwnm. 2,2,3,1,1 /* get the key */ 758 bne- 9b /* protection violation */ 7598: /* found, set reference/change bits */ 760 lwz 1,4(2) /* reload tlb entry */ 761 ori 1,1,0x180 762 sth 1,6(2) 763 b 5b 7645: /* not found anywhere */ 765 mfsrr1 3 766 lis 1,0x42000000@h /* set dsisr<1> to flag pte not found */ 767 /* dsisr<6> to flag store */ 7681: 769 mtctr 0 /* restore counter */ 770 andi. 2,3,0xffff /* clean upper srr1 */ 771 mtsrr1 2 772 mtdsisr 1 /* load the dsisr */ 773 mfspr 1,DMISS /* get the miss address */ 774 mtdar 1 /* put in dar */ 775 mfmsr 0 776 xoris 0,0,0x20000@h /* flip the msr<tgpr> bit */ 777 mtcrf 0x80,3 /* restore cr0 */ 778 mtmsr 0 /* now with native gprs */ 779 isync 780 ba EXC_DSI 781tlbdsmsize = .-tlbdsmiss 782 783#ifdef DDB 784#define ddbsave 0xde0 /* primary save area for DDB */ 785/* 786 * In case of DDB we want a separate trap catcher for it 787 */ 788 .local ddbstk 789 .comm ddbstk,INTSTK,8 /* ddb stack */ 790 791 .globl ddblow,ddbsize 792ddblow: 793 mtsprg 1,1 /* save SP */ 794 stmw 28,ddbsave(0) /* free r28-r31 */ 795 mflr 28 /* save LR */ 796 mfcr 29 /* save CR */ 797 lis 1,ddbstk+INTSTK@ha /* get new SP */ 798 addi 1,1,ddbstk+INTSTK@l 799 bla ddbtrap 800ddbsize = .-ddblow 801#endif /* DDB */ 802 803#ifdef IPKDB 804#define ipkdbsave 0xde0 /* primary save area for IPKDB */ 805/* 806 * In case of IPKDB we want a separate trap catcher for it 807 */ 808 809 .local ipkdbstk 810 .comm ipkdbstk,INTSTK,8 /* ipkdb stack */ 811 812 .globl ipkdblow,ipkdbsize 813ipkdblow: 814 mtsprg 1,1 /* save SP */ 815 stmw 28,ipkdbsave(0) /* free r28-r31 */ 816 mflr 28 /* save LR */ 817 mfcr 29 /* save CR */ 818 lis 1,ipkdbstk+INTSTK@ha /* get new SP */ 819 addi 1,1,ipkdbstk+INTSTK@l 820 bla ipkdbtrap 821ipkdbsize = .-ipkdblow 822#endif /* IPKDB */ 823 824/* 825 * FRAME_SETUP assumes: 826 * SPRG1 SP (1) 827 * savearea r28-r31,DAR,DSISR (DAR & DSISR only for DSI traps) 828 * 28 LR 829 * 29 CR 830 * 1 kernel stack 831 * LR trap type 832 * SRR0/1 as at start of trap 833 */ 834#define FRAME_SETUP(savearea) \ 835/* Have to enable translation to allow access of kernel stack: */ \ 836 mfsrr0 30; \ 837 mfsrr1 31; \ 838 stmw 30,savearea+24(0); \ 839 mfmsr 30; \ 840 ori 30,30,(PSL_DR|PSL_IR); \ 841 mtmsr 30; \ 842 isync; \ 843 mfsprg 31,1; \ 844 stwu 31,-FRAMELEN(1); \ 845 stw 0,FRAME_0+8(1); \ 846 stw 31,FRAME_1+8(1); \ 847 stw 28,FRAME_LR+8(1); \ 848 stw 29,FRAME_CR+8(1); \ 849 lmw 28,savearea(0); \ 850 stmw 2,FRAME_2+8(1); \ 851 lmw 28,savearea+16(0); \ 852 mfxer 3; \ 853 mfctr 4; \ 854 mflr 5; \ 855 andi. 5,5,0xff00; \ 856 stw 3,FRAME_XER+8(1); \ 857 stw 4,FRAME_CTR+8(1); \ 858 stw 5,FRAME_EXC+8(1); \ 859 stw 28,FRAME_DAR+8(1); \ 860 stw 29,FRAME_DSISR+8(1); \ 861 stw 30,FRAME_SRR0+8(1); \ 862 stw 31,FRAME_SRR1+8(1) 863 864#define FRAME_LEAVE(savearea) \ 865/* Now restore regs: */ \ 866 lwz 2,FRAME_SRR0+8(1); \ 867 lwz 3,FRAME_SRR1+8(1); \ 868 lwz 4,FRAME_CTR+8(1); \ 869 lwz 5,FRAME_XER+8(1); \ 870 lwz 6,FRAME_LR+8(1); \ 871 lwz 7,FRAME_CR+8(1); \ 872 stw 2,savearea(0); \ 873 stw 3,savearea+4(0); \ 874 mtctr 4; \ 875 mtxer 5; \ 876 mtlr 6; \ 877 mtsprg 1,7; /* save cr */ \ 878 lmw 2,FRAME_2+8(1); \ 879 lwz 0,FRAME_0+8(1); \ 880 lwz 1,FRAME_1+8(1); \ 881 mtsprg 2,2; /* save r2 & r3 */ \ 882 mtsprg 3,3; \ 883/* Disable translation, machine check and recoverability: */ \ 884 mfmsr 2; \ 885 andi. 2,2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ 886 mtmsr 2; \ 887 isync; \ 888/* Decide whether we return to user mode: */ \ 889 lwz 3,savearea+4(0); \ 890 mtcr 3; \ 891 bc 4,17,1f; /* branch if PSL_PR is false */ \ 892/* Restore user & kernel access SR: */ \ 893/* lis 2,curpm@ha; get real address of pmap */ \ 894/* lwz 2,curpm@l(2); */ \ 895/* lwz 3,PM_USRSR(2); */ \ 896/* mtsr USER_SR,3; */ \ 897/* lwz 3,PM_KERNELSR(2); */ \ 898/* mtsr KERNEL_SR,3; */ \ 8991: mfsprg 2,1; /* restore cr */ \ 900 mtcr 2; \ 901 lwz 2,savearea(0); \ 902 lwz 3,savearea+4(0); \ 903 mtsrr0 2; \ 904 mtsrr1 3; \ 905 mfsprg 2,2; /* restore r2 & r3 */ \ 906 mfsprg 3,3 907 908/* 909 * Preamble code for DSI/ISI traps 910 */ 911disitrap: 912 lmw 30,disisave(0) 913 stmw 30,tempsave(0) 914 lmw 30,disisave+8(0) 915 stmw 30,tempsave+8(0) 916 mfdar 30 917 mfdsisr 31 918 stmw 30,tempsave+16(0) 919realtrap: 920/* Test whether we already had PR set */ 921 mfsrr1 1 922 mtcr 1 923 mfsprg 1,1 /* restore SP (might have been 924 overwritten) */ 925 bc 4,17,s_trap /* branch if PSL_PR is false */ 926 mfsprg 1,0 927 lwz 1,PC_CURPCB(1) 928 addi 1,1,USPACE /* stack is top of user struct */ 929 930/* 931 * Now the common trap catching code. 932 */ 933s_trap: 934/* First have to enable KERNEL mapping */ 935 lis 31,KERNEL_SEGMENT@h 936 ori 31,31,KERNEL_SEGMENT@l 937 mtsr KERNEL_SR,31 938 FRAME_SETUP(tempsave) 939/* Now we can recover interrupts again: */ 940 mfmsr 7 941 ori 7,7,(PSL_EE|PSL_FP|PSL_ME|PSL_RI)@l 942 mtmsr 7 943 isync 944/* Call C trap code: */ 945 addi 3,1,8 946 mr 30,3 947 bl trap 948 mr 3,30 949 bl ast 950 FRAME_LEAVE(tempsave) 951 rfi 952 953/* 954 * DSI second stage fault handler 955 */ 956s_dsitrap: 957 mfdsisr 31 /* test whether this may be a 958 spill fault */ 959 mtcr 31 960 mtsprg 1,1 /* save SP */ 961 bc 4,1,disitrap /* branch if table miss is false */ 962 lis 1,spillstk+SPILLSTK@ha 963 addi 1,1,spillstk+SPILLSTK@l /* get spill stack */ 964 stwu 1,-52(1) 965 stw 0,48(1) /* save non-volatile registers */ 966 stw 3,44(1) 967 stw 4,40(1) 968 stw 5,36(1) 969 stw 6,32(1) 970 stw 7,28(1) 971 stw 8,24(1) 972 stw 9,20(1) 973 stw 10,16(1) 974 stw 11,12(1) 975 stw 12,8(1) 976 mflr 30 /* save trap type */ 977 mfctr 31 /* & CTR */ 978 mfdar 3 979s_pte_spill: 980 bl pmap_pte_spill /* try a spill */ 981 or. 3,3,3 982 mtctr 31 /* restore CTR */ 983 mtlr 30 /* and trap type */ 984 mfsprg 31,2 /* get saved XER */ 985 mtxer 31 /* restore XER */ 986 lwz 12,8(1) /* restore non-volatile registers */ 987 lwz 11,12(1) 988 lwz 10,16(1) 989 lwz 9,20(1) 990 lwz 8,24(1) 991 lwz 7,28(1) 992 lwz 6,32(1) 993 lwz 5,36(1) 994 lwz 4,40(1) 995 lwz 3,44(1) 996 lwz 0,48(1) 997 beq disitrap 998 mfsprg 1,1 /* restore SP */ 999 mtcr 29 /* restore CR */ 1000 mtlr 28 /* restore LR */ 1001 lmw 28,disisave(0) /* restore r28-r31 */ 1002 rfi /* return to trapped code */ 1003 1004/* 1005 * ISI second stage fault handler 1006 */ 1007s_isitrap: 1008 mfsrr1 31 /* test whether this may be a 1009 spill fault */ 1010 mtcr 31 1011 mtsprg 1,1 /* save SP */ 1012 bc 4,1,disitrap /* branch if table miss is false */ 1013 lis 1,spillstk+SPILLSTK@ha 1014 addi 1,1,spillstk+SPILLSTK@l /* get spill stack */ 1015 stwu 1,-52(1) 1016 stw 0,48(1) /* save non-volatile registers */ 1017 stw 3,44(1) 1018 stw 4,40(1) 1019 stw 5,36(1) 1020 stw 6,32(1) 1021 stw 7,28(1) 1022 stw 8,24(1) 1023 stw 9,20(1) 1024 stw 10,16(1) 1025 stw 11,12(1) 1026 stw 12,8(1) 1027 mfxer 30 /* save XER */ 1028 mtsprg 2,30 1029 mflr 30 /* save trap type */ 1030 mfctr 31 /* & ctr */ 1031 mfsrr0 3 1032 b s_pte_spill /* above */ 1033 1034/* 1035 * External interrupt second level handler 1036 */ 1037#define INTRENTER \ 1038/* Save non-volatile registers: */ \ 1039 stwu 1,-88(1); /* temporarily */ \ 1040 stw 0,84(1); \ 1041 mfsprg 0,1; /* get original SP */ \ 1042 stw 0,0(1); /* and store it */ \ 1043 stw 3,80(1); \ 1044 stw 4,76(1); \ 1045 stw 5,72(1); \ 1046 stw 6,68(1); \ 1047 stw 7,64(1); \ 1048 stw 8,60(1); \ 1049 stw 9,56(1); \ 1050 stw 10,52(1); \ 1051 stw 11,48(1); \ 1052 stw 12,44(1); \ 1053 stw 28,40(1); /* saved LR */ \ 1054 stw 29,36(1); /* saved CR */ \ 1055 stw 30,32(1); /* saved XER */ \ 1056 lmw 28,tempsave(0); /* restore r28-r31 */ \ 1057 mfctr 6; \ 1058 lis 5,intr_depth@ha; \ 1059 lwz 5,intr_depth@l(5); \ 1060 mfsrr0 4; \ 1061 mfsrr1 3; \ 1062 stw 6,28(1); \ 1063 stw 5,20(1); \ 1064 stw 4,12(1); \ 1065 stw 3,8(1); \ 1066/* interrupts are recoverable here, and enable translation */ \ 1067 lis 3,(KERNEL_SEGMENT|SR_KS|SR_KP)@h; \ 1068 ori 3,3,(KERNEL_SEGMENT|SR_KS|SR_KP)@l; \ 1069 mtsr KERNEL_SR,3; \ 1070 mfmsr 5; \ 1071 ori 5,5,(PSL_IR|PSL_DR|PSL_RI); \ 1072 mtmsr 5; \ 1073 isync 1074 1075 .globl extint_call 1076extintr: 1077 INTRENTER 1078extint_call: 1079 bl extint_call /* to be filled in later */ 1080 1081intr_exit: 1082/* Disable interrupts (should already be disabled) and MMU here: */ 1083 mfmsr 3 1084 andi. 3,3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l 1085 mtmsr 3 1086 isync 1087/* restore possibly overwritten registers: */ 1088 lwz 12,44(1) 1089 lwz 11,48(1) 1090 lwz 10,52(1) 1091 lwz 9,56(1) 1092 lwz 8,60(1) 1093 lwz 7,64(1) 1094 lwz 6,8(1) 1095 lwz 5,12(1) 1096 lwz 4,28(1) 1097 lwz 3,32(1) 1098 mtsrr1 6 1099 mtsrr0 5 1100 mtctr 4 1101 mtxer 3 1102/* Returning to user mode? */ 1103 mtcr 6 /* saved SRR1 */ 1104 bc 4,17,1f /* branch if PSL_PR is false */ 1105 mfsprg 3,0 /* get pcpu */ 1106 lwz 3,PC_CURPCB(3) /* get curpcb from pcpu */ 1107 lwz 3,PCB_PMR(3) /* get pmap real address from curpcb */ 1108 mtsr KERNEL_SR,3 1109/* Setup for entry to realtrap: */ 1110 lwz 3,0(1) /* get saved SP */ 1111 mtsprg 1,3 1112#if 0 /* XXX */ 1113 li 6,EXC_AST 1114#endif 1115 stmw 28,tempsave(0) /* establish tempsave again */ 1116 mtlr 6 1117 lwz 28,40(1) /* saved LR */ 1118 lwz 29,36(1) /* saved CR */ 1119 lwz 6,68(1) 1120 lwz 5,72(1) 1121 lwz 4,76(1) 1122 lwz 3,80(1) 1123 lwz 0,84(1) 1124 lis 30,intr_depth@ha /* adjust reentrancy count */ 1125 lwz 31,intr_depth@l(30) 1126 addi 31,31,-1 1127 stw 31,intr_depth@l(30) 1128 b realtrap /* XXX: should call ast(frame ptr) */ 11291: 1130/* Here is the normal exit of extintr: */ 1131 lwz 5,36(1) 1132 lwz 6,40(1) 1133 mtcr 5 1134 mtlr 6 1135 lwz 6,68(1) 1136 lwz 5,72(1) 1137 lis 3,intr_depth@ha /* adjust reentrancy count */ 1138 lwz 4,intr_depth@l(3) 1139 addi 4,4,-1 1140 stw 4,intr_depth@l(3) 1141 lwz 4,76(1) 1142 lwz 3,80(1) 1143 lwz 0,84(1) 1144 lwz 1,0(1) 1145 rfi 1146 1147/* 1148 * Decrementer interrupt second level handler 1149 */ 1150decrintr: 1151 INTRENTER 1152 addi 3,1,8 /* intr frame */ 1153 bl decr_intr 1154 lis 28,decrnest@ha 1155 xor 29,29,29 1156 stw 29,decrnest@l(28) 1157 b intr_exit 1158 1159#ifdef DDB 1160/* 1161 * Deliberate entry to ddbtrap 1162 */ 1163 .globl ddb_trap 1164ddb_trap: 1165 mtsprg 1,1 1166 mfmsr 3 1167 mtsrr1 3 1168 andi. 3,3,~(PSL_EE|PSL_ME|PSL_RI)@l 1169 mtmsr 3 /* disable interrupts */ 1170 isync 1171 stmw 28,ddbsave(0) 1172 mflr 28 1173 li 29,EXC_BPT 1174 mtlr 29 1175 mfcr 29 1176 mtsrr0 28 1177 1178/* 1179 * Now the ddb trap catching code. 1180 */ 1181ddbtrap: 1182 FRAME_SETUP(ddbsave) 1183/* Call C trap code: */ 1184 addi 3,1,8 1185 bl ddb_trap_glue 1186 or. 3,3,3 1187 bne ddbleave 1188/* This wasn't for DDB, so switch to real trap: */ 1189 lwz 3,FRAME_EXC+8(1) /* save exception */ 1190 stw 3,ddbsave+8(0) 1191 FRAME_LEAVE(ddbsave) 1192 mtsprg 1,1 /* prepare for entrance to realtrap */ 1193 stmw 28,tempsave(0) 1194 mflr 28 1195 mfcr 29 1196 lwz 31,ddbsave+8(0) 1197 mtlr 31 1198 b realtrap 1199ddbleave: 1200 FRAME_LEAVE(ddbsave) 1201 rfi 1202#endif /* DDB */ 1203 1204#ifdef IPKDB 1205/* 1206 * Deliberate entry to ipkdbtrap 1207 */ 1208 .globl ipkdb_trap 1209ipkdb_trap: 1210 mtsprg 1,1 1211 mfmsr 3 1212 mtsrr1 3 1213 andi. 3,3,~(PSL_EE|PSL_ME|PSL_RI)@l 1214 mtmsr 3 /* disable interrupts */ 1215 isync 1216 stmw 28,ipkdbsave(0) 1217 mflr 28 1218 li 29,EXC_BPT 1219 mtlr 29 1220 mfcr 29 1221 mtsrr0 28 1222 1223/* 1224 * Now the ipkdb trap catching code. 1225 */ 1226ipkdbtrap: 1227 FRAME_SETUP(ipkdbsave) 1228/* Call C trap code: */ 1229 addi 3,1,8 1230 bl ipkdb_trap_glue 1231 or. 3,3,3 1232 bne ipkdbleave 1233/* This wasn't for IPKDB, so switch to real trap: */ 1234 lwz 3,FRAME_EXC+8(1) /* save exception */ 1235 stw 3,ipkdbsave+8(0) 1236 FRAME_LEAVE(ipkdbsave) 1237 mtsprg 1,1 /* prepare for entrance to realtrap */ 1238 stmw 28,tempsave(0) 1239 mflr 28 1240 mfcr 29 1241 lwz 31,ipkdbsave+8(0) 1242 mtlr 31 1243 b realtrap 1244ipkdbleave: 1245 FRAME_LEAVE(ipkdbsave) 1246 rfi 1247 1248ipkdbfault: 1249 ba _ipkdbfault 1250_ipkdbfault: 1251 mfsrr0 3 1252 addi 3,3,4 1253 mtsrr0 3 1254 li 3,-1 1255 rfi 1256 1257/* 1258 * int ipkdbfbyte(unsigned char *p) 1259 */ 1260 .globl ipkdbfbyte 1261ipkdbfbyte: 1262 li 9,EXC_DSI /* establish new fault routine */ 1263 lwz 5,0(9) 1264 lis 6,ipkdbfault@ha 1265 lwz 6,ipkdbfault@l(6) 1266 stw 6,0(9) 1267#ifdef IPKDBUSERHACK 1268 lis 8,ipkdbsr@ha 1269 lwz 8,ipkdbsr@l(8) 1270 mtsr USER_SR,8 1271 isync 1272#endif 1273 dcbst 0,9 /* flush data... */ 1274 sync 1275 icbi 0,9 /* and instruction caches */ 1276 lbz 3,0(3) /* fetch data */ 1277 stw 5,0(9) /* restore previous fault handler */ 1278 dcbst 0,9 /* and flush data... */ 1279 sync 1280 icbi 0,9 /* and instruction caches */ 1281 blr 1282 1283/* 1284 * int ipkdbsbyte(unsigned char *p, int c) 1285 */ 1286 .globl ipkdbsbyte 1287ipkdbsbyte: 1288 li 9,EXC_DSI /* establish new fault routine */ 1289 lwz 5,0(9) 1290 lis 6,ipkdbfault@ha 1291 lwz 6,ipkdbfault@l(6) 1292 stw 6,0(9) 1293#ifdef IPKDBUSERHACK 1294 lis 8,ipkdbsr@ha 1295 lwz 8,ipkdbsr@l(8) 1296 mtsr USER_SR,8 1297 isync 1298#endif 1299 dcbst 0,9 /* flush data... */ 1300 sync 1301 icbi 0,9 /* and instruction caches */ 1302 mr 6,3 1303 xor 3,3,3 1304 stb 4,0(6) 1305 dcbst 0,6 /* Now do appropriate flushes 1306 to data... */ 1307 sync 1308 icbi 0,6 /* and instruction caches */ 1309 stw 5,0(9) /* restore previous fault handler */ 1310 dcbst 0,9 /* and flush data... */ 1311 sync 1312 icbi 0,9 /* and instruction caches */ 1313 blr 1314#endif /* IPKDB */ 1315 1316/* | |
1317 * int setfault() 1318 * 1319 * Similar to setjmp to setup for handling faults on accesses to user memory. 1320 * Any routine using this may only call bcopy, either the form below, 1321 * or the (currently used) C code optimized, so it doesn't use any non-volatile 1322 * registers. 1323 */ 1324 .globl setfault 1325setfault: 1326 mflr 0 1327 mfcr 12 1328 mfsprg 4,0 | 398 * int setfault() 399 * 400 * Similar to setjmp to setup for handling faults on accesses to user memory. 401 * Any routine using this may only call bcopy, either the form below, 402 * or the (currently used) C code optimized, so it doesn't use any non-volatile 403 * registers. 404 */ 405 .globl setfault 406setfault: 407 mflr 0 408 mfcr 12 409 mfsprg 4,0 |
1329 lwz 4,PC_CURPCB(4) | 410 lwz 4,PC_CURTHREAD(4) 411 lwz 4,TD_PCB(4) |
1330 stw 3,PCB_ONFAULT(4) 1331 stw 0,0(3) 1332 stw 1,4(3) 1333 stw 2,8(3) 1334 stmw 12,12(3) 1335 xor 3,3,3 1336 blr 1337 | 412 stw 3,PCB_ONFAULT(4) 413 stw 0,0(3) 414 stw 1,4(3) 415 stw 2,8(3) 416 stmw 12,12(3) 417 xor 3,3,3 418 blr 419 |
1338/* 1339 * Signal "trampoline" code. 1340 */ 1341 .globl sigcode 1342sigcode: 1343 b sys_exit 1344esigcode: 1345 .data 1346GLOBAL(szsigcode) 1347 .long esigcode-sigcode 1348 .text 1349 | 420#include <powerpc/powerpc/trap_subr.S> |