root/tests/kernel/arch/hppa/h_execregs.S
/*      $NetBSD: h_execregs.S,v 1.2 2025/02/28 16:08:19 riastradh Exp $ */

/*-
 * Copyright (c) 2025 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#define _LOCORE

#include <sys/syscall.h>

#include <machine/asm.h>
#include <machine/vmparam.h>

#include "execregs.h"

_ENTRY(execregs_start)
        .callinfo frame=(NEXECREGS*4), calls
        .entry

        ldo     (NEXECREGS*4)(%sp), %sp         /* space for NEXECREGS */
        stw     %t1, (4*(0 - NEXECREGS))(%sp)   /* order matches execregs.h */
        stw     %t2, (4*(1 - NEXECREGS))(%sp)
        /* sp: stack pointer */
        stw     %t3, (4*(2 - NEXECREGS))(%sp)
        /* cr17/iisq_head: privileged */
        /* cr17/iisq_tail: privileged */
        /* cr18/iioq_head: privileged */
        /* cr18/iioq_tail: privileged */
        /* cr15/eiem: privileged */
        /* cr22/ipsw: privileged */
        /* sr3: privileged(?) */
        /* cr8/pidr1: privileged */
        /* cr20/isr: privileged */
        /* cr21/ior: privileged */
        /* cr19/iir: privileged */
        /* flags: N/A(?) */
        stw     %sar, (4*(3 - NEXECREGS))(%sp)
        stw     %r1, (4*(4 - NEXECREGS))(%sp)
        stw     %rp, (4*(5 - NEXECREGS))(%sp)
        /* r3: frame pointer (set to initial stack pointer) */
        stw     %r4, (4*(6 - NEXECREGS))(%sp)
        stw     %r5, (4*(7 - NEXECREGS))(%sp)
        stw     %r6, (4*(8 - NEXECREGS))(%sp)
        stw     %r7, (4*(9 - NEXECREGS))(%sp)
        stw     %r8, (4*(10 - NEXECREGS))(%sp)
        stw     %r9, (4*(11 - NEXECREGS))(%sp)
        stw     %r10, (4*(12 - NEXECREGS))(%sp)
        stw     %r11, (4*(13 - NEXECREGS))(%sp)
        stw     %r12, (4*(14 - NEXECREGS))(%sp)
        stw     %r13, (4*(15 - NEXECREGS))(%sp)
        stw     %r14, (4*(16 - NEXECREGS))(%sp)
        stw     %r15, (4*(17 - NEXECREGS))(%sp)
        stw     %r16, (4*(18 - NEXECREGS))(%sp)
        stw     %r17, (4*(19 - NEXECREGS))(%sp)
        stw     %r18, (4*(20 - NEXECREGS))(%sp)
        stw     %t4, (4*(21 - NEXECREGS))(%sp)
        stw     %arg3, (4*(22 - NEXECREGS))(%sp)
        stw     %arg2, (4*(23 - NEXECREGS))(%sp)
        stw     %arg1, (4*(24 - NEXECREGS))(%sp)
        /* arg0: ps_strings */
        stw     %dp, (4*(25 - NEXECREGS))(%sp)
        stw     %ret0, (4*(26 - NEXECREGS))(%sp)
        stw     %ret1, (4*(27 - NEXECREGS))(%sp)
        stw     %r31, (4*(28 - NEXECREGS))(%sp)
        /* sr0-sr7: space registers initialized by kernel */
        /* cr9/pidr2: privileged */
        /* cr12/pidr3: privileged */
        /* cr13/pidr4: privileged */
        /* cr0/rctr: privileged */
        /* cr10/ccr: privileged */
        /* cr23/eirr: privileged */
        /* cr24: privileged */
        /* cr25/vtop: privileged */
        /* cr26: ??? */
        stw     %cr27, (4*(29 - NEXECREGS))(%sp)
        stw     %cr28, (4*(30 - NEXECREGS))(%sp)
        /* cr30/fpregs: privileged */
        /* cr31: privileged */

        addc    %t1, %r0, %r0   /* t1 := PSW[C/B]{0} */
        zdep    %t1, 23, 8, %t1 /* t1 := PSW */
        stw     %t1, (4*(31 - NEXECREGS))(%sp)

        /* store the fp registers */
        ldo     (4*(32 - NEXECREGS))(%sp), %t1
        fstd,ma %fr0, 8(%t1)
        fstd,ma %fr1, 8(%t1)
        fstd,ma %fr2, 8(%t1)
        fstd,ma %fr3, 8(%t1)
        fstd,ma %fr4, 8(%t1)
        fstd,ma %fr5, 8(%t1)
        fstd,ma %fr6, 8(%t1)
        fstd,ma %fr7, 8(%t1)
        fstd,ma %fr8, 8(%t1)
        fstd,ma %fr9, 8(%t1)
        fstd,ma %fr10, 8(%t1)
        fstd,ma %fr11, 8(%t1)
        fstd,ma %fr12, 8(%t1)
        fstd,ma %fr13, 8(%t1)
        fstd,ma %fr14, 8(%t1)
        fstd,ma %fr15, 8(%t1)
        fstd,ma %fr16, 8(%t1)
        fstd,ma %fr17, 8(%t1)
        fstd,ma %fr18, 8(%t1)
        fstd,ma %fr19, 8(%t1)
        fstd,ma %fr20, 8(%t1)
        fstd,ma %fr21, 8(%t1)
        fstd,ma %fr22, 8(%t1)
        fstd,ma %fr23, 8(%t1)
        fstd,ma %fr24, 8(%t1)
        fstd,ma %fr25, 8(%t1)
        fstd,ma %fr26, 8(%t1)
        fstd,ma %fr27, 8(%t1)
        fstd,ma %fr28, 8(%t1)
        fstd,ma %fr29, 8(%t1)
        fstd,ma %fr30, 8(%t1)
        fstd    %fr31, 0(%t1)

        /* call write(STDOUT_FILENO, regs, sizeof(regs)) */
        ldi     1, %arg0                        /* arg0 := STDOUT_FILENO */
        ldo     -(4*NEXECREGS)(%sp), %arg1      /* arg1 := regs */
        ldi     (4*NEXECREGS), %arg2            /* arg2 := sizeof(regs) */
        ldil    L%SYSCALLGATE, %r1
        ble     4(%sr2, %r1)
         ldi    SYS_write, %t1

        comb,<>,n       %r0, %t1, 2f            /* bail if write failed */
        ldi             (4*NEXECREGS), %t1      /* bail if wrong # bytes */
        comb,<>,n       %ret0, %t1, 2f

        /* call exit(0) */
        ldi     0, %arg0
1:      ldil    L%SYSCALLGATE, %r1
        ble     4(%sr2, %r1)
         ldi    SYS_exit, %t1
        break   0, 0                            /* paranoia */

2:      /* call exit(127) */
        b       1b
         ldi    127, %arg0
EXIT(execregs_start)

/* main stub to simplify linking */
LEAF_ENTRY(main)
        break   0, 0                            /* paranoia */
EXIT(main)