Print this page
de-linting of .s files


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #if defined(lint)
  27 #include <sys/types.h>
  28 #include <sys/t_lock.h>
  29 #include <sys/promif.h>
  30 #include <sys/prom_isa.h>
  31 #endif  /* lint */
  32 
  33 #include <sys/asm_linkage.h>
  34 #include <sys/intreg.h>
  35 #include <sys/ivintr.h>
  36 #include <sys/mmu.h>
  37 #include <sys/machpcb.h>
  38 #include <sys/machtrap.h>
  39 #include <sys/machlock.h>
  40 #include <sys/fdreg.h>
  41 #include <sys/vis.h>
  42 #include <sys/traptrace.h>
  43 #include <sys/panic.h>
  44 #include <sys/machasi.h>
  45 #include <sys/privregs.h>
  46 #include <sys/hypervisor_api.h>
  47 #include <sys/clock.h>
  48 
  49 #if defined(lint)
  50 
  51 #include <sys/thread.h>
  52 #include <sys/time.h>
  53 
  54 #else   /* lint */
  55 
  56 #include "assym.h"
  57 
  58 
  59 !
  60 ! REGOFF must add up to allow double word access to r_tstate.
  61 ! PCB_WBUF must also be aligned.
  62 !
  63 #if (REGOFF & 7) != 0
  64 #error "struct regs not aligned"
  65 #endif
  66 
  67 /*
  68  * Absolute external symbols.
  69  * On the sun4u we put the panic buffer in the third and fourth pages.
  70  * We set things up so that the first 2 pages of KERNELBASE is illegal
  71  * to act as a redzone during copyin/copyout type operations. One of
  72  * the reasons the panic buffer is allocated in low memory to
  73  * prevent being overwritten during booting operations (besides
  74  * the fact that it is small enough to share pages with others).
  75  */


 165  * show in which TRACE_PTR the assertion failure happened.
 166  */
 167         .align  8
 168 trap_freeze_pc:
 169         .nword  0
 170 #endif  /* TRAPTRACE */
 171 
 172         .align 4
 173         .seg    ".text"
 174 
 175 #ifdef  NOPROM
 176         .global availmem
 177 availmem:
 178         .word   0
 179 #endif  /* NOPROM */
 180 
 181         .align  8
 182 _local_p1275cis:
 183         .nword  0
 184 
 185 #endif  /* lint */
 186 
 187 #if defined(lint)
 188 
 189 void
 190 _start(void)
 191 {}
 192 
 193 #else /* lint */
 194 
 195         .seg    ".data"
 196 
 197         .global nwindows, nwin_minus_one, winmask
 198 nwindows:
 199         .word   8
 200 nwin_minus_one:
 201         .word   7
 202 winmask:
 203         .word   8
 204 
 205         .global afsrbuf
 206 afsrbuf:
 207         .word   0,0,0,0
 208 
 209 /*
 210  * System initialization
 211  *
 212  * Our contract with the boot prom specifies that the MMU is on and the
 213  * first 16 meg of memory is mapped with a level-1 pte.  We are called
 214  * with p1275cis ptr in %o0 and kdi_dvec in %o1; we start execution


 347 #endif
 348 
 349         !
 350         ! Now call main.  We will return as process 1 (init).
 351         !
 352         call    main
 353         nop
 354 
 355         !
 356         ! Main should never return.
 357         !
 358         set     .mainretmsg, %o0
 359         call    panic
 360         nop
 361         SET_SIZE(_start)
 362 
 363 .mainretmsg:
 364         .asciz  "main returned"
 365         .align  4
 366 
 367 #endif  /* lint */
 368 
 369 
 370 /*
 371  * Generic system trap handler.
 372  *
 373  * Some kernel trap handlers save themselves from buying a window by
 374  * borrowing some of sys_trap's unused locals. %l0 thru %l3 may be used
 375  * for this purpose, as user_rtt and priv_rtt do not depend on them.
 376  * %l4 thru %l7 should NOT be used this way.
 377  *
 378  * Entry Conditions:
 379  *      %pstate         am:0 priv:1 ie:0
 380  *      %gl             global level  1
 381  *
 382  * Register Inputs:
 383  *      %g1             pc of trap handler
 384  *      %g2, %g3        args for handler
 385  *      %g4             desired %pil (-1 means current %pil)
 386  *      %g5, %g6        destroyed
 387  *      %g7             saved
 388  *
 389  * Register Usage:
 390  *      %l0, %l1        temps
 391  *      %l3             saved %g1
 392  *      %l6             curthread for user traps, %pil for priv traps
 393  *      %l7             regs
 394  *
 395  * Called function prototype variants:
 396  *
 397  *      func(struct regs *rp);
 398  *      func(struct regs *rp, uintptr_t arg1 [%g2], uintptr_t arg2 [%g3])
 399  *      func(struct regs *rp, uintptr_t arg1 [%g2],
 400  *          uint32_t arg2 [%g3.l], uint32_t arg3 [%g3.h])
 401  *      func(struct regs *rp, uint32_t arg1 [%g2.l],
 402  *          uint32_t arg2 [%g3.l], uint32_t arg3 [%g3.h], uint32_t [%g2.h])
 403  */
 404 
 405 #if defined(lint)
 406 
 407 void
 408 sys_trap(void)
 409 {}
 410 
 411 #else   /* lint */
 412 
 413         ENTRY_NP(sys_trap)
 414 #ifdef DEBUG
 415         ! Assert gl == 1
 416         rdpr    %gl, %g5
 417         cmp     %g5, 1
 418         bne,a,pn %xcc, ptl1_panic
 419           mov   PTL1_BAD_GL, %g1
 420 #endif
 421 
 422         !
 423         ! force tl=1, update %cwp, branch to correct handler
 424         !
 425 
 426         wrpr    %g0, 1, %tl
 427         rdpr    %tstate, %g5
 428         btst    TSTATE_PRIV, %g5
 429         and     %g5, TSTATE_CWP, %g6
 430         bnz,pn  %xcc, priv_trap
 431         wrpr    %g0, %g6, %cwp
 432 


