Changeset 965dc18 in mainline for kernel/arch/sparc64/src/smp
- Timestamp:
- 2008-12-05T19:59:03Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 49093a4
- Parents:
- 0258e67
- Location:
- kernel/arch/sparc64/src/smp
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/sparc64/src/smp/ipi.c
r0258e67 r965dc18 47 47 #include <panic.h> 48 48 49 /** Set the contents of the outgoing interrupt vector data. 50 * 51 * The first data item (data 0) will be set to the value of func, the 52 * rest of the vector will contain zeros. 53 * 54 * This is a helper function used from within the cross_call function. 55 * 56 * @param func value the first data item of the vector will be set to 57 */ 58 static inline void set_intr_w_data(void (* func)(void)) 59 { 60 #if defined (US) 61 asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_0, (uintptr_t) func); 62 asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_1, 0); 63 asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_2, 0); 64 #elif defined (US3) 65 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_0, (uintptr_t) func); 66 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_1, 0); 67 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_2, 0); 68 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_3, 0); 69 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_4, 0); 70 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_5, 0); 71 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_6, 0); 72 asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_7, 0); 73 #endif 74 } 75 49 76 /** Invoke function on another processor. 50 77 * … … 74 101 panic("Interrupt Dispatch Status busy bit set\n"); 75 102 103 ASSERT(!(pstate_read() & PSTATE_IE_BIT)); 104 76 105 do { 77 asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_0, 78 (uintptr_t) func); 79 asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_1, 0); 80 asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_2, 0); 81 asi_u64_write(ASI_UDB_INTR_W, 106 set_intr_w_data(func); 107 asi_u64_write(ASI_INTR_W, 82 108 (mid << INTR_VEC_DISPATCH_MID_SHIFT) | 83 ASI_UDB_INTR_W_DISPATCH, 0);109 VA_INTR_W_DISPATCH, 0); 84 110 85 111 membar(); -
kernel/arch/sparc64/src/smp/smp.c
r0258e67 r965dc18 36 36 #include <genarch/ofw/ofw_tree.h> 37 37 #include <cpu.h> 38 #include <arch/cpu_family.h> 38 39 #include <arch/cpu.h> 39 40 #include <arch.h> … … 44 45 #include <synch/waitq.h> 45 46 #include <print.h> 47 #include <arch/cpu_node.h> 46 48 47 49 /** … … 62 64 count_t cnt = 0; 63 65 64 node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); 65 while (node) { 66 cnt++; 67 node = ofw_tree_find_peer_by_device_type(node, "cpu"); 66 if (is_us() || is_us_iii()) { 67 node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); 68 while (node) { 69 cnt++; 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 80 config.cpu_count = max(1, cnt); 81 } 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); 71 113 } 72 114 … … 77 119 int i; 78 120 79 node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); 80 for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) { 81 uint32_t mid; 82 ofw_tree_property_t *prop; 83 84 prop = ofw_tree_getprop(node, "upa-portid"); 85 if (!prop || !prop->value) 86 continue; 87 88 mid = *((uint32_t *) prop->value); 89 if (CPU->arch.mid == mid) { 90 /* 91 * Skip the current CPU. 92 */ 93 continue; 121 if (is_us() || is_us_iii()) { 122 node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); 123 for (i = 0; node; 124 node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) 125 wakeup_cpu(node); 126 } else if (is_us_iv()) { 127 node = ofw_tree_find_child(cpus_parent(), "cmp"); 128 while (node) { 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"); 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 }
Note:
See TracChangeset
for help on using the changeset viewer.
