Subject: Re: m88k code donation
To: None <port-m88k@netbsd.org>
From: Toru Nishimura <locore32@gaea.ocn.ne.jp>
List: port-m88k
Date: 10/23/2003 14:03:41
Here is the code fragment excerpt demonstration for persons familiar
with NetBSD kernel.

- locore.s -
ENTRY(XCPT)
        PSR: supervisor mode, FP has stopped and inhibited to use,
        interrupts disabled, shadow registers frozen.
        EPSR: contain PSR upon exception taken.
        SSBR: contain SSR upon exception taken.
        SXIP, SNIP, SFIP: contain values upon exception taken.
        FIP: exception vector address
        NIP, XIP: V bits are cleared, enforcing them noop
        SR0,1,2,3 usage:
            SR0 - curpcb
            SR1 - cpu_number()
            SR2 - scratch register
            SR3 - scratch register

        # take kernel stack pointer.
        # if (USERMODE(EPSR))
        #    ksp := tf := curpcb + USPACE - sizeof(trapframe)
        # else  
        #    ksp := tf := ksp - sizeof(trapframe)
        stcr    r1,SR2                  # yield r1
        ldcr    r1,EPSR
        bb1.n   31,r1,1f                # if (PSR_SUPERVISOR_MODE)
        stcr    r31,SR3                 # !delay slot! - save r31
        ldcr    r31,SR0
        addu    r31,r31,USPACE          # r31 = curpcb + USPACE
1:      subu    r31,r31,TF_SIZ          # r31 -= sizeof(trapframe)
        ldcr    r1,SR2                  # restore r1
                
        # save all the values in trapframe. 
        st.d    r0,r31,TF_REG0
        st.d    r2,r31,TF_REG2
        st.d    r4,r31,TF_REG4

- trap.c -
trap(type)
        int type;
{
        struct proc *p = curproc;
        struct trapframe *tf = p->p_md.md_tf;
        u_quad_t sticks;
        int sig;
        unsigned ucode;

        uvmexp.traps++;
        sticks = USERMODE(tf) ? p->p_sticks : 0;
        switch (type) {
        default:
        dopanic:
                if (type < sizeof(typename)/sizeof(char *))
                        printf("%s in %s mode", typename[type],
                                USERMODE(tf) ? "user" : "kernel");
#ifdef DDB
        /*
                go DDB session
        */
#else
        /*
                dump registers and dump top of stack contents
                halt
        */
#endif
        
        case T_INSNACCESS:
                if (USERMODE(tf))
                        goto pagefault;
                printf("kernel mode insn access fault");
                goto dopanic;

        case T_DATAACCESS:
                if (USERMODE(tf))
                        goto pagefault;
                /* kernel got data access fault in user address space */
                if (curpcb->pcb_onfault != 0)
                        goto bailout;
        /*
                pick fault address from tf->dma0 register
                tf->dmt0 & DMT_DAS shows in which space the address belongs to
                if the fault address was in user space
                        goto pagefault;
                analyse CMMU PFSR, consult uvm_fault() to solve.

                PFSR = 0;
        */
                tf->sfip = tf->snip | NIP_V;
                tf->snip = 0;
                tf->dmt0 = 0;
                break;

        pagefault: /* user mode insn or data access fault */
        /*
                analyse CMMU PFSR, consult uvm_fault() to solve.
                PFSR = 0;
        */

Toru Nishimura/ALKYL Technology