Subversion Repositories HelenOS

Rev

Rev 4130 | Rev 4638 | 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>
37
#include <genarch/ofw/ofw_tree.h>
38
#include <cpu.h>
39
#include <arch/cpu.h>
4614 rimsky 40
#include <arch/boot/boot.h>
3771 rimsky 41
#include <arch.h>
42
#include <config.h>
43
#include <macros.h>
44
#include <arch/types.h>
45
#include <synch/synch.h>
46
#include <synch/waitq.h>
47
#include <print.h>
4614 rimsky 48
#include <arch/sun4v/hypercall.h>
49
#include <arch/sun4v/md.h>
50
#include <time/delay.h>
3771 rimsky 51
 
4614 rimsky 52
#define CPU_STATE_RUNNING   2
53
 
54
extern void kernel_image_start(void);
55
extern void *trap_table;
56
 
3771 rimsky 57
/** Determine number of processors. */
58
void smp_init(void)
59
{
4614 rimsky 60
    md_node_t node = md_get_root();
61
    count_t cpu_count = 0;
62
 
63
    /* walk through MD, find the current CPU node & its clock-frequency */
64
    while(md_next_node(&node, "cpu")) {
65
        cpu_count++;
66
    }
67
 
68
    config.cpu_count = cpu_count;
3771 rimsky 69
}
70
 
71
 
72
/** Wake application processors up. */
73
void kmp(void *arg)
74
{
4614 rimsky 75
    (void) arg;
76
 
77
    uint64_t myid;
78
    __hypercall_fast_ret1(0, 0, 0, 0, 0, CPU_MYID, &myid);
79
 
80
    /* stop the CPUs before making them execute our code */
81
    uint64_t i;
82
    for (i = 0; i < config.cpu_count; i++) {
83
        if (i == myid)
84
            continue;
85
 
86
        if (__hypercall_fast1(CPU_STOP, i) != 0)
87
            continue;
88
 
89
        uint64_t state;
90
        __hypercall_fast_ret1(i, 0, 0, 0, 0, CPU_STATE, &state);
91
        while (state == CPU_STATE_RUNNING) {
92
            __hypercall_fast_ret1(i, 0, 0, 0, 0, CPU_STATE, &state);
93
        }
94
    }
95
 
96
    /* wake the processors up, one by one */
97
    uint64_t state;
98
    for (i = 1; i < config.cpu_count; i++) {
99
        __hypercall_fast_ret1(i, 0, 0, 0, 0, CPU_STATE, &state);
100
        printf("Starting CPU %d, error code = %d.\n", i, __hypercall_fast4(
101
            CPU_START,
102
            i,
103
            (uint64_t) KA2PA(kernel_image_start),
104
            KA2PA(trap_table),
105
            bootinfo.physmem_start         
106
        ));
107
 
108
        if (waitq_sleep_timeout(&ap_completion_wq, 10000000, SYNCH_FLAGS_NONE) ==
109
                    ESYNCH_TIMEOUT)
110
            printf("%s: waiting for processor (cpuid = %" PRIu32
111
                ") timed out\n", __func__, i);
112
 
113
    }
114
 
3771 rimsky 115
}
116
 
117
/** @}
118
 */