Subversion Repositories HelenOS

Rev

Rev 4614 | Rev 4663 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3771 rimsky 1
/*
2
 * Copyright (c) 2006 Jakub Jermar
3
 * Copyright (c) 2009 Pavel Rimsky
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * - Redistributions of source code must retain the above copyright
11
 *   notice, this list of conditions and the following disclaimer.
12
 * - Redistributions in binary form must reproduce the above copyright
13
 *   notice, this list of conditions and the following disclaimer in the
14
 *   documentation and/or other materials provided with the distribution.
15
 * - The name of the author may not be used to endorse or promote products
16
 *   derived from this software without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 */
29
 
30
/** @addtogroup sparc64
31
 * @{
32
 */
33
/** @file
34
 */
35
 
36
#include <smp/smp.h>
4638 rimsky 37
#include <smp/ipi.h>
3771 rimsky 38
#include <genarch/ofw/ofw_tree.h>
39
#include <cpu.h>
40
#include <arch/cpu.h>
4614 rimsky 41
#include <arch/boot/boot.h>
3771 rimsky 42
#include <arch.h>
43
#include <config.h>
44
#include <macros.h>
45
#include <arch/types.h>
46
#include <synch/synch.h>
47
#include <synch/waitq.h>
48
#include <print.h>
4614 rimsky 49
#include <arch/sun4v/hypercall.h>
50
#include <arch/sun4v/md.h>
4638 rimsky 51
#include <arch/sun4v/ipi.h>
4614 rimsky 52
#include <time/delay.h>
3771 rimsky 53
 
4614 rimsky 54
#define CPU_STATE_RUNNING   2
55
 
56
extern void kernel_image_start(void);
57
extern void *trap_table;
58
 
3771 rimsky 59
/** Determine number of processors. */
60
void smp_init(void)
61
{
4614 rimsky 62
    md_node_t node = md_get_root();
63
    count_t cpu_count = 0;
64
 
65
    /* walk through MD, find the current CPU node & its clock-frequency */
66
    while(md_next_node(&node, "cpu")) {
67
        cpu_count++;
68
    }
69
 
70
    config.cpu_count = cpu_count;
3771 rimsky 71
}
72
 
73
 
74
/** Wake application processors up. */
75
void kmp(void *arg)
76
{
4638 rimsky 77
#if 1
4614 rimsky 78
    (void) arg;
79
 
80
    uint64_t myid;
81
    __hypercall_fast_ret1(0, 0, 0, 0, 0, CPU_MYID, &myid);
82
 
83
    /* stop the CPUs before making them execute our code */
84
    uint64_t i;
85
    for (i = 0; i < config.cpu_count; i++) {
86
        if (i == myid)
87
            continue;
88
 
89
        if (__hypercall_fast1(CPU_STOP, i) != 0)
90
            continue;
91
 
92
        uint64_t state;
93
        __hypercall_fast_ret1(i, 0, 0, 0, 0, CPU_STATE, &state);
94
        while (state == CPU_STATE_RUNNING) {
95
            __hypercall_fast_ret1(i, 0, 0, 0, 0, CPU_STATE, &state);
96
        }
97
    }
98
 
99
    /* wake the processors up, one by one */
100
    uint64_t state;
101
    for (i = 1; i < config.cpu_count; i++) {
102
        __hypercall_fast_ret1(i, 0, 0, 0, 0, CPU_STATE, &state);
103
        printf("Starting CPU %d, error code = %d.\n", i, __hypercall_fast4(
104
            CPU_START,
105
            i,
106
            (uint64_t) KA2PA(kernel_image_start),
107
            KA2PA(trap_table),
108
            bootinfo.physmem_start         
109
        ));
110
 
111
        if (waitq_sleep_timeout(&ap_completion_wq, 10000000, SYNCH_FLAGS_NONE) ==
112
                    ESYNCH_TIMEOUT)
113
            printf("%s: waiting for processor (cpuid = %" PRIu32
114
                ") timed out\n", __func__, i);
115
 
116
    }
4638 rimsky 117
#else
4614 rimsky 118
 
4638 rimsky 119
    asm volatile (
120
        "setx temp_cpu_mondo_handler, %g4, %g6 \n"
121
        //"setx 0x80246ad8, %g4, %g7 \n"
122
        "setx 0x80200f80, %g4, %g7 \n"
123
 
124
        "ldx [%g6], %g4 \n"
125
        "stxa %g4, [%g7] 0x14 \n"
126
        "membar #Sync \n"
127
 
128
        "add %g7, 0x8, %g7 \n"
129
        "ldx [%g6 + 0x8], %g4 \n"
130
        "stxa %g4, [%g7] 0x14 \n"
131
        "membar #Sync \n"
132
 
133
        "add %g7, 0x8, %g7 \n"
134
        "ldx [%g6 + 0x10], %g4 \n"
135
        "stxa %g4, [%g7] 0x14 \n"
136
        "membar #Sync \n"
137
 
138
        "add %g7, 0x8, %g7 \n"
139
        "ldx [%g6 + 0x18], %g4 \n"
140
        "stxa %g4, [%g7] 0x14 \n"
141
        "membar #Sync \n"
142
 
143
        "add %g7, 0x8, %g7 \n"
144
        "ldx [%g6 + 0x20], %g4 \n"
145
        "stxa %g4, [%g7] 0x14 \n"
146
        "membar #Sync \n"
147
 
148
        "add %g7, 0x8, %g7 \n"
149
        "ldx [%g6 + 0x28], %g4 \n"
150
        "stxa %g4, [%g7] 0x14 \n"
151
        "membar #Sync \n"
152
 
153
        "add %g7, 0x8, %g7 \n"
154
        "ldx [%g6 + 0x30], %g4 \n"
155
        "stxa %g4, [%g7] 0x14 \n"
156
        "membar #Sync \n"
157
 
158
        "add %g7, 0x8, %g7 \n"
159
        "ldx [%g6 + 0x38], %g4 \n"
160
        "stxa %g4, [%g7] 0x14 \n"
161
        "membar #Sync \n"
162
 
163
        "add %g7, 0x8, %g7 \n"
164
        "ldx [%g6 + 0x40], %g4 \n"
165
        "stxa %g4, [%g7] 0x14 \n"
166
        "membar #Sync \n"
167
 
168
        "flush %i7"
169
 
170
        );
171
    delay(1000);
172
    printf("Result: %d\n", ipi_unicast_to((void (*)(void)) 1234, 1));
173
        if (waitq_sleep_timeout(&ap_completion_wq, 10000000, SYNCH_FLAGS_NONE) ==
174
                    ESYNCH_TIMEOUT)
175
            printf("%s: waiting for processor (cpuid = %" PRIu32
176
                ") timed out\n", __func__, 1);
177
#endif
3771 rimsky 178
}
179
 
180
/** @}
181
 */