Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3582 → Rev 3581

/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();
}