1030         rdpr    %canrestore, %g1
1031         brnz    %g1, 3f
1032         nop                     ! no trap, use restore directly
1033         rdpr    %cwp, %g1
1034         wrpr    %g1, %g7, %tstate       ! needed by wbuf recovery code
1035         ! hand craft the restore to avoid getting to TL > 2
1036         FILL_64bit_rtt(ASI_N)
1037 3:
1038         restore
1039         !
1040         ! set %tstate to the correct %cwp
1041         ! retry resumes prom execution
1042         !
1043         rdpr    %cwp, %g1
1044         wrpr    %g1, %g7, %tstate
1045         retry
1046         /* NOTREACHED */
1047         SET_SIZE(priv_rtt)
1048         SET_SIZE(ktl0)
1049 
1050 #endif  /* lint */
1051 
1052 #ifndef lint
1053 
1054 #ifdef DEBUG
1055         .seg    ".data"
1056         .align  4
1057 
1058         .global bad_g4_called
1059 bad_g4_called:
1060         .word   0
1061 
1062 sys_trap_wrong_pil:
1063         .asciz  "sys_trap: %g4(%d) is lower than %pil(%d)"
1064         .align  4
1065         .seg    ".text"
1066 
1067         ENTRY_NP(bad_g4)
1068         mov     %o1, %o0
1069         mov     %o2, %o1
1070         call    panic
1071         mov     %o3, %o2
1072         SET_SIZE(bad_g4)
1073 #endif /* DEBUG */
1074 #endif /* lint */
1075 
1076 /*
1077  * sys_tl1_panic can be called by traps at tl1 which
1078  * really want to panic, but need the rearrangement of
1079  * the args as provided by this wrapper routine.
1080  */
1081 #if defined(lint)
1082 
1083 void
1084 sys_tl1_panic(void)
1085 {}
1086 
1087 #else   /* lint */
1088         ENTRY_NP(sys_tl1_panic)
1089         mov     %o1, %o0
1090         mov     %o2, %o1
1091         call    panic
1092         mov     %o3, %o2
1093         SET_SIZE(sys_tl1_panic)
1094 #endif /* lint */
1095 
1096 
1097 /*
1098  * Flush all windows to memory, except for the one we entered in.
1099  * We do this by doing NWINDOW-2 saves then the same number of restores.
1100  * This leaves the WIM immediately before window entered in.
1101  * This is used for context switching.
1102  */
1103 
1104 #if defined(lint)
1105 
1106 void
1107 flush_windows(void)
1108 {}
1109 
1110 #else   /* lint */
1111 
1112         ENTRY_NP(flush_windows)
1113         retl
1114         flushw
1115         SET_SIZE(flush_windows)
1116 
1117 #endif  /* lint */
1118 
1119 #if defined(lint)
1120 
1121 void
1122 debug_flush_windows(void)
1123 {}
1124 
1125 #else   /* lint */
1126 
1127         ENTRY_NP(debug_flush_windows)
1128         set     nwindows, %g1
1129         ld      [%g1], %g1
1130         mov     %g1, %g2
1131 
1132 1:
1133         save    %sp, -WINDOWSIZE, %sp
1134         brnz    %g2, 1b
1135         dec     %g2
1136 
1137         mov     %g1, %g2
1138 2:
1139         restore
1140         brnz    %g2, 2b
1141         dec     %g2
1142 
1143         retl
1144         nop
1145 
1146         SET_SIZE(debug_flush_windows)
1147 
1148 #endif  /* lint */
1149 
1150 /*
1151  * flush user windows to memory.
1152  */
1153 
1154 #if defined(lint)
1155 
1156 void
1157 flush_user_windows(void)
1158 {}
1159 
1160 #else   /* lint */
1161 
1162         ENTRY_NP(flush_user_windows)
1163         rdpr    %otherwin, %g1
1164         brz     %g1, 3f
1165         clr     %g2
1166 1:
1167         save    %sp, -WINDOWSIZE, %sp
1168         rdpr    %otherwin, %g1
1169         brnz    %g1, 1b
1170         add     %g2, 1, %g2
1171 2:
1172         sub     %g2, 1, %g2             ! restore back to orig window
1173         brnz    %g2, 2b
1174         restore
1175 3:
1176         retl
1177         nop
1178         SET_SIZE(flush_user_windows)
1179 
1180 #endif  /* lint */
1181 
1182 /*
1183  * Throw out any user windows in the register file.
1184  * Used by setregs (exec) to clean out old user.
1185  * Used by sigcleanup to remove extraneous windows when returning from a
1186  * signal.
1187  */
1188 
1189 #if defined(lint)
1190 
1191 void
1192 trash_user_windows(void)
1193 {}
1194 
1195 #else   /* lint */
1196 
1197         ENTRY_NP(trash_user_windows)
1198         rdpr    %otherwin, %g1
1199         brz     %g1, 3f                 ! no user windows?
1200         ldn     [THREAD_REG + T_STACK], %g5
1201 
1202         !
1203         ! There are old user windows in the register file. We disable ints
1204         ! and increment cansave so that we don't overflow on these windows.
1205         ! Also, this sets up a nice underflow when first returning to the
1206         ! new user.
1207         !
1208         rdpr    %pstate, %g2
1209         wrpr    %g2, PSTATE_IE, %pstate
1210         rdpr    %cansave, %g3
1211         rdpr    %otherwin, %g1          ! re-read in case of interrupt
1212         add     %g3, %g1, %g3
1213         wrpr    %g0, 0, %otherwin
1214         wrpr    %g0, %g3, %cansave
1215         wrpr    %g0, %g2, %pstate
1216 3:
1217         retl
1218         clr     [%g5 + MPCB_WBCNT]       ! zero window buffer cnt
1219         SET_SIZE(trash_user_windows)
1220 
1221 
1222 #endif  /* lint */
1223 
1224 /*
1225  * Setup g7 via the CPU data structure.
1226  */
1227 #if defined(lint)
1228 
1229 struct scb *
1230 set_tbr(struct scb *s)
1231 { return (s); }
1232 
1233 #else   /* lint */
1234 
1235         ENTRY_NP(set_tbr)
1236         retl
1237         ta      72              ! no tbr, stop simulation
1238         SET_SIZE(set_tbr)
1239 
1240 #endif  /* lint */
1241 
1242 
1243 #if defined(lint)
1244 /*
1245  * These need to be defined somewhere to lint and there is no "hicore.s"...
1246  */
1247 char etext[1], end[1];
1248 #endif  /* lint*/
1249 
1250 #if defined (lint)
1251 
1252 /* ARGSUSED */
1253 void
1254 ptl1_panic(u_int reason)
1255 {}
1256 
1257 #else /* lint */
1258 
1259 #define PTL1_SAVE_WINDOW(RP)                                            \
1260         stxa    %l0, [RP + RW64_LOCAL + (0 * RW64_LOCAL_INCR)] %asi;    \
1261         stxa    %l1, [RP + RW64_LOCAL + (1 * RW64_LOCAL_INCR)] %asi;    \
1262         stxa    %l2, [RP + RW64_LOCAL + (2 * RW64_LOCAL_INCR)] %asi;    \
1263         stxa    %l3, [RP + RW64_LOCAL + (3 * RW64_LOCAL_INCR)] %asi;    \
1264         stxa    %l4, [RP + RW64_LOCAL + (4 * RW64_LOCAL_INCR)] %asi;    \
1265         stxa    %l5, [RP + RW64_LOCAL + (5 * RW64_LOCAL_INCR)] %asi;    \
1266         stxa    %l6, [RP + RW64_LOCAL + (6 * RW64_LOCAL_INCR)] %asi;    \
1267         stxa    %l7, [RP + RW64_LOCAL + (7 * RW64_LOCAL_INCR)] %asi;    \
1268         stxa    %i0, [RP + RW64_IN + (0 * RW64_IN_INCR)] %asi;          \
1269         stxa    %i1, [RP + RW64_IN + (1 * RW64_IN_INCR)] %asi;          \
1270         stxa    %i2, [RP + RW64_IN + (2 * RW64_IN_INCR)] %asi;          \
1271         stxa    %i3, [RP + RW64_IN + (3 * RW64_IN_INCR)] %asi;          \
1272         stxa    %i4, [RP + RW64_IN + (4 * RW64_IN_INCR)] %asi;          \
1273         stxa    %i5, [RP + RW64_IN + (5 * RW64_IN_INCR)] %asi;          \
1274         stxa    %i6, [RP + RW64_IN + (6 * RW64_IN_INCR)] %asi;          \
1275         stxa    %i7, [RP + RW64_IN + (7 * RW64_IN_INCR)] %asi
1276 #define PTL1_NEXT_WINDOW(scr)   \
1277         add     scr, RWIN64SIZE, scr
1278 


