/branches/sparc/kernel/arch/sparc64/include/cpu_family.h |
---|
File deleted |
\ No newline at end of file |
/branches/sparc/kernel/arch/sparc64/include/regdef.h |
---|
60,11 → 60,7 |
* FIREPLANE_CONFIG register on US3. |
*/ |
#define ICBUS_CONFIG_MID_SHIFT 17 |
#if defined (US) |
#define ICBUS_CONFIG_MID_MASK 0x1f |
#elif defined (US3) |
#define ICBUS_CONFIG_MID_MASK 0x3ff |
#endif |
#endif |
/branches/sparc/kernel/arch/sparc64/include/register.h |
---|
126,16 → 126,10 |
union icbus_config { |
uint64_t value; |
struct { |
#if defined (US) |
uint64_t : 34; |
unsigned pcon : 8; /**< Processor configuration. */ |
unsigned mid : 5; /**< Module (processor) ID register. */ |
unsigned pcap : 17; /**< Processor capabilities. */ |
#elif defined (US3) |
uint64_t : 37; |
unsigned mid : 10; /**< Module (processor) ID register. */ |
uint64_t : 17; |
#endif |
} __attribute__ ((packed)); |
}; |
typedef union icbus_config icbus_config_t; |
/branches/sparc/kernel/arch/sparc64/include/cpu_node.h |
---|
37,11 → 37,19 |
#include <genarch/ofw/ofw_tree.h> |
/* |
* Name of the CPU OFW node property, which holds the MID (processor ID). |
* US uses UPA, US3 uses Fireplane, hence the properties names are different. |
*/ |
#if defined (US) |
#define PORTID_NAME "upa-portid" |
#elif defined (US3) |
#define PORTID_NAME "portid" |
#endif |
/** Finds the parent node of all the CPU nodes (nodes named "cpu" or "cmp"). |
/** Finds the parent node of all the CPU nodes. |
* |
* Depending on the machine type (and possibly the OFW version), CPUs can be |
* at "/" or at "/ssm@0,0". |
* Depending on the OFW version, CPUS can be at "/" or at "/ssm@0,0". |
*/ |
static inline ofw_tree_node_t *cpus_parent(void) |
{ |
/branches/sparc/kernel/arch/sparc64/src/smp/smp.c |
---|
35,7 → 35,6 |
#include <smp/smp.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <cpu.h> |
#include <arch/cpu_family.h> |
#include <arch/cpu.h> |
#include <arch.h> |
#include <config.h> |
63,54 → 62,15 |
ofw_tree_node_t *node; |
count_t cnt = 0; |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
cnt++; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
cnt += 2; |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
} |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
cnt++; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
config.cpu_count = max(1, cnt); |
} |
/** |
* Wakes up the CPU which is represented by the "node" OFW tree node. |
* If "node" represents the current CPU, calling the function has |
* no effect. |
*/ |
static void wakeup_cpu(ofw_tree_node_t *node) |
{ |
uint32_t mid; |
ofw_tree_property_t *prop; |
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */ |
prop = ofw_tree_getprop(node, "upa-portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "cpuid"); |
if (!prop || prop->value == NULL) |
return; |
mid = *((uint32_t *) prop->value); |
if (CPU->arch.mid == mid) |
return; |
waking_up_mid = mid; |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) |
printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n", |
__func__, mid); |
} |
/** Wake application processors up. */ |
void kmp(void *arg) |
{ |
117,19 → 77,31 |
ofw_tree_node_t *node; |
int i; |
printf("\nGoing to wake CPUs up.\n"); |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) |
wakeup_cpu(node); |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
wakeup_cpu(ofw_tree_find_child(node, "cpu@0")); |
wakeup_cpu(ofw_tree_find_child(node, "cpu@1")); |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) { |
uint32_t mid; |
ofw_tree_property_t *prop; |
prop = ofw_tree_getprop(node, PORTID_NAME); |
if (!prop || !prop->value) |
continue; |
mid = *((uint32_t *) prop->value); |
if (CPU->arch.mid == mid) { |
/* |
* Skip the current CPU. |
*/ |
continue; |
} |
/* |
* Processor with ID == mid can proceed with its initialization. |
*/ |
waking_up_mid = mid; |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) |
printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n", |
__func__, mid); |
} |
} |
/branches/sparc/kernel/arch/sparc64/src/cpu/cpu.c |
---|
32,7 → 32,6 |
/** @file |
*/ |
#include <arch/cpu_family.h> |
#include <cpu.h> |
#include <arch.h> |
#include <genarch/ofw/ofw_tree.h> |
40,38 → 39,6 |
#include <print.h> |
#include <arch/cpu_node.h> |
/** |
* Finds out the clock frequency of the current CPU. |
* |
* @param node node representing the current CPU in the OFW tree |
* @return clock frequency if "node" is the current CPU and no error |
* occurs, -1 if "node" is not the current CPU or on error |
*/ |
static int find_cpu_frequency(ofw_tree_node_t *node) |
{ |
ofw_tree_property_t *prop; |
uint32_t mid; |
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */ |
prop = ofw_tree_getprop(node, "upa-portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "cpuid"); |
if (prop && prop->value) { |
mid = *((uint32_t *) prop->value); |
if (mid == CPU->arch.mid) { |
prop = ofw_tree_getprop(node, "clock-frequency"); |
if (prop && prop->value) { |
return *((uint32_t *) prop->value); |
} |
} |
} |
return -1; |
} |
/** Perform sparc64 specific initialization of the processor structure for the |
* current processor. |
*/ |
78,6 → 45,7 |
void cpu_arch_init(void) |
{ |
ofw_tree_node_t *node; |
uint32_t mid; |
uint32_t clock_frequency = 0; |
icbus_config_t icbus_config; |
87,28 → 55,24 |
/* |
* Detect processor frequency. |
*/ |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
int f = find_cpu_frequency(node); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
ofw_tree_property_t *prop; |
prop = ofw_tree_getprop(node, PORTID_NAME); |
if (prop && prop->value) { |
mid = *((uint32_t *) prop->value); |
if (mid == CPU->arch.mid) { |
prop = ofw_tree_getprop(node, |
"clock-frequency"); |
if (prop && prop->value) |
clock_frequency = *((uint32_t *) |
prop->value); |
} |
} |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
int f; |
f = find_cpu_frequency(ofw_tree_find_child(node, "cpu@0")); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
f = find_cpu_frequency(ofw_tree_find_child(node, "cpu@1")); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
} |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
CPU->arch.clock_frequency = clock_frequency; |
tick_init(); |
} |