xref: /nrf52832-nimble/rt-thread/libcpu/ppc/ppc405/context_gcc.S (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero#include "context.h"
2*10465441SEvalZero#define SPRG0	0x110	/* Special Purpose Register General 0 */
3*10465441SEvalZero#define SPRG1	0x111	/* Special Purpose Register General 1 */
4*10465441SEvalZero
5*10465441SEvalZero    .globl rt_hw_interrupt_disable
6*10465441SEvalZero    .globl rt_hw_interrupt_enable
7*10465441SEvalZero    .globl rt_hw_context_switch
8*10465441SEvalZero    .globl rt_hw_context_switch_to
9*10465441SEvalZero    .globl rt_hw_context_switch_interrupt
10*10465441SEvalZero    .globl rt_hw_systemcall_entry
11*10465441SEvalZero
12*10465441SEvalZero/*
13*10465441SEvalZero * rt_base_t rt_hw_interrupt_disable();
14*10465441SEvalZero * return the interrupt status and disable interrupt
15*10465441SEvalZero */
16*10465441SEvalZero#if 0
17*10465441SEvalZerort_hw_interrupt_disable:
18*10465441SEvalZero    mfmsr   r3          /* Disable interrupts */
19*10465441SEvalZero    li      r4,0
20*10465441SEvalZero    ori     r4,r4,MSR_EE
21*10465441SEvalZero    andc    r4,r4,r3
22*10465441SEvalZero    SYNC                /* Some chip revs need this... */
23*10465441SEvalZero    mtmsr   r4
24*10465441SEvalZero    SYNC
25*10465441SEvalZero    blr
26*10465441SEvalZero#else
27*10465441SEvalZerort_hw_interrupt_disable:
28*10465441SEvalZero    addis  r4, r0, 0xFFFD
29*10465441SEvalZero    ori    r4, r4, 0x7FFF
30*10465441SEvalZero    mfmsr  r3
31*10465441SEvalZero    and    r4, r4, 3                                      /* Clear bits 14 and 16, corresponding to...   */
32*10465441SEvalZero    mtmsr  r4                                            /* ...critical and non-critical interrupts     */
33*10465441SEvalZero    blr
34*10465441SEvalZero#endif
35*10465441SEvalZero
36*10465441SEvalZero/*
37*10465441SEvalZero * void rt_hw_interrupt_enable(rt_base_t level);
38*10465441SEvalZero * restore interrupt
39*10465441SEvalZero */
40*10465441SEvalZerort_hw_interrupt_enable:
41*10465441SEvalZero    mtmsr   r3
42*10465441SEvalZero    SYNC
43*10465441SEvalZero    blr
44*10465441SEvalZero
45*10465441SEvalZero/*
46*10465441SEvalZero * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
47*10465441SEvalZero * r3 --> from
48*10465441SEvalZero * r4 --> to
49*10465441SEvalZero *
50*10465441SEvalZero * r1: stack pointer
51*10465441SEvalZero */
52*10465441SEvalZerort_hw_systemcall_entry:
53*10465441SEvalZero    mtspr   SPRG0,r3                            /* save r3 to SPRG0 */
54*10465441SEvalZero    mtspr   SPRG1,r4                            /* save r4 to SPRG1 */
55*10465441SEvalZero
56*10465441SEvalZero    lis     r3,rt_thread_switch_interrput_flag@h
57*10465441SEvalZero    ori     r3,r3,rt_thread_switch_interrput_flag@l
58*10465441SEvalZero    lwz     r4,0(r3)
59*10465441SEvalZero    cmpi    cr0,0,r4,0x0                        /* whether is 0     */
60*10465441SEvalZero    beq     _no_switch                          /* no switch, exit  */
61*10465441SEvalZero    li      r4,0x0                              /* set rt_thread_switch_interrput_flag to 0 */
62*10465441SEvalZero    stw     r4,0(r3)
63*10465441SEvalZero
64*10465441SEvalZero    /* load from thread to r3 */
65*10465441SEvalZero    lis     r3,rt_interrupt_from_thread@h       /* set rt_interrupt_from_thread */
66*10465441SEvalZero    ori     r3,r3,rt_interrupt_from_thread@l
67*10465441SEvalZero    lwz     r3,0(r3)
68*10465441SEvalZero
69*10465441SEvalZero    cmpi    cr0,0,r3,0x0                        /* whether is 0 */
70*10465441SEvalZero    beq     _restore                            /* it's first switch, goto _restore */
71*10465441SEvalZero
72*10465441SEvalZero    /* save r1:sp to thread[from] stack pointer */
73*10465441SEvalZero    subi    r1, r1, STACK_FRAME_SIZE
74*10465441SEvalZero    stw     r1, 0(r3)
75*10465441SEvalZero
76*10465441SEvalZero    /* restore r3, r4 from SPRG */
77*10465441SEvalZero    mfspr   r3,SPRG0
78*10465441SEvalZero    mfspr   r4,SPRG0
79*10465441SEvalZero
80*10465441SEvalZero    /* save registers   */
81*10465441SEvalZero    stw     r0,GPR0(r1)                         /* save general purpose registers 0    */
82*10465441SEvalZero    stmw    r2,GPR2(r1)                         /* save general purpose registers 2-31 */
83*10465441SEvalZero
84*10465441SEvalZero    mfusprg0 r0                                 /* save usprg0  */
85*10465441SEvalZero    stw     r0,USPRG0(r1)
86*10465441SEvalZero    mfcr    r0,                                 /* save cr      */
87*10465441SEvalZero    stw     r0,CR(r1)
88*10465441SEvalZero    mfxer   r0                                  /* save xer     */
89*10465441SEvalZero    stw     r0,XER(r1)
90*10465441SEvalZero    mfctr   r0                                  /* save ctr     */
91*10465441SEvalZero    stw     r0,CTR(r1)
92*10465441SEvalZero    mflr    r0                                  /* save lr      */
93*10465441SEvalZero    stw     r0, LR(r1)
94*10465441SEvalZero
95*10465441SEvalZero    mfsrr0  r0                                  /* save SRR0 and SRR1   */
96*10465441SEvalZero    stw     r0,SRR0(r1)
97*10465441SEvalZero    mfsrr1  r0
98*10465441SEvalZero    stw     r0,SRR1(r1)
99*10465441SEvalZero
100*10465441SEvalZero_restore:
101*10465441SEvalZero    /* get thread[to] stack pointer */
102*10465441SEvalZero    lis     r4,rt_interrupt_to_thread@h
103*10465441SEvalZero    ori     r4,r4,rt_interrupt_to_thread@l
104*10465441SEvalZero    lwz     r1,0(r4)
105*10465441SEvalZero    lwz     r1,0(r1)
106*10465441SEvalZero
107*10465441SEvalZero    lwz     r0,SRR1(r1)                         /* restore SRR1 and SRR0   */
108*10465441SEvalZero    mtsrr1  r0
109*10465441SEvalZero    lwz     r0,SRR0(r1)
110*10465441SEvalZero    mtsrr0  r0
111*10465441SEvalZero
112*10465441SEvalZero    lwz     r0,LR(r1)                           /* restore lr       */
113*10465441SEvalZero    mtlr    r0
114*10465441SEvalZero    lwz     r0,CTR(r1)                          /* restore ctr     */
115*10465441SEvalZero    mtctr   r0
116*10465441SEvalZero    lwz     r0,XER(r1)                          /* restore xer     */
117*10465441SEvalZero    mtxer   r0
118*10465441SEvalZero    lwz     r0,CR(r1)                           /* restore cr      */
119*10465441SEvalZero    mtcr    r0
120*10465441SEvalZero    lwz     r0,USPRG0(r1)                       /* restore usprg0  */
121*10465441SEvalZero    // mtusprg0 r0
122*10465441SEvalZero
123*10465441SEvalZero    lmw     r2, GPR2(r1)                        /* restore general register */
124*10465441SEvalZero    lwz     r0,GPR0(r1)
125*10465441SEvalZero    addi    r1, r1, STACK_FRAME_SIZE
126*10465441SEvalZero    /* RFI will restore status register and thus the correct priority*/
127*10465441SEvalZero    rfi
128*10465441SEvalZero
129*10465441SEvalZero_no_switch:
130*10465441SEvalZero    /* restore r3, r4 from SPRG */
131*10465441SEvalZero    mfspr   r3,SPRG0
132*10465441SEvalZero    mfspr   r4,SPRG0
133*10465441SEvalZero    rfi
134*10465441SEvalZero
135*10465441SEvalZero    /* void rt_hw_context_switch_to(to); */
136*10465441SEvalZero    .globl rt_hw_context_switch_to
137*10465441SEvalZerort_hw_context_switch_to:
138*10465441SEvalZero    /* set rt_thread_switch_interrput_flag = 1 */
139*10465441SEvalZero    lis     r5,rt_thread_switch_interrput_flag@h
140*10465441SEvalZero    ori     r5,r5,rt_thread_switch_interrput_flag@l
141*10465441SEvalZero    li      r6, 0x01
142*10465441SEvalZero    stw     r6,0(r5)
143*10465441SEvalZero
144*10465441SEvalZero    /* set rt_interrupt_from_thread = 0 */
145*10465441SEvalZero    lis     r5,rt_interrupt_from_thread@h
146*10465441SEvalZero    ori     r5,r5,rt_interrupt_from_thread@l
147*10465441SEvalZero    li      r6, 0x00
148*10465441SEvalZero    stw     r6,0(r5)
149*10465441SEvalZero
150*10465441SEvalZero    /* set rt_interrupt_from_thread = to */
151*10465441SEvalZero    lis     r5,rt_interrupt_to_thread@h
152*10465441SEvalZero    ori     r5,r5,rt_interrupt_to_thread@l
153*10465441SEvalZero    stw     r3,0(r5)
154*10465441SEvalZero
155*10465441SEvalZero    /* trigger a system call */
156*10465441SEvalZero    sc
157*10465441SEvalZero
158*10465441SEvalZero    blr
159*10465441SEvalZero
160*10465441SEvalZero    /* void rt_hw_context_switch(from, to); */
161*10465441SEvalZero    .globl rt_hw_context_switch
162*10465441SEvalZerort_hw_context_switch:
163*10465441SEvalZero    /* compare rt_thread_switch_interrupt_flag and set it */
164*10465441SEvalZero    lis     r5,rt_thread_switch_interrput_flag@h
165*10465441SEvalZero    ori     r5,r5,rt_thread_switch_interrput_flag@l
166*10465441SEvalZero    lwz     r6,0(r5)
167*10465441SEvalZero    cmpi    cr0,0,r6,0x1                        /* whether is 1 */
168*10465441SEvalZero    beq     _reswitch                           /* set already, goto _reswitch */
169*10465441SEvalZero    li      r6,0x1                              /* set rt_thread_switch_interrput_flag to 1*/
170*10465441SEvalZero    stw     r6,0(r5)
171*10465441SEvalZero
172*10465441SEvalZero    /* set rt_interrupt_from_thread to 'from' */
173*10465441SEvalZero    lis     r5,rt_interrupt_from_thread@h
174*10465441SEvalZero    ori     r5,r5,rt_interrupt_from_thread@l
175*10465441SEvalZero    stw     r3,0(r5)
176*10465441SEvalZero
177*10465441SEvalZero_reswitch:
178*10465441SEvalZero    /* set rt_interrupt_to_thread to 'to' */
179*10465441SEvalZero    lis     r6,rt_interrupt_to_thread@h
180*10465441SEvalZero    ori     r6,r6,rt_interrupt_to_thread@l
181*10465441SEvalZero    stw     r4,0(r6)
182*10465441SEvalZero
183*10465441SEvalZero    /* trigger a system call */
184*10465441SEvalZero    sc
185*10465441SEvalZero
186*10465441SEvalZero    blr
187*10465441SEvalZero
188*10465441SEvalZero    .globl rt_hw_context_switch_interrupt
189*10465441SEvalZerort_hw_context_switch_interrupt:
190*10465441SEvalZero    /* compare rt_thread_switch_interrupt_flag and set it */
191*10465441SEvalZero    lis     r5,rt_thread_switch_interrput_flag@h
192*10465441SEvalZero    ori     r5,r5,rt_thread_switch_interrput_flag@l
193*10465441SEvalZero    lwz     r6,0(r5)
194*10465441SEvalZero    cmpi    cr0,0,r6,0x1                        /* whether is 1 */
195*10465441SEvalZero    beq     _int_reswitch                       /* set already, goto _reswitch */
196*10465441SEvalZero    li      r6,0x1                              /* set rt_thread_switch_interrput_flag to 1*/
197*10465441SEvalZero    stw     r6,0(r5)
198*10465441SEvalZero
199*10465441SEvalZero    /* set rt_interrupt_from_thread to 'from' */
200*10465441SEvalZero    lis     r5,rt_interrupt_from_thread@h
201*10465441SEvalZero    ori     r5,r5,rt_interrupt_from_thread@l
202*10465441SEvalZero    stw     r3,0(r5)
203*10465441SEvalZero
204*10465441SEvalZero_int_reswitch:
205*10465441SEvalZero    /* set rt_interrupt_to_thread to 'to' */
206*10465441SEvalZero    lis     r6,rt_interrupt_to_thread@h
207*10465441SEvalZero    ori     r6,r6,rt_interrupt_to_thread@l
208*10465441SEvalZero    stw     r4,0(r6)
209*10465441SEvalZero
210*10465441SEvalZero    blr
211