1480         CPU_ADDR(%l0, %l1)                      ! %l0 = cpu[cpuid]
1481         add     %l0, CPU_PTL1, %l1              ! %l1 = &CPU->mcpu.ptl1_state
1482         !
1483         ! prepare to call panic()
1484         !
1485         ldn     [%l0 + CPU_THREAD], THREAD_REG  ! restore %g7
1486         ldn     [%l1 + PTL1_STKTOP], %l2        ! %sp = ptl1_stktop
1487         sub     %l2, SA(MINFRAME) + STACK_BIAS, %sp
1488         clr     %fp                             ! no frame below this window
1489         clr     %i7
1490         !
1491         ! enable limited interrupts
1492         !
1493         wrpr    %g0, CLOCK_LEVEL, %pil
1494         wrpr    %g0, PSTATE_KERN, %pstate
1495         !
1496         ba,pt   %xcc, ptl1_panic_handler
1497           mov   %l1, %o0
1498         /*NOTREACHED*/
1499         SET_SIZE(ptl1_panic)
1500 #endif /* lint */
1501 
1502 #ifdef  PTL1_PANIC_DEBUG
1503 #if defined (lint)
1504 /*
1505  * ptl1_recurse() calls itself a number of times to either set up a known
1506  * stack or to cause a kernel stack overflow. It decrements the arguments 
1507  * on each recursion.
1508  * It's called by #ifdef PTL1_PANIC_DEBUG code in startup.c to set the
1509  * registers to a known state to facilitate debugging.
1510  */
1511 
1512 /* ARGSUSED */
1513 void 
1514 ptl1_recurse(int count_threshold, int trap_threshold)
1515 {}
1516 
1517 #else /* lint */
1518 
1519         ENTRY_NP(ptl1_recurse)
1520         save    %sp, -SA(MINFRAME), %sp
1521 
1522         set     ptl1_recurse_call, %o7
1523         cmp     %o7, %i7                        ! if ptl1_recurse is called
1524         be,pt  %icc, 0f                         ! by itself, then skip
1525           nop                                   ! register initialization
1526 
1527         /* 
1528          * Initialize Out Registers to Known Values 
1529          */
1530         set     0x01000, %l0                    ! %i0 is the ...
1531                                                 ! recursion_depth_count
1532         sub     %i0, 1, %o0;
1533         sub     %i1, 1, %o1;
1534         add     %l0, %o0, %o2;
1535         add     %l0, %o2, %o3;
1536         add     %l0, %o3, %o4;
1537         add     %l0, %o4, %o5;
1538         ba,a    1f


