Rev 3071 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3071 | Rev 3672 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | */ |
33 | */ |
34 | 34 | ||
35 | #include <smp/smp.h> |
35 | #include <smp/smp.h> |
36 | #include <genarch/ofw/ofw_tree.h> |
36 | #include <genarch/ofw/ofw_tree.h> |
37 | #include <cpu.h> |
37 | #include <cpu.h> |
- | 38 | #include <arch/cpu_family.h> |
|
38 | #include <arch/cpu.h> |
39 | #include <arch/cpu.h> |
39 | #include <arch.h> |
40 | #include <arch.h> |
40 | #include <config.h> |
41 | #include <config.h> |
41 | #include <macros.h> |
42 | #include <macros.h> |
42 | #include <arch/types.h> |
43 | #include <arch/types.h> |
43 | #include <synch/synch.h> |
44 | #include <synch/synch.h> |
44 | #include <synch/waitq.h> |
45 | #include <synch/waitq.h> |
45 | #include <print.h> |
46 | #include <print.h> |
- | 47 | #include <arch/cpu_node.h> |
|
46 | 48 | ||
47 | /** |
49 | /** |
48 | * This global variable is used to pick-up application processors |
50 | * This global variable is used to pick-up application processors |
49 | * from their active loop in start.S. When a processor looping in |
51 | * from their active loop in start.S. When a processor looping in |
50 | * start.S sees that this variable contains its MID, it can |
52 | * start.S sees that this variable contains its MID, it can |
Line 59... | Line 61... | ||
59 | void smp_init(void) |
61 | void smp_init(void) |
60 | { |
62 | { |
61 | ofw_tree_node_t *node; |
63 | ofw_tree_node_t *node; |
62 | count_t cnt = 0; |
64 | count_t cnt = 0; |
63 | 65 | ||
- | 66 | if (is_us() || is_us_iii()) { |
|
64 | node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
67 | node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
65 | while (node) { |
68 | while (node) { |
66 | cnt++; |
69 | cnt++; |
67 | node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
70 | node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
- | 71 | } |
|
- | 72 | } else if (is_us_iv()) { |
|
- | 73 | node = ofw_tree_find_child(cpus_parent(), "cmp"); |
|
- | 74 | while (node) { |
|
- | 75 | cnt += 2; |
|
- | 76 | node = ofw_tree_find_peer_by_name(node, "cmp"); |
|
- | 77 | } |
|
68 | } |
78 | } |
69 | 79 | ||
70 | config.cpu_count = max(1, cnt); |
80 | config.cpu_count = max(1, cnt); |
71 | } |
81 | } |
72 | 82 | ||
- | 83 | /** |
|
- | 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 |
|
- | 86 | * no effect. |
|
- | 87 | */ |
|
- | 88 | static void wakeup_cpu(ofw_tree_node_t *node) |
|
- | 89 | { |
|
- | 90 | uint32_t mid; |
|
- | 91 | ofw_tree_property_t *prop; |
|
- | 92 | ||
- | 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"); |
|
- | 99 | ||
- | 100 | if (!prop || prop->value == NULL) |
|
- | 101 | return; |
|
- | 102 | ||
- | 103 | mid = *((uint32_t *) prop->value); |
|
- | 104 | if (CPU->arch.mid == mid) |
|
- | 105 | return; |
|
- | 106 | ||
- | 107 | waking_up_mid = mid; |
|
- | 108 | ||
- | 109 | if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == |
|
- | 110 | ESYNCH_TIMEOUT) |
|
- | 111 | printf("%s: waiting for processor (mid = %" PRIu32 |
|
- | 112 | ") timed out\n", __func__, mid); |
|
- | 113 | } |
|
- | 114 | ||
73 | /** Wake application processors up. */ |
115 | /** Wake application processors up. */ |
74 | void kmp(void *arg) |
116 | void kmp(void *arg) |
75 | { |
117 | { |
76 | ofw_tree_node_t *node; |
118 | ofw_tree_node_t *node; |
77 | int i; |
119 | int i; |
78 | 120 | ||
- | 121 | if (is_us() || is_us_iii()) { |
|
79 | node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
122 | node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
- | 123 | for (i = 0; node; |
|
80 | for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) { |
124 | node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) |
81 | uint32_t mid; |
125 | wakeup_cpu(node); |
82 | ofw_tree_property_t *prop; |
126 | } else if (is_us_iv()) { |
83 | - | ||
84 | prop = ofw_tree_getprop(node, "upa-portid"); |
127 | node = ofw_tree_find_child(cpus_parent(), "cmp"); |
85 | if (!prop || !prop->value) |
- | |
86 | continue; |
128 | while (node) { |
87 | - | ||
88 | mid = *((uint32_t *) prop->value); |
129 | wakeup_cpu(ofw_tree_find_child(node, "cpu@0")); |
89 | if (CPU->arch.mid == mid) { |
130 | wakeup_cpu(ofw_tree_find_child(node, "cpu@1")); |
90 | /* |
- | |
91 | * Skip the current CPU. |
131 | node = ofw_tree_find_peer_by_name(node, "cmp"); |
92 | */ |
- | |
93 | continue; |
- | |
94 | } |
132 | } |
95 | - | ||
96 | /* |
- | |
97 | * Processor with ID == mid can proceed with its initialization. |
- | |
98 | */ |
- | |
99 | waking_up_mid = mid; |
- | |
100 | - | ||
101 | if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) |
- | |
102 | printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n", |
- | |
103 | __func__, mid); |
- | |
104 | } |
133 | } |
105 | } |
134 | } |
106 | 135 | ||
107 | /** @} |
136 | /** @} |
108 | */ |
137 | */ |