2
* Copyright (c) 2006 Jakub Jermar
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* - Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
* - The name of the author may not be used to endorse or promote products
15
* derived from this software without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
/** @addtogroup sparc64
36
#include <genarch/ofw/ofw_tree.h>
38
#include <arch/cpu_family.h>
43
#include <arch/types.h>
44
#include <synch/synch.h>
45
#include <synch/waitq.h>
47
#include <arch/cpu_node.h>
50
* This global variable is used to pick-up application processors
51
* from their active loop in start.S. When a processor looping in
52
* start.S sees that this variable contains its MID, it can
53
* proceed with its initialization.
55
* This variable is modified only by the bootstrap processor.
56
* Other processors access it read-only.
58
volatile uint64_t waking_up_mid = (uint64_t) -1;
60
/** Determine number of processors. */
63
ofw_tree_node_t *node;
66
if (is_us() || is_us_iii()) {
67
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
70
node = ofw_tree_find_peer_by_device_type(node, "cpu");
72
} else if (is_us_iv()) {
73
node = ofw_tree_find_child(cpus_parent(), "cmp");
76
node = ofw_tree_find_peer_by_name(node, "cmp");
80
config.cpu_count = max(1, cnt);
84
* Wakes up the CPU which is represented by the "node" OFW tree node.
85
* If "node" represents the current CPU, calling the function has
88
static void wakeup_cpu(ofw_tree_node_t *node)
91
ofw_tree_property_t *prop;
93
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */
94
prop = ofw_tree_getprop(node, "upa-portid");
95
if ((!prop) || (!prop->value))
96
prop = ofw_tree_getprop(node, "portid");
97
if ((!prop) || (!prop->value))
98
prop = ofw_tree_getprop(node, "cpuid");
100
if (!prop || prop->value == NULL)
103
mid = *((uint32_t *) prop->value);
104
if (CPU->arch.mid == mid)
109
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) ==
111
printf("%s: waiting for processor (mid = %" PRIu32
112
") timed out\n", __func__, mid);
115
/** Wake application processors up. */
118
ofw_tree_node_t *node;
121
if (is_us() || is_us_iii()) {
122
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
124
node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++)
126
} else if (is_us_iv()) {
127
node = ofw_tree_find_child(cpus_parent(), "cmp");
129
wakeup_cpu(ofw_tree_find_child(node, "cpu@0"));
130
wakeup_cpu(ofw_tree_find_child(node, "cpu@1"));
131
node = ofw_tree_find_peer_by_name(node, "cmp");