1563 
1564         brz,pn %i1, ptl1_recurse_trap           ! if trpp_count == 0) {
1565           nop                                   !    trap to ptl1_panic
1566                                                 !                       
1567         brz,pn %i0, ptl1_recure_exit            ! if(depth_count == 0) {
1568           nop                                   !    skip recursive call
1569                                                 ! }
1570 ptl1_recurse_call:
1571         call    ptl1_recurse
1572           nop
1573 
1574 ptl1_recure_exit:
1575         ret
1576         restore
1577 
1578 ptl1_recurse_trap:
1579         ta      PTL1_DEBUG_TRAP;                ! Trap Always to ptl1_panic()
1580           nop                                   ! NOTREACHED 
1581         SET_SIZE(ptl1_recurse)
1582 
1583 #endif /* lint */
1584 
1585 #if defined (lint)
1586 
1587 /* ARGSUSED */
1588 void
1589 ptl1_panic_xt(int arg1, int arg2)
1590 {}
1591 
1592 #else /* lint */
1593         /*
1594          * Asm function to handle a cross trap to call ptl1_panic()
1595          */
1596         ENTRY_NP(ptl1_panic_xt)
1597         ba      ptl1_panic
1598           mov   PTL1_BAD_DEBUG, %g1
1599         SET_SIZE(ptl1_panic_xt)
1600 
1601 #endif /* lint */
1602 
1603 #endif  /* PTL1_PANIC_DEBUG */
1604 
1605 #ifdef  TRAPTRACE
1606 #if     defined (lint)
1607 
1608 void
1609 trace_ptr_panic(void)
1610 {
1611 }
1612 
1613 #else   /* lint */
1614 
1615         ENTRY_NP(trace_ptr_panic)
1616         !
1617         ! freeze the trap trace to disable the assertions.  Otherwise,
1618         ! ptl1_panic is likely to be repeatedly called from there.
1619         ! %g2 and %g3 are used as scratch registers in ptl1_panic.
1620         !
1621         mov     1, %g3
1622         sethi   %hi(trap_freeze), %g2
1623         st      %g3, [%g2 + %lo(trap_freeze)]
1624         !
1625         ! %g1 contains the %pc address where an assertion was failed.
1626         ! save it in trap_freeze_pc for a debugging hint if there is
1627         ! no value saved in it.
1628         !
1629         set     trap_freeze_pc, %g2
1630         casn    [%g2], %g0, %g1
1631 
1632         ba      ptl1_panic
1633         mov     PTL1_BAD_TRACE_PTR, %g1
1634         SET_SIZE(trace_ptr_panic)
1635 
1636 #endif  /* lint */
1637 #endif  /* TRAPTRACE */
1638 
1639 /*
1640  * The interface for a 32-bit client program that takes over the TBA
1641  * calling the 64-bit romvec OBP.
1642  */
1643 
1644 #if defined(lint)
1645 
1646 /* ARGSUSED */
1647 int
1648 client_handler(void *cif_handler, void *arg_array)
1649 { return 0; }
1650 
1651 #else   /* lint */
1652 
1653         ENTRY(client_handler)
1654         save    %sp, -SA64(MINFRAME64), %sp     ! 32 bit frame, 64 bit sized
1655         sethi   %hi(tba_taken_over), %l2
1656         ld      [%l2+%lo(tba_taken_over)], %l3
1657         brz     %l3, 1f                         ! is the tba_taken_over = 1 ?
1658         rdpr    %wstate, %l5                    ! save %wstate
1659         andn    %l5, WSTATE_MASK, %l6
1660         wrpr    %l6, WSTATE_KMIX, %wstate
1661 1:      mov     %i1, %o0
1662 1:      rdpr    %pstate, %l4                    ! Get the present pstate value
1663         andn    %l4, PSTATE_AM, %l6
1664         wrpr    %l6, 0, %pstate                 ! Set PSTATE_AM = 0
1665         jmpl    %i0, %o7                        ! Call cif handler
1666         nop
1667         wrpr    %l4, 0, %pstate                 ! restore pstate
1668         brz     %l3, 1f                         ! is the tba_taken_over = 1
1669           nop
1670         wrpr    %g0, %l5, %wstate               ! restore wstate
1671 1:      ret                                     ! Return result ...
1672         restore %o0, %g0, %o0                   ! delay; result in %o0
1673         SET_SIZE(client_handler)
1674 
1675 #endif  /* lint */
1676 
1677 #if defined(lint)
1678 
1679 /*ARGSUSED*/
1680 void
1681 panic_bad_hcall(uint64_t err, uint64_t hcall)
1682 {}
1683 
1684 #else   /* lint */
1685 
1686         .seg    ".text"
1687 bad_hcall_error:
1688         .asciz  "hypervisor call 0x%x returned an unexpected error %d"
1689 
1690         /*
1691          * panic_bad_hcall is called when a hcall returns
1692          * unexpected error
1693          * %o0 error number
1694          * %o1 hcall number
1695          */
1696 
1697         ENTRY(panic_bad_hcall)
1698         mov     %o0, %o2
1699         sethi   %hi(bad_hcall_error), %o0
1700         or      %o0, %lo(bad_hcall_error), %o0
1701         mov     %o7, %o3
1702         call    panic
1703         mov     %o3, %o7
1704         SET_SIZE(panic_bad_hcall)
1705 
1706 #endif  /* lint */


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 







  26 #include <sys/asm_linkage.h>
  27 #include <sys/intreg.h>
  28 #include <sys/ivintr.h>
  29 #include <sys/mmu.h>
  30 #include <sys/machpcb.h>
  31 #include <sys/machtrap.h>
  32 #include <sys/machlock.h>
  33 #include <sys/fdreg.h>
  34 #include <sys/vis.h>
  35 #include <sys/traptrace.h>
  36 #include <sys/panic.h>
  37 #include <sys/machasi.h>
  38 #include <sys/privregs.h>
  39 #include <sys/hypervisor_api.h>
  40 #include <sys/clock.h>
  41 







  42 #include "assym.h"
  43 
  44 
  45 !
  46 ! REGOFF must add up to allow double word access to r_tstate.
  47 ! PCB_WBUF must also be aligned.
  48 !
  49 #if (REGOFF & 7) != 0
  50 #error "struct regs not aligned"
  51 #endif
  52 
  53 /*
  54  * Absolute external symbols.
  55  * On the sun4u we put the panic buffer in the third and fourth pages.
  56  * We set things up so that the first 2 pages of KERNELBASE is illegal
  57  * to act as a redzone during copyin/copyout type operations. One of
  58  * the reasons the panic buffer is allocated in low memory to
  59  * prevent being overwritten during booting operations (besides
  60  * the fact that it is small enough to share pages with others).
  61  */


 151  * show in which TRACE_PTR the assertion failure happened.
 152  */
 153         .align  8
 154 trap_freeze_pc:
 155         .nword  0
 156 #endif  /* TRAPTRACE */
 157 
 158         .align 4
 159         .seg    ".text"
 160 
 161 #ifdef  NOPROM
 162         .global availmem
 163 availmem:
 164         .word   0
 165 #endif  /* NOPROM */
 166 
 167         .align  8
 168 _local_p1275cis:
 169         .nword  0
 170 










 171         .seg    ".data"
 172 
 173         .global nwindows, nwin_minus_one, winmask
 174 nwindows:
 175         .word   8
 176 nwin_minus_one:
 177         .word   7
 178 winmask:
 179         .word   8
 180 
 181         .global afsrbuf
 182 afsrbuf:
 183         .word   0,0,0,0
 184 
 185 /*
 186  * System initialization
 187  *
 188  * Our contract with the boot prom specifies that the MMU is on and the
 189  * first 16 meg of memory is mapped with a level-1 pte.  We are called
 190  * with p1275cis ptr in %o0 and kdi_dvec in %o1; we start execution


 323 #endif
 324 
 325         !
 326         ! Now call main.  We will return as process 1 (init).
 327         !
 328         call    main
 329         nop
 330 
 331         !
 332         ! Main should never return.
 333         !
 334         set     .mainretmsg, %o0
 335         call    panic
 336         nop
 337         SET_SIZE(_start)
 338 
 339 .mainretmsg:
 340         .asciz  "main returned"
 341         .align  4
 342 

 343 

 344 /*
 345  * Generic system trap handler.
 346  *
 347  * Some kernel trap handlers save themselves from buying a window by
 348  * borrowing some of sys_trap's unused locals. %l0 thru %l3 may be used
 349  * for this purpose, as user_rtt and priv_rtt do not depend on them.
 350  * %l4 thru %l7 should NOT be used this way.
 351  *
 352  * Entry Conditions:
 353  *      %pstate         am:0 priv:1 ie:0
 354  *      %gl             global level  1
 355  *
 356  * Register Inputs:
 357  *      %g1             pc of trap handler
 358  *      %g2, %g3        args for handler
 359  *      %g4             desired %pil (-1 means current %pil)
 360  *      %g5, %g6        destroyed
 361  *      %g7             saved
 362  *
 363  * Register Usage:
 364  *      %l0, %l1        temps
 365  *      %l3             saved %g1
 366  *      %l6             curthread for user traps, %pil for priv traps
 367  *      %l7             regs
 368  *
 369  * Called function prototype variants:
 370  *
 371  *      func(struct regs *rp);
 372  *      func(struct regs *rp, uintptr_t arg1 [%g2], uintptr_t arg2 [%g3])
 373  *      func(struct regs *rp, uintptr_t arg1 [%g2],
 374  *          uint32_t arg2 [%g3.l], uint32_t arg3 [%g3.h])
 375  *      func(struct regs *rp, uint32_t arg1 [%g2.l],
 376  *          uint32_t arg2 [%g3.l], uint32_t arg3 [%g3.h], uint32_t [%g2.h])
 377  */
 378 








 379         ENTRY_NP(sys_trap)
 380 #ifdef DEBUG
 381         ! Assert gl == 1
 382         rdpr    %gl, %g5
 383         cmp     %g5, 1
 384         bne,a,pn %xcc, ptl1_panic
 385           mov   PTL1_BAD_GL, %g1
 386 #endif
 387 
 388         !
 389         ! force tl=1, update %cwp, branch to correct handler
 390         !
 391 
 392         wrpr    %g0, 1, %tl
 393         rdpr    %tstate, %g5
 394         btst    TSTATE_PRIV, %g5
 395         and     %g5, TSTATE_CWP, %g6
 396         bnz,pn  %xcc, priv_trap
 397         wrpr    %g0, %g6, %cwp
 398 


 996         rdpr    %canrestore, %g1
 997         brnz    %g1, 3f
 998         nop                     ! no trap, use restore directly
 999         rdpr    %cwp, %g1
1000         wrpr    %g1, %g7, %tstate       ! needed by wbuf recovery code
1001         ! hand craft the restore to avoid getting to TL > 2
1002         FILL_64bit_rtt(ASI_N)
1003 3:
1004         restore
1005         !
1006         ! set %tstate to the correct %cwp
1007         ! retry resumes prom execution
1008         !
1009         rdpr    %cwp, %g1
1010         wrpr    %g1, %g7, %tstate
1011         retry
1012         /* NOTREACHED */
1013         SET_SIZE(priv_rtt)
1014         SET_SIZE(ktl0)
1015 




1016 #ifdef DEBUG
1017         .seg    ".data"
1018         .align  4
1019 
1020         .global bad_g4_called
1021 bad_g4_called:
1022         .word   0
1023 
1024 sys_trap_wrong_pil:
1025         .asciz  "sys_trap: %g4(%d) is lower than %pil(%d)"
1026         .align  4
1027         .seg    ".text"
1028 
1029         ENTRY_NP(bad_g4)
1030         mov     %o1, %o0
1031         mov     %o2, %o1
1032         call    panic
1033         mov     %o3, %o2
1034         SET_SIZE(bad_g4)
1035 #endif /* DEBUG */

1036 
1037 /*
1038  * sys_tl1_panic can be called by traps at tl1 which
1039  * really want to panic, but need the rearrangement of
1040  * the args as provided by this wrapper routine.
1041  */







1042         ENTRY_NP(sys_tl1_panic)
1043         mov     %o1, %o0
1044         mov     %o2, %o1
1045         call    panic
1046         mov     %o3, %o2
1047         SET_SIZE(sys_tl1_panic)

1048 
1049 
1050 /*
1051  * Flush all windows to memory, except for the one we entered in.
1052  * We do this by doing NWINDOW-2 saves then the same number of restores.
1053  * This leaves the WIM immediately before window entered in.
1054  * This is used for context switching.
1055  */
1056 








1057         ENTRY_NP(flush_windows)
1058         retl
1059         flushw
1060         SET_SIZE(flush_windows)
1061 










1062         ENTRY_NP(debug_flush_windows)
1063         set     nwindows, %g1
1064         ld      [%g1], %g1
1065         mov     %g1, %g2
1066 
1067 1:
1068         save    %sp, -WINDOWSIZE, %sp
1069         brnz    %g2, 1b
1070         dec     %g2
1071 
1072         mov     %g1, %g2
1073 2:
1074         restore
1075         brnz    %g2, 2b
1076         dec     %g2
1077 
1078         retl
1079         nop
1080 
1081         SET_SIZE(debug_flush_windows)
1082 


1083 /*
1084  * flush user windows to memory.
1085  */
1086 








1087         ENTRY_NP(flush_user_windows)
1088         rdpr    %otherwin, %g1
1089         brz     %g1, 3f
1090         clr     %g2
1091 1:
1092         save    %sp, -WINDOWSIZE, %sp
1093         rdpr    %otherwin, %g1
1094         brnz    %g1, 1b
1095         add     %g2, 1, %g2
1096 2:
1097         sub     %g2, 1, %g2             ! restore back to orig window
1098         brnz    %g2, 2b
1099         restore
1100 3:
1101         retl
1102         nop
1103         SET_SIZE(flush_user_windows)
1104 


1105 /*
1106  * Throw out any user windows in the register file.
1107  * Used by setregs (exec) to clean out old user.
1108  * Used by sigcleanup to remove extraneous windows when returning from a
1109  * signal.
1110  */
1111 








1112         ENTRY_NP(trash_user_windows)
1113         rdpr    %otherwin, %g1
1114         brz     %g1, 3f                 ! no user windows?
1115         ldn     [THREAD_REG + T_STACK], %g5
1116 
1117         !
1118         ! There are old user windows in the register file. We disable ints
1119         ! and increment cansave so that we don't overflow on these windows.
1120         ! Also, this sets up a nice underflow when first returning to the
1121         ! new user.
1122         !
1123         rdpr    %pstate, %g2
1124         wrpr    %g2, PSTATE_IE, %pstate
1125         rdpr    %cansave, %g3
1126         rdpr    %otherwin, %g1          ! re-read in case of interrupt
1127         add     %g3, %g1, %g3
1128         wrpr    %g0, 0, %otherwin
1129         wrpr    %g0, %g3, %cansave
1130         wrpr    %g0, %g2, %pstate
1131 3:
1132         retl
1133         clr     [%g5 + MPCB_WBCNT]       ! zero window buffer cnt
1134         SET_SIZE(trash_user_windows)
1135 
1136 


1137 /*
1138  * Setup g7 via the CPU data structure.
1139  */

1140 






1141         ENTRY_NP(set_tbr)
1142         retl
1143         ta      72              ! no tbr, stop simulation
1144         SET_SIZE(set_tbr)
1145 

1146 

















1147 #define PTL1_SAVE_WINDOW(RP)                                            \
1148         stxa    %l0, [RP + RW64_LOCAL + (0 * RW64_LOCAL_INCR)] %asi;    \
1149         stxa    %l1, [RP + RW64_LOCAL + (1 * RW64_LOCAL_INCR)] %asi;    \
1150         stxa    %l2, [RP + RW64_LOCAL + (2 * RW64_LOCAL_INCR)] %asi;    \
1151         stxa    %l3, [RP + RW64_LOCAL + (3 * RW64_LOCAL_INCR)] %asi;    \
1152         stxa    %l4, [RP + RW64_LOCAL + (4 * RW64_LOCAL_INCR)] %asi;    \
1153         stxa    %l5, [RP + RW64_LOCAL + (5 * RW64_LOCAL_INCR)] %asi;    \
1154         stxa    %l6, [RP + RW64_LOCAL + (6 * RW64_LOCAL_INCR)] %asi;    \
1155         stxa    %l7, [RP + RW64_LOCAL + (7 * RW64_LOCAL_INCR)] %asi;    \
1156         stxa    %i0, [RP + RW64_IN + (0 * RW64_IN_INCR)] %asi;          \
1157         stxa    %i1, [RP + RW64_IN + (1 * RW64_IN_INCR)] %asi;          \
1158         stxa    %i2, [RP + RW64_IN + (2 * RW64_IN_INCR)] %asi;          \
1159         stxa    %i3, [RP + RW64_IN + (3 * RW64_IN_INCR)] %asi;          \
1160         stxa    %i4, [RP + RW64_IN + (4 * RW64_IN_INCR)] %asi;          \
1161         stxa    %i5, [RP + RW64_IN + (5 * RW64_IN_INCR)] %asi;          \
1162         stxa    %i6, [RP + RW64_IN + (6 * RW64_IN_INCR)] %asi;          \
1163         stxa    %i7, [RP + RW64_IN + (7 * RW64_IN_INCR)] %asi
1164 #define PTL1_NEXT_WINDOW(scr)   \
1165         add     scr, RWIN64SIZE, scr
1166 


1368         CPU_ADDR(%l0, %l1)                      ! %l0 = cpu[cpuid]
1369         add     %l0, CPU_PTL1, %l1              ! %l1 = &CPU->mcpu.ptl1_state
1370         !
1371         ! prepare to call panic()
1372         !
1373         ldn     [%l0 + CPU_THREAD], THREAD_REG  ! restore %g7
1374         ldn     [%l1 + PTL1_STKTOP], %l2        ! %sp = ptl1_stktop
1375         sub     %l2, SA(MINFRAME) + STACK_BIAS, %sp
1376         clr     %fp                             ! no frame below this window
1377         clr     %i7
1378         !
1379         ! enable limited interrupts
1380         !
1381         wrpr    %g0, CLOCK_LEVEL, %pil
1382         wrpr    %g0, PSTATE_KERN, %pstate
1383         !
1384         ba,pt   %xcc, ptl1_panic_handler
1385           mov   %l1, %o0
1386         /*NOTREACHED*/
1387         SET_SIZE(ptl1_panic)

1388 
1389 #ifdef  PTL1_PANIC_DEBUG








1390 







1391         ENTRY_NP(ptl1_recurse)
1392         save    %sp, -SA(MINFRAME), %sp
1393 
1394         set     ptl1_recurse_call, %o7
1395         cmp     %o7, %i7                        ! if ptl1_recurse is called
1396         be,pt  %icc, 0f                         ! by itself, then skip
1397           nop                                   ! register initialization
1398 
1399         /* 
1400          * Initialize Out Registers to Known Values 
1401          */
1402         set     0x01000, %l0                    ! %i0 is the ...
1403                                                 ! recursion_depth_count
1404         sub     %i0, 1, %o0;
1405         sub     %i1, 1, %o1;
1406         add     %l0, %o0, %o2;
1407         add     %l0, %o2, %o3;
1408         add     %l0, %o3, %o4;
1409         add     %l0, %o4, %o5;
1410         ba,a    1f


1435 
1436         brz,pn %i1, ptl1_recurse_trap           ! if trpp_count == 0) {
1437           nop                                   !    trap to ptl1_panic
1438                                                 !                       
1439         brz,pn %i0, ptl1_recure_exit            ! if(depth_count == 0) {
1440           nop                                   !    skip recursive call
1441                                                 ! }
1442 ptl1_recurse_call:
1443         call    ptl1_recurse
1444           nop
1445 
1446 ptl1_recure_exit:
1447         ret
1448         restore
1449 
1450 ptl1_recurse_trap:
1451         ta      PTL1_DEBUG_TRAP;                ! Trap Always to ptl1_panic()
1452           nop                                   ! NOTREACHED 
1453         SET_SIZE(ptl1_recurse)
1454 










1455         /*
1456          * Asm function to handle a cross trap to call ptl1_panic()
1457          */
1458         ENTRY_NP(ptl1_panic_xt)
1459         ba      ptl1_panic
1460           mov   PTL1_BAD_DEBUG, %g1
1461         SET_SIZE(ptl1_panic_xt)
1462 


1463 #endif  /* PTL1_PANIC_DEBUG */
1464 
1465 #ifdef  TRAPTRACE

1466 







1467         ENTRY_NP(trace_ptr_panic)
1468         !
1469         ! freeze the trap trace to disable the assertions.  Otherwise,
1470         ! ptl1_panic is likely to be repeatedly called from there.
1471         ! %g2 and %g3 are used as scratch registers in ptl1_panic.
1472         !
1473         mov     1, %g3
1474         sethi   %hi(trap_freeze), %g2
1475         st      %g3, [%g2 + %lo(trap_freeze)]
1476         !
1477         ! %g1 contains the %pc address where an assertion was failed.
1478         ! save it in trap_freeze_pc for a debugging hint if there is
1479         ! no value saved in it.
1480         !
1481         set     trap_freeze_pc, %g2
1482         casn    [%g2], %g0, %g1
1483 
1484         ba      ptl1_panic
1485         mov     PTL1_BAD_TRACE_PTR, %g1
1486         SET_SIZE(trace_ptr_panic)
1487 

1488 #endif  /* TRAPTRACE */
1489 
1490 /*
1491  * The interface for a 32-bit client program that takes over the TBA
1492  * calling the 64-bit romvec OBP.
1493  */
1494 









1495         ENTRY(client_handler)
1496         save    %sp, -SA64(MINFRAME64), %sp     ! 32 bit frame, 64 bit sized
1497         sethi   %hi(tba_taken_over), %l2
1498         ld      [%l2+%lo(tba_taken_over)], %l3
1499         brz     %l3, 1f                         ! is the tba_taken_over = 1 ?
1500         rdpr    %wstate, %l5                    ! save %wstate
1501         andn    %l5, WSTATE_MASK, %l6
1502         wrpr    %l6, WSTATE_KMIX, %wstate
1503 1:      mov     %i1, %o0
1504 1:      rdpr    %pstate, %l4                    ! Get the present pstate value
1505         andn    %l4, PSTATE_AM, %l6
1506         wrpr    %l6, 0, %pstate                 ! Set PSTATE_AM = 0
1507         jmpl    %i0, %o7                        ! Call cif handler
1508         nop
1509         wrpr    %l4, 0, %pstate                 ! restore pstate
1510         brz     %l3, 1f                         ! is the tba_taken_over = 1
1511           nop
1512         wrpr    %g0, %l5, %wstate               ! restore wstate
1513 1:      ret                                     ! Return result ...
1514         restore %o0, %g0, %o0                   ! delay; result in %o0
1515         SET_SIZE(client_handler)
1516 











1517         .seg    ".text"
1518 bad_hcall_error:
1519         .asciz  "hypervisor call 0x%x returned an unexpected error %d"
1520 
1521         /*
1522          * panic_bad_hcall is called when a hcall returns
1523          * unexpected error
1524          * %o0 error number
1525          * %o1 hcall number
1526          */
1527 
1528         ENTRY(panic_bad_hcall)
1529         mov     %o0, %o2
1530         sethi   %hi(bad_hcall_error), %o0
1531         or      %o0, %lo(bad_hcall_error), %o0
1532         mov     %o7, %o3
1533         call    panic
1534         mov     %o3, %o7
1535         SET_SIZE(panic_bad_hcall)
1536