Rev 3467 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3467 | Rev 3582 | ||
---|---|---|---|
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> |
Line 60... | Line 61... | ||
60 | void smp_init(void) |
61 | void smp_init(void) |
61 | { |
62 | { |
62 | ofw_tree_node_t *node; |
63 | ofw_tree_node_t *node; |
63 | count_t cnt = 0; |
64 | count_t cnt = 0; |
64 | 65 | ||
- | 66 | if (is_us() || is_us_iii()) { |
|
65 | node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
67 | node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
66 | while (node) { |
68 | while (node) { |
67 | cnt++; |
69 | cnt++; |
68 | 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 | } |
|
69 | } |
78 | } |
70 | 79 | ||
71 | config.cpu_count = max(1, cnt); |
80 | config.cpu_count = max(1, cnt); |
72 | } |
81 | } |
73 | 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) == ESYNCH_TIMEOUT) |
|
- | 110 | printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n", |
|
- | 111 | __func__, mid); |
|
- | 112 | } |
|
- | 113 | ||
74 | /** Wake application processors up. */ |
114 | /** Wake application processors up. */ |
75 | void kmp(void *arg) |
115 | void kmp(void *arg) |
76 | { |
116 | { |
77 | ofw_tree_node_t *node; |
117 | ofw_tree_node_t *node; |
78 | int i; |
118 | int i; |
79 | 119 | ||
- | 120 | printf("\nGoing to wake CPUs up.\n"); |
|
- | 121 | ||
- | 122 | if (is_us() || is_us_iii()) { |
|
80 | node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
123 | node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
81 | for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) { |
124 | for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) |
82 | uint32_t mid; |
125 | wakeup_cpu(node); |
83 | ofw_tree_property_t *prop; |
126 | } else if (is_us_iv()) { |
84 | - | ||
85 | prop = ofw_tree_getprop(node, PORTID_NAME); |
127 | node = ofw_tree_find_child(cpus_parent(), "cmp"); |
86 | if (!prop || !prop->value) |
- | |
87 | continue; |
128 | while (node) { |
88 | - | ||
89 | mid = *((uint32_t *) prop->value); |
129 | wakeup_cpu(ofw_tree_find_child(node, "cpu@0")); |
90 | if (CPU->arch.mid == mid) { |
130 | wakeup_cpu(ofw_tree_find_child(node, "cpu@1")); |
91 | /* |
- | |
92 | * Skip the current CPU. |
131 | node = ofw_tree_find_peer_by_name(node, "cmp"); |
93 | */ |
- | |
94 | continue; |
- | |
95 | } |
132 | } |
96 | - | ||
97 | /* |
- | |
98 | * Processor with ID == mid can proceed with its initialization. |
- | |
99 | */ |
- | |
100 | waking_up_mid = mid; |
- | |
101 | - | ||
102 | if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) |
- | |
103 | printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n", |
- | |
104 | __func__, mid); |
- | |
105 | } |
133 | } |
106 | } |
134 | } |
107 | 135 | ||
108 | /** @} |
136 | /** @} |
109 | */ |
137 | */ |