summaryrefslogtreecommitdiffstats
path: root/pk/ppe42/ppe42_thread_init.S
blob: 7185f7c783833b8ffcf52c894accff391f6e33b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/// \file ppe42_thread_init.S
/// \brief PPE42-specific thread initialization
///
/// The entry points in this file are routines that are typically used during
/// initialization, and their code space could be deallocated and recovered if
/// no longer needed by the application after initialization.

        .nolist
#include "pk.h"
        .list
        
/// \fn void __pk_thread_context_initialize(PkThread *thread, PkThreadRoutine thread_routine, void *private)
/// \brief Create the initial thread context on the stack
///
/// The non-reserved GPRs are prepatterned with 0x0000\<rn\>\<rn\> where \<rn\> is
/// the register number (as decimal).  The initial context is set up with the
/// thread running in the default machine context, and when the thread is
/// switched in it will begin executing at the entry point of the thread
/// routine with the \c private parameter in R3.  The LR is initialized such
/// that when the thread returns, it will return to the entry point of \c
/// pk_complete().
#ifdef DOXYGEN_ONLY
void 
__pk_thread_context_initialize(PkThread        *thread, 
                                PkThreadRoutine thread_routine, 
                                void             *private);
#endif
//-----------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2014
// *! All Rights Reserved -- Property of IBM
// *! *** IBM Confidential ***
//-----------------------------------------------------------------------------
        
/// \cond

        .global_function __pk_thread_context_initialize

__pk_thread_context_initialize:

        ## R3 = thread (param)
        ## R4 = thread_routine (param)
        ## R5 = private (param)
        ## R6 = thread stack pointer (computed)
        ## R7 = scratch

        .macro  _gpr_init, prefix, reg, val
        li      %r7, \val
        stw     %r7, \prefix\reg(%r6)
        .endm

        ## Initialize volatile context on the thread stack. The CR is cleared,
        ## the LR = pk_complete(), R3 has the private parameter.

        lwz     %r6, PK_THREAD_OFFSET_SAVED_STACK_POINTER(%r3)
        
        stwu    %r6, -PK_CTX_SIZE(%r6)

        li      %r7, 0
        stw     %r7, PK_CTX_CR(%r6)

        _liw    %r7, pk_complete
        stw     %r7, PK_CTX_LR(%r6)

        stw     %r5, PK_CTX_GPR3(%r6)

        _gpr_init PK_CTX_GPR, 4, 0x0404
        _gpr_init PK_CTX_GPR, 5, 0x0505
        _gpr_init PK_CTX_GPR, 6, 0x0606

        ## XER and CTR are clear, SRR0 = thread_routine, SRR1 = default machine
        ## context.

        li      %r7, 0
        stw     %r7, PK_CTX_XER(%r6)
        stw     %r7, PK_CTX_CTR(%r6)

        stw     %r4, PK_CTX_SRR0(%r6)

        _lwzsd  %r7, __pk_thread_machine_context_default
        stw     %r7, PK_CTX_SRR1(%r6)

        _gpr_init PK_CTX_GPR, 0,  0x0000
        _gpr_init PK_CTX_GPR, 7,  0x0707
        _gpr_init PK_CTX_GPR, 8,  0x0808
        _gpr_init PK_CTX_GPR, 9,  0x0909
        _gpr_init PK_CTX_GPR, 10, 0x1010

        ## Initialize the non-volatile context on the thread stack.

        _gpr_init PK_CTX_GPR, 28, 0x2828       
        _gpr_init PK_CTX_GPR, 29, 0x2929       
        _gpr_init PK_CTX_GPR, 30, 0x3030       
        _gpr_init PK_CTX_GPR, 31, 0x3131

        ## Initialize the kernel context on the thread stack.
        ## Note: Thread priority is set later each time the thread is
        ##       resumed.

        lis     %r7, PPE42_THREAD_MODE
        stw     %r7, PK_CTX_KERNEL_CTX(%r6)

        ## Initialization is done - the stack pointer is stored back in the
        ## thread.

        stw     %r6, PK_THREAD_OFFSET_SAVED_STACK_POINTER(%r3)
        blr

        .epilogue __pk_thread_context_initialize

/// \endcond
OpenPOWER on IntegriCloud