support.S revision 101955
180709Sjake/*- 280709Sjake * Copyright (c) 2001 Jake Burkholder. 380709Sjake * All rights reserved. 480709Sjake * 580709Sjake * Redistribution and use in source and binary forms, with or without 680709Sjake * modification, are permitted provided that the following conditions 780709Sjake * are met: 880709Sjake * 1. Redistributions of source code must retain the above copyright 980709Sjake * notice, this list of conditions and the following disclaimer. 1080709Sjake * 2. Redistributions in binary form must reproduce the above copyright 1180709Sjake * notice, this list of conditions and the following disclaimer in the 1280709Sjake * documentation and/or other materials provided with the distribution. 1380709Sjake * 1481337Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1580709Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1680709Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1781337Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1880709Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1980709Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2080709Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2180709Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2280709Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2380709Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2480709Sjake * SUCH DAMAGE. 2580709Sjake * 2680709Sjake * $FreeBSD: head/sys/sparc64/sparc64/support.S 101955 2002-08-16 00:57:37Z jake $ 2780709Sjake */ 2880709Sjake 2980709Sjake#include <machine/asi.h> 3080709Sjake#include <machine/asmacros.h> 3182909Sjake#include <machine/ktr.h> 3282909Sjake#include <machine/pstate.h> 3380709Sjake 3480709Sjake#include "assym.s" 3580709Sjake 3688641Sjake .register %g2, #ignore 3788641Sjake .register %g3, #ignore 3888641Sjake .register %g6, #ignore 3988641Sjake 4084193Sjake#define E /* empty */ 4180709Sjake 4284193Sjake/* 4384193Sjake * Generate load and store instructions for the corresponding width and asi 4484193Sjake * (or not). Note that we want to evaluate the macro args before 4584193Sjake * concatenating, so that E really turns into nothing. 4684193Sjake */ 4780709Sjake#define _LD(w, a) ld ## w ## a 4880709Sjake#define _ST(w, a) st ## w ## a 4980709Sjake 5080709Sjake#define LD(w, a) _LD(w, a) 5180709Sjake#define ST(w, a) _ST(w, a) 5280709Sjake 5384193Sjake/* 5484193Sjake * Common code for copy routines. 5584193Sjake * 5684193Sjake * We use large macros to generate functions for each of the copy routines. 5784193Sjake * This allows the load and store instructions to be generated for the right 5884193Sjake * operation, asi or not. It is possible to write an asi independent function 5984193Sjake * but this would require 2 expensive wrs in the main loop to switch %asi. 6084193Sjake * It would also screw up profiling (if we ever get it), but may save some I$. 6184193Sjake * We assume that either one of dasi and sasi is empty, or that they are both 6284193Sjake * the same (empty or non-empty). It is up to the caller to set %asi. 6384193Sjake */ 6484193Sjake 6584193Sjake/* 6684193Sjake * ASI independent implementation of copystr(9). 6784193Sjake * Used to implement copyinstr() and copystr(). 6884193Sjake * 6984193Sjake * Return value is in %g1. 7084193Sjake */ 7184193Sjake#define _COPYSTR(src, dst, len, done, sa, sasi, da, dasi) \ 7284193Sjake brz len, 4f ; \ 7384193Sjake mov src, %g2 ; \ 7484193Sjake1: deccc 1, len ; \ 7584193Sjake bl,a,pn %xcc, 3f ; \ 7684193Sjake nop ; \ 7784193Sjake LD(ub, sa) [src] sasi, %g1 ; \ 7884193Sjake ST(b, da) %g1, [dst] dasi ; \ 7984193Sjake brz,pn %g1, 3f ; \ 8084193Sjake inc src ; \ 8184193Sjake b %xcc, 1b ; \ 8280709Sjake inc dst ; \ 8384193Sjake2: mov ENAMETOOLONG, %g1 ; \ 8484193Sjake3: sub src, %g2, %g2 ; \ 8584193Sjake brnz,a done, 4f ; \ 8684193Sjake stx %g2, [done] ; \ 8784193Sjake4: 8880709Sjake 8984193Sjake/* 9084193Sjake * ASI independent implementation of memset(3). 9186520Sjake * Used to implement bzero(), memset() and aszero(). 9284193Sjake * 9384193Sjake * If the pattern is non-zero, duplicate it to fill 64 bits. 9484193Sjake * Store bytes until dst is 8-byte aligned, then store 8 bytes. 9584193Sjake * It has yet to be determined how much unrolling is beneficial. 9684193Sjake * Could also read and compare before writing to minimize snoop traffic. 9784193Sjake * 9884193Sjake * XXX bzero() should be implemented as 9984193Sjake * #define bzero(dst, len) (void)memset((dst), 0, (len)) 10084193Sjake * if at all. 10184193Sjake */ 10284193Sjake#define _MEMSET(dst, pat, len, da, dasi) \ 10384193Sjake brlez,pn len, 5f ; \ 10484193Sjake and pat, 0xff, pat ; \ 10584193Sjake brz,pt pat, 1f ; \ 10684193Sjake sllx pat, 8, %g1 ; \ 10784193Sjake or pat, %g1, pat ; \ 10884193Sjake sllx pat, 16, %g1 ; \ 10984193Sjake or pat, %g1, pat ; \ 11084193Sjake sllx pat, 32, %g1 ; \ 11184193Sjake or pat, %g1, pat ; \ 112100841Sjake _ALIGN_TEXT ; \ 11384193Sjake1: deccc 1, len ; \ 11484193Sjake bl,pn %xcc, 5f ; \ 11584193Sjake btst 7, dst ; \ 11684193Sjake bz,a,pt %xcc, 2f ; \ 11784193Sjake inc 1, len ; \ 11884193Sjake ST(b, da) pat, [dst] dasi ; \ 11984193Sjake b %xcc, 1b ; \ 12084193Sjake inc dst ; \ 121100841Sjake _ALIGN_TEXT ; \ 12284193Sjake2: deccc 32, len ; \ 12384193Sjake bl,a,pn %xcc, 3f ; \ 12484193Sjake inc 32, len ; \ 12584193Sjake ST(x, da) pat, [dst] dasi ; \ 12684193Sjake ST(x, da) pat, [dst + 8] dasi ; \ 12784193Sjake ST(x, da) pat, [dst + 16] dasi ; \ 12884193Sjake ST(x, da) pat, [dst + 24] dasi ; \ 12984193Sjake b %xcc, 2b ; \ 13084193Sjake inc 32, dst ; \ 131100841Sjake _ALIGN_TEXT ; \ 13284193Sjake3: deccc 8, len ; \ 13384193Sjake bl,a,pn %xcc, 4f ; \ 13484193Sjake inc 8, len ; \ 13584193Sjake ST(x, da) pat, [dst] dasi ; \ 13684193Sjake b %xcc, 3b ; \ 13784193Sjake inc 8, dst ; \ 138100841Sjake _ALIGN_TEXT ; \ 13984193Sjake4: deccc 1, len ; \ 14084193Sjake bl,a,pn %xcc, 5f ; \ 14184193Sjake nop ; \ 14284193Sjake ST(b, da) pat, [dst] dasi ; \ 14384193Sjake b %xcc, 4b ; \ 14484193Sjake inc 1, dst ; \ 14584193Sjake5: 14680709Sjake 14784193Sjake/* 14884193Sjake * ASI independent implementation of memcpy(3). 14986520Sjake * Used to implement bcopy(), copyin(), copyout(), memcpy(), ascopy(), 15086520Sjake * ascopyfrom() and ascopyto(). 15184193Sjake * 15284193Sjake * Transfer bytes until dst is 8-byte aligned. If src is then also 8 byte 15384193Sjake * aligned, transfer 8 bytes, otherwise finish with bytes. The unaligned 15484193Sjake * case could be optimized, but it is expected that this is the uncommon 15584193Sjake * case and of questionable value. The code to do so is also rather large 15688641Sjake * and ugly. It has yet to be determined how much unrolling is beneficial. 15784193Sjake * 15884193Sjake * XXX bcopy() must also check for overlap. This is stupid. 15984193Sjake * XXX bcopy() should be implemented as 16084193Sjake * #define bcopy(src, dst, len) (void)memcpy((dst), (src), (len)) 16184193Sjake * if at all. 16284193Sjake */ 16384193Sjake#define _MEMCPY(dst, src, len, da, dasi, sa, sasi) \ 16484193Sjake1: deccc 1, len ; \ 16584193Sjake bl,pn %xcc, 6f ; \ 16684193Sjake btst 7, dst ; \ 16784193Sjake bz,a,pt %xcc, 2f ; \ 16884193Sjake inc 1, len ; \ 16984193Sjake LD(ub, sa) [src] sasi, %g1 ; \ 17080709Sjake ST(b, da) %g1, [dst] dasi ; \ 17184193Sjake inc 1, src ; \ 17284193Sjake b %xcc, 1b ; \ 17384193Sjake inc 1, dst ; \ 174100841Sjake _ALIGN_TEXT ; \ 17584193Sjake2: btst 7, src ; \ 17684193Sjake bz,a,pt %xcc, 3f ; \ 17784193Sjake nop ; \ 17884193Sjake b,a %xcc, 5f ; \ 179100841Sjake _ALIGN_TEXT ; \ 18084193Sjake3: deccc 32, len ; \ 18184193Sjake bl,a,pn %xcc, 4f ; \ 18284193Sjake inc 32, len ; \ 18384193Sjake LD(x, sa) [src] sasi, %g1 ; \ 18484193Sjake LD(x, sa) [src + 8] sasi, %g2 ; \ 18584193Sjake LD(x, sa) [src + 16] sasi, %g3 ; \ 18684193Sjake LD(x, sa) [src + 24] sasi, %g4 ; \ 18784193Sjake ST(x, da) %g1, [dst] dasi ; \ 18884193Sjake ST(x, da) %g2, [dst + 8] dasi ; \ 18984193Sjake ST(x, da) %g3, [dst + 16] dasi ; \ 19084193Sjake ST(x, da) %g4, [dst + 24] dasi ; \ 19184193Sjake inc 32, src ; \ 19284193Sjake b %xcc, 3b ; \ 19384193Sjake inc 32, dst ; \ 194100841Sjake _ALIGN_TEXT ; \ 19584193Sjake4: deccc 8, len ; \ 19684193Sjake bl,a,pn %xcc, 5f ; \ 19784193Sjake inc 8, len ; \ 19884193Sjake LD(x, sa) [src] sasi, %g1 ; \ 19984193Sjake ST(x, da) %g1, [dst] dasi ; \ 20084193Sjake inc 8, src ; \ 20184193Sjake b %xcc, 4b ; \ 20284193Sjake inc 8, dst ; \ 203100841Sjake _ALIGN_TEXT ; \ 20484193Sjake5: deccc 1, len ; \ 20584193Sjake bl,a,pn %xcc, 6f ; \ 20684193Sjake nop ; \ 20784193Sjake LD(ub, sa) [src] sasi, %g1 ; \ 20884193Sjake ST(b, da) %g1, [dst] dasi ; \ 20980709Sjake inc src ; \ 21084193Sjake b %xcc, 5b ; \ 21180709Sjake inc dst ; \ 21284193Sjake6: 21380709Sjake 214101955Sjake/* 215101955Sjake * void ascopy(u_long asi, vm_offset_t src, vm_offset_t dst, size_t len) 216101955Sjake */ 217101955SjakeENTRY(ascopy) 218101955Sjake wr %o0, 0, %asi 219101955Sjake _MEMCPY(%o2, %o1, %o3, a, %asi, a, %asi) 220101955Sjake retl 221101955Sjake nop 222101955SjakeEND(ascopy) 22380709Sjake 224101955Sjake/* 225101955Sjake * void ascopyfrom(u_long sasi, vm_offset_t src, caddr_t dst, size_t len) 226101955Sjake */ 227101955SjakeENTRY(ascopyfrom) 228101955Sjake wr %o0, 0, %asi 229101955Sjake _MEMCPY(%o2, %o1, %o3, E, E, a, %asi) 230101955Sjake retl 231101955Sjake nop 232101955SjakeEND(ascopyfrom) 23380709Sjake 234101955Sjake/* 235101955Sjake * void ascopyto(caddr_t src, u_long dasi, vm_offset_t dst, size_t len) 236101955Sjake */ 237101955SjakeENTRY(ascopyto) 238101955Sjake wr %o1, 0, %asi 239101955Sjake _MEMCPY(%o2, %o0, %o3, a, %asi, E, E) 240101955Sjake retl 241101955Sjake nop 242101955SjakeEND(ascopyto) 24380709Sjake 244101955Sjake/* 245101955Sjake * void aszero(u_long asi, vm_offset_t pa, size_t len) 246101955Sjake */ 247101955SjakeENTRY(aszero) 248101955Sjake wr %o0, 0, %asi 249101955Sjake _MEMSET(%o1, %g0, %o2, a, %asi) 250101955Sjake retl 251101955Sjake nop 252101955SjakeEND(aszero) 25380709Sjake 25480709Sjake/* 25584193Sjake * int bcmp(const void *b1, const void *b2, size_t len) 25680709Sjake */ 25780709SjakeENTRY(bcmp) 25880709Sjake brz,pn %o2, 2f 25980709Sjake clr %o3 26080709Sjake1: ldub [%o0 + %o3], %o4 26180709Sjake ldub [%o1 + %o3], %o5 26280709Sjake cmp %o4, %o5 26384193Sjake bne,pn %xcc, 2f 26480709Sjake inc %o3 26580709Sjake deccc %o2 26680709Sjake bne,pt %xcc, 1b 26780709Sjake nop 26880709Sjake2: retl 26980709Sjake mov %o2, %o0 27080709SjakeEND(bcmp) 27180709Sjake 27280709Sjake/* 27380709Sjake * void bcopy(const void *src, void *dst, size_t len) 27480709Sjake */ 27586520SjakeENTRY(bcopy) 27684193SjakeENTRY(ovbcopy) 27784193Sjake /* 27884193Sjake * Check for overlap, and copy backwards if so. 27984193Sjake */ 28084193Sjake sub %o1, %o0, %g1 28184193Sjake cmp %g1, %o2 28284193Sjake bgeu,a,pt %xcc, 3f 28384193Sjake nop 28484193Sjake 28584193Sjake /* 28684193Sjake * Copy backwards. 28784193Sjake */ 28884193Sjake add %o0, %o2, %o0 28984193Sjake add %o1, %o2, %o1 29084193Sjake1: deccc 1, %o2 29184193Sjake bl,a,pn %xcc, 2f 29284193Sjake nop 29384193Sjake dec 1, %o0 29484193Sjake ldub [%o0], %g1 29584193Sjake dec 1, %o1 29684193Sjake b %xcc, 1b 29784193Sjake stb %g1, [%o1] 29884193Sjake2: retl 29984193Sjake nop 30084193Sjake 30184193Sjake /* 30284193Sjake * Do the fast version. 30384193Sjake */ 30484193Sjake3: _MEMCPY(%o1, %o0, %o2, E, E, E, E) 30580709Sjake retl 30680709Sjake nop 30780709SjakeEND(bcopy) 30880709Sjake 30980709Sjake/* 31084193Sjake * void bzero(void *b, size_t len) 31180709Sjake */ 31284193SjakeENTRY(bzero) 31384193Sjake _MEMSET(%o0, %g0, %o1, E, E) 31480709Sjake retl 31580709Sjake nop 31684193SjakeEND(bzero) 31780709Sjake 31880709Sjake/* 319101955Sjake * int copystr(const void *src, void *dst, size_t len, size_t *done) 32080709Sjake */ 321101955SjakeENTRY(copystr) 322101955Sjake _COPYSTR(%o0, %o1, %o2, %o3, E, E, E, E) 32384193Sjake retl 324101955Sjake mov %g1, %o0 325101955SjakeEND(copystr) 32684193Sjake 32784193Sjake/* 32880709Sjake * void *memcpy(void *dst, const void *src, size_t len) 32980709Sjake */ 33080709SjakeENTRY(memcpy) 33184193Sjake mov %o0, %o3 33284193Sjake _MEMCPY(%o3, %o1, %o2, E, E, E, E) 33380709Sjake retl 33480709Sjake nop 33580709SjakeEND(memcpy) 33680709Sjake 33780709Sjake/* 33884193Sjake * void *memset(void *b, int c, size_t len) 33984193Sjake */ 34084193SjakeENTRY(memset) 34184193Sjake mov %o0, %o3 34284193Sjake _MEMSET(%o3, %o1, %o2, E, E) 34384193Sjake retl 34484193Sjake nop 34584193SjakeEND(memset) 34684193Sjake 347101955Sjake .globl copy_nofault_begin 348101955Sjakecopy_nofault_begin: 349101955Sjake nop 350101955Sjake 35184193Sjake/* 35280709Sjake * int copyin(const void *uaddr, void *kaddr, size_t len) 35380709Sjake */ 35480709SjakeENTRY(copyin) 35584193Sjake wr %g0, ASI_AIUP, %asi 35684193Sjake _MEMCPY(%o1, %o0, %o2, E, E, a, %asi) 35780709Sjake retl 35880709Sjake clr %o0 35980709SjakeEND(copyin) 36080709Sjake 36180709Sjake/* 36280709Sjake * int copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done) 36380709Sjake */ 36480709SjakeENTRY(copyinstr) 36584193Sjake wr %g0, ASI_AIUP, %asi 36684193Sjake _COPYSTR(%o0, %o1, %o2, %o3, a, %asi, E, E) 36780709Sjake retl 36884193Sjake mov %g1, %o0 36980709SjakeEND(copyinstr) 37080709Sjake 37180709Sjake/* 37280709Sjake * int copyout(const void *kaddr, void *uaddr, size_t len) 37380709Sjake */ 37480709SjakeENTRY(copyout) 37584193Sjake wr %g0, ASI_AIUP, %asi 37684193Sjake _MEMCPY(%o1, %o0, %o2, a, %asi, E, E) 37780709Sjake retl 37880709Sjake clr %o0 37980709SjakeEND(copyout) 38080709Sjake 381101955Sjake .globl copy_nofault_end 382101955Sjakecopy_nofault_end: 383101955Sjake nop 384101955Sjake 385101955SjakeENTRY(copy_fault) 38680709Sjake retl 38780709Sjake mov EFAULT, %o0 388101955SjakeEND(copy_fault) 38980709Sjake 390101955Sjake .globl fs_nofault_begin 391101955Sjakefs_nofault_begin: 392101955Sjake nop 39380709Sjake 39480709Sjake/* 395101955Sjake * Chatty aliases for fetch, store functions. 39680709Sjake */ 397101955Sjake .globl fubyte, fusword, fuword, subyte, susword, suword 398101955Sjake .set fubyte, fuword8 399101955Sjake .set fusword, fuword16 400101955Sjake .set fuword, fuword64 401101955Sjake .set subyte, suword8 402101955Sjake .set susword, suword16 403101955Sjake .set suword, suword64 40480709Sjake 40580709Sjake/* 406101955Sjake * int fuword8(const void *base) 40780709Sjake */ 408101955SjakeENTRY(fuword8) 409101955Sjake retl 410101955Sjake lduba [%o0] ASI_AIUP, %o0 411101955SjakeEND(fuword8) 41280709Sjake 41380709Sjake/* 414101955Sjake * int fuword16(const void *base) 41580709Sjake */ 41698511SjakeENTRY(fuword16) 417101955Sjake retl 418101955Sjake lduha [%o0] ASI_AIUP, %o0 41998511SjakeEND(fuword16) 42080709Sjake 42180709Sjake/* 42298511Sjake * int32_t fuword32(const void *base) 42397307Sdfr */ 42498511SjakeENTRY(fuword32) 425101955Sjake retl 426101955Sjake lduwa [%o0] ASI_AIUP, %o0 42798511SjakeEND(fuword32) 42898511Sjake 42998511Sjake/* 43098511Sjake * int64_t fuword64(const void *base) 43198511Sjake */ 43297307SdfrENTRY(fuword64) 433101955Sjake retl 434101955Sjake ldxa [%o0] ASI_AIUP, %o0 43597307SdfrEND(fuword64) 43697307Sdfr 43797307Sdfr/* 438101955Sjake * int suword8(const void *base, int word) 43980709Sjake */ 440101955SjakeENTRY(suword8) 441101955Sjake stba %o1, [%o0] ASI_AIUP 442101955Sjake retl 443101955Sjake clr %o0 444101955SjakeEND(suword8) 44580709Sjake 44680709Sjake/* 447101955Sjake * int suword16(const void *base, int word) 44880709Sjake */ 44998511SjakeENTRY(suword16) 450101955Sjake stha %o1, [%o0] ASI_AIUP 451101955Sjake retl 452101955Sjake clr %o0 45398511SjakeEND(suword16) 45480709Sjake 45597307Sdfr/* 45698511Sjake * int suword32(const void *base, int32_t word) 45797307Sdfr */ 45898511SjakeENTRY(suword32) 459101955Sjake stwa %o1, [%o0] ASI_AIUP 460101955Sjake retl 461101955Sjake clr %o0 46298511SjakeEND(suword32) 46398511Sjake 46498511Sjake/* 46598511Sjake * int suword64(const void *base, int64_t word) 46698511Sjake */ 46797307SdfrENTRY(suword64) 468101955Sjake stxa %o1, [%o0] ASI_AIUP 469101955Sjake retl 470101955Sjake clr %o0 47197307SdfrEND(suword64) 47297307Sdfr 473101955Sjake .globl fs_nofault_intr_begin 474101955Sjakefs_nofault_intr_begin: 475101955Sjake nop 476101955Sjake 477101955Sjake/* 478101955Sjake * int fuswintr(const void *base) 479101955Sjake */ 480101955SjakeENTRY(fuswintr) 48185238Sjake retl 482101955Sjake lduha [%o0] ASI_AIUP, %o0 483101955SjakeEND(fuswintr) 48485238Sjake 485101955Sjake/* 486101955Sjake * int suswintr(const void *base, int word) 487101955Sjake */ 488101955SjakeENTRY(suswintr) 489101955Sjake stha %o1, [%o0] ASI_AIUP 49080709Sjake retl 491101955Sjake clr %o0 492101955SjakeEND(suswintr) 49380709Sjake 494101955Sjake .globl fs_nofault_intr_end 495101955Sjakefs_nofault_intr_end: 496101955Sjake nop 497101955Sjake 498101955Sjake .globl fs_nofault_end 499101955Sjakefs_nofault_end: 500101955Sjake nop 501101955Sjake 502101955SjakeENTRY(fs_fault) 50385238Sjake retl 50485238Sjake mov -1, %o0 505101955SjakeEND(fsfault) 50685238Sjake 50780709SjakeENTRY(longjmp) 50880709Sjake set 1, %g3 50980709Sjake movrz %o1, %o1, %g3 51080709Sjake mov %o0, %g1 51188641Sjake ldx [%g1 + _JB_FP], %g2 51280709Sjake1: cmp %fp, %g2 51380709Sjake bl,a,pt %xcc, 1b 51480709Sjake restore 51580709Sjake bne,pn %xcc, 2f 51688641Sjake ldx [%g1 + _JB_SP], %o2 51780709Sjake cmp %o2, %sp 51880709Sjake blt,pn %xcc, 2f 51980709Sjake movge %xcc, %o2, %sp 52088641Sjake ldx [%g1 + _JB_PC], %o7 52188641Sjake retl 52280709Sjake mov %g3, %o0 52380709Sjake2: PANIC("longjmp botch", %l1) 52480709SjakeEND(longjmp) 52580709Sjake 52680709SjakeENTRY(setjmp) 52788641Sjake stx %sp, [%o0 + _JB_SP] 52888641Sjake stx %o7, [%o0 + _JB_PC] 52988641Sjake stx %fp, [%o0 + _JB_FP] 53080709Sjake retl 53180709Sjake clr %o0 53280709SjakeEND(setjmp) 53380709Sjake 53480709Sjake/* 53580709Sjake * void openfirmware(cell_t args[]) 53680709Sjake */ 53780709SjakeENTRY(openfirmware) 53884193Sjake save %sp, -CCFSZ, %sp 53986520Sjake SET(ofw_vec, %l7, %l6) 54081183Sjake ldx [%l6], %l6 54181386Sjake rdpr %pil, %l7 54284193Sjake wrpr %g0, PIL_TICK, %pil 54381183Sjake call %l6 54480709Sjake mov %i0, %o0 54581386Sjake wrpr %l7, 0, %pil 54684193Sjake ret 54784193Sjake restore %o0, %g0, %o0 54880709SjakeEND(openfirmware) 54986147Stmm 55086147Stmm/* 55186147Stmm * void ofw_exit(cell_t args[]) 55286147Stmm */ 55386147StmmENTRY(openfirmware_exit) 55486147Stmm save %sp, -CCFSZ, %sp 55586147Stmm flushw 55686147Stmm wrpr %g0, PIL_TICK, %pil 55786520Sjake SET(ofw_tba, %l7, %l5) 55886147Stmm ldx [%l5], %l5 55986147Stmm wrpr %l5, 0, %tba ! restore the ofw trap table 56086520Sjake SET(ofw_vec, %l7, %l6) 56186147Stmm ldx [%l6], %l6 56286520Sjake SET(kstack0 + KSTACK_PAGES * PAGE_SIZE - PCB_SIZEOF, %l7, %l0) 56386147Stmm sub %l0, SPOFF, %fp ! setup a stack in a locked page 56486147Stmm sub %l0, SPOFF + CCFSZ, %sp 56586147Stmm mov AA_DMMU_PCXR, %l3 ! set context 0 56686147Stmm stxa %g0, [%l3] ASI_DMMU 56788641Sjake membar #Sync 56886147Stmm wrpr %g0, 0, %tl ! force trap level 0 56986147Stmm call %l6 57086147Stmm mov %i0, %o0 57186147Stmm ! never to return 57286147StmmEND(openfirmware_exit) 573100841Sjake 574100910Sjake#ifdef GPROF 575100841Sjake 576100910SjakeENTRY(user) 577100910Sjake nop 578100910Sjake 579100910SjakeENTRY(btrap) 580100910Sjake nop 581100910Sjake 582100910SjakeENTRY(etrap) 583100910Sjake nop 584100910Sjake 585100910SjakeENTRY(bintr) 586100910Sjake nop 587100910Sjake 588100910SjakeENTRY(eintr) 589100910Sjake nop 590100910Sjake 591100910Sjake 592100841Sjake/* 593100841Sjake * XXX including sys/gmon.h in genassym.c is not possible due to uintfptr_t 594100841Sjake * badness. 595100841Sjake */ 596100841Sjake#define GM_STATE 0x0 597100841Sjake#define GMON_PROF_OFF 3 598100841Sjake#define GMON_PROF_HIRES 4 599100841Sjake 600100910Sjake .globl _mcount 601100910Sjake .set _mcount, __cyg_profile_func_enter 602100910Sjake 603100910SjakeENTRY(__cyg_profile_func_enter) 604100841Sjake SET(_gmonparam, %o3, %o2) 605100841Sjake lduw [%o2 + GM_STATE], %o3 606100841Sjake cmp %o3, GMON_PROF_OFF 607100841Sjake be,a,pn %icc, 1f 608100841Sjake nop 609100841Sjake SET(mcount, %o3, %o2) 610100841Sjake jmpl %o2, %g0 611100841Sjake nop 612100841Sjake1: retl 613100841Sjake nop 614100910SjakeEND(__cyg_profile_func_enter) 615100841Sjake 616100910Sjake#ifdef GUPROF 617100910Sjake 618100910SjakeENTRY(__cyg_profile_func_exit) 619100841Sjake SET(_gmonparam, %o3, %o2) 620100841Sjake lduw [%o2 + GM_STATE], %o3 621100841Sjake cmp %o3, GMON_PROF_HIRES 622100841Sjake be,a,pn %icc, 1f 623100841Sjake nop 624100841Sjake SET(mexitcount, %o3, %o2) 625100841Sjake jmpl %o2, %g0 626100841Sjake nop 627100841Sjake1: retl 628100841Sjake nop 629100910SjakeEND(__cyg_profile_func_exit) 630100841Sjake 631100910Sjake#endif /* GUPROF */ 632100841Sjake 633100910Sjake#endif /* GPROF */ 634