Rev 3479 | Rev 3591 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3479 | Rev 3582 | ||
---|---|---|---|
Line 38... | Line 38... | ||
38 | #include <string.h> |
38 | #include <string.h> |
39 | #include <register.h> |
39 | #include <register.h> |
40 | #include "main.h" |
40 | #include "main.h" |
41 | #include "asm.h" |
41 | #include "asm.h" |
42 | 42 | ||
- | 43 | extern uint8_t subarchitecture; |
|
- | 44 | ||
43 | void write(const char *str, const int len) |
45 | void write(const char *str, const int len) |
44 | { |
46 | { |
45 | int i; |
47 | int i; |
46 | 48 | ||
47 | for (i = 0; i < len; i++) { |
49 | for (i = 0; i < len; i++) { |
Line 54... | Line 56... | ||
54 | int ofw_translate_failed(ofw_arg_t flag) |
56 | int ofw_translate_failed(ofw_arg_t flag) |
55 | { |
57 | { |
56 | return flag != -1; |
58 | return flag != -1; |
57 | } |
59 | } |
58 | 60 | ||
59 | int ofw_cpu(void) |
61 | static int wake_cpus_in_node(phandle child, uint64_t current_mid) |
60 | { |
62 | { |
61 | char type_name[BUF_SIZE]; |
- | |
62 | phandle node; |
- | |
63 | phandle ssm; |
- | |
64 | - | ||
65 | ssm = ofw_find_device("/ssm@0,0"); |
- | |
66 | if (ssm == -1) { |
- | |
67 | node = ofw_get_child_node(ofw_root); |
- | |
68 | } else { |
- | |
69 | node = ofw_get_child_node(ssm); |
- | |
70 | } |
- | |
71 | - | ||
72 | if (node == 0 || node == -1) { |
- | |
73 | printf("Could not find any child nodes of the root node.\n"); |
- | |
74 | return 0; |
- | |
75 | } |
- | |
76 | - | ||
77 | uint64_t current_mid; |
- | |
78 | - | ||
79 | asm volatile ("ldxa [%1] %2, %0\n" |
- | |
80 | : "=r" (current_mid) |
- | |
81 | : "r" (0), "i" (ASI_ICBUS_CONFIG)); |
- | |
82 | current_mid >>= ICBUS_CONFIG_MID_SHIFT; |
- | |
83 | current_mid &= ICBUS_CONFIG_MID_MASK; |
- | |
84 | - | ||
85 | int cpus; |
63 | int cpus; |
- | 64 | char type_name[BUF_SIZE]; |
|
86 | 65 | ||
87 | for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node), |
66 | for (cpus = 0; child != 0 && child != -1; |
88 | cpus++) { |
67 | child = ofw_get_peer_node(child), cpus++) { |
89 | if (ofw_get_property(node, "device_type", type_name, |
68 | if (ofw_get_property(child, "device_type", type_name, |
90 | sizeof(type_name)) > 0) { |
69 | sizeof(type_name)) > 0) { |
91 | if (strcmp(type_name, "cpu") == 0) { |
70 | if (strcmp(type_name, "cpu") == 0) { |
92 | uint32_t mid; |
71 | uint32_t mid; |
93 | 72 | ||
- | 73 | /* |
|
94 | /* "upa-portid" for US, "portid" for US-III */ |
74 | * "upa-portid" for US, "portid" for US-III, |
- | 75 | * "cpuid" for US-IV* |
|
- | 76 | */ |
|
95 | if (ofw_get_property( |
77 | if (ofw_get_property( |
96 | node, "upa-portid", |
78 | child, "upa-portid", |
97 | &mid, sizeof(mid)) <= 0 |
79 | &mid, sizeof(mid)) <= 0 |
98 | && ofw_get_property(node, "portid", |
80 | && ofw_get_property(child, "portid", |
- | 81 | &mid, sizeof(mid)) <= 0 |
|
- | 82 | && ofw_get_property(child, "cpuid", |
|
99 | &mid, sizeof(mid)) <= 0) |
83 | &mid, sizeof(mid)) <= 0) |
100 | continue; |
84 | continue; |
101 | 85 | ||
102 | if (current_mid != mid) { |
86 | if (current_mid != mid) { |
103 | /* |
87 | /* |
104 | * Start secondary processor. |
88 | * Start secondary processor. |
105 | */ |
89 | */ |
- | 90 | printf("Starting CPU: %d.\n", mid); |
|
106 | (void) ofw_call("SUNW,start-cpu", 3, 1, |
91 | (void) ofw_call("SUNW,start-cpu", 3, 1, |
107 | NULL, node, KERNEL_VIRTUAL_ADDRESS, |
92 | NULL, child, KERNEL_VIRTUAL_ADDRESS, |
108 | bootinfo.physmem_start | |
93 | bootinfo.physmem_start | |
109 | AP_PROCESSOR); |
94 | AP_PROCESSOR); |
110 | } |
95 | } |
111 | } |
96 | } |
112 | } |
97 | } |
113 | } |
98 | } |
114 | 99 | ||
115 | return cpus; |
100 | return cpus; |
116 | } |
101 | } |
117 | 102 | ||
- | 103 | int ofw_cpu(void) |
|
- | 104 | { |
|
- | 105 | int cpus; |
|
- | 106 | phandle node; |
|
- | 107 | phandle subnode; |
|
- | 108 | phandle ssm; |
|
- | 109 | phandle cmp; |
|
- | 110 | char name[BUF_SIZE]; |
|
- | 111 | ||
- | 112 | /* get the current CPU MID */ |
|
- | 113 | uint64_t current_mid; |
|
- | 114 | ||
- | 115 | asm volatile ("ldxa [%1] %2, %0\n" |
|
- | 116 | : "=r" (current_mid) |
|
- | 117 | : "r" (0), "i" (ASI_ICBUS_CONFIG)); |
|
- | 118 | current_mid >>= ICBUS_CONFIG_MID_SHIFT; |
|
- | 119 | ||
- | 120 | if (subarchitecture == SUBARCH_US) { |
|
- | 121 | current_mid &= ICBUS_CONFIG_MID_MASK_US; |
|
- | 122 | } else if (subarchitecture == SUBARCH_US3) { |
|
- | 123 | current_mid &= ICBUS_CONFIG_MID_MASK_US3; |
|
- | 124 | } else { |
|
- | 125 | printf("MID format unknown for this subarchitecture."); |
|
- | 126 | return 0; |
|
- | 127 | } |
|
- | 128 | ||
- | 129 | /* wake up CPUs */ |
|
- | 130 | ssm = ofw_find_device("/ssm@0,0"); |
|
- | 131 | if (ssm == -1) { |
|
- | 132 | node = ofw_get_child_node(ofw_root); |
|
- | 133 | cpus = wake_cpus_in_node(node, current_mid); |
|
- | 134 | } else { |
|
- | 135 | node = ofw_get_child_node(ssm); |
|
- | 136 | cpus = wake_cpus_in_node(node, current_mid); |
|
- | 137 | while (node != 0 && node != -1) { |
|
- | 138 | if (ofw_get_property(node, "name", name, |
|
- | 139 | sizeof(name)) > 0) { |
|
- | 140 | if (strcmp(name, "cmp") == 0) { |
|
- | 141 | printf("nasel jsem dalsi CPU"); |
|
- | 142 | subnode = ofw_get_child_node(node); |
|
- | 143 | cpus += wake_cpus_in_node(subnode, |
|
- | 144 | current_mid); |
|
- | 145 | } |
|
- | 146 | } |
|
- | 147 | node = ofw_get_peer_node(node); |
|
- | 148 | } |
|
- | 149 | } |
|
- | 150 | ||
- | 151 | return cpus; |
|
- | 152 | ||
- | 153 | } |
|
- | 154 | ||
118 | /** Get physical memory starting address. |
155 | /** Get physical memory starting address. |
119 | * |
156 | * |
120 | * @param start Pointer to variable where the physical memory starting |
157 | * @param start Pointer to variable where the physical memory starting |
121 | * address will be stored. |
158 | * address will be stored. |
122 | * |
159 | * |