summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/mips64/sgi-ip27/TODO2
-rw-r--r--arch/mips64/sgi-ip27/ip27-init.c65
-rw-r--r--arch/mips64/sgi-ip27/ip27-setup.c8
-rw-r--r--arch/mips64/sgi-ip27/ip27-timer.c45
4 files changed, 94 insertions, 26 deletions
diff --git a/arch/mips64/sgi-ip27/TODO b/arch/mips64/sgi-ip27/TODO
index eabbdc891..fbe55ea5c 100644
--- a/arch/mips64/sgi-ip27/TODO
+++ b/arch/mips64/sgi-ip27/TODO
@@ -4,7 +4,7 @@ not to write to the IOC3 ever.
3. Need to figure out why address swaizzling is needed in inw/outw for
Qlogic scsi controllers.
4. Need to integrate ip27-klconfig.c:find_lboard and
-ip27-init.c:find_lbaord_real.
+ip27-init.c:find_lbaord_real. DONE
5. Is it okay to set calias space on all nodes as 0, instead of 8k as
in irix?
6. Investigate why things do not work without the setup_test() call
diff --git a/arch/mips64/sgi-ip27/ip27-init.c b/arch/mips64/sgi-ip27/ip27-init.c
index 882e58f33..fea427a16 100644
--- a/arch/mips64/sgi-ip27/ip27-init.c
+++ b/arch/mips64/sgi-ip27/ip27-init.c
@@ -15,6 +15,7 @@
#include <asm/smp.h>
#include <asm/processor.h>
#include <asm/sn/launch.h>
+#include <asm/sn/sn_private.h>
#define CPU_NONE (cpuid_t)-1
@@ -23,11 +24,17 @@
#define CPUMASK_CLRB(p, bit) (p) &= ~(1ULL << (bit))
#define CPUMASK_TSTB(p, bit) ((p) & (1ULL << (bit)))
+#define CNODEMASK_CLRALL(p) (p) = 0
+#define CNODEMASK_TSTB(p, bit) ((p) & (1ULL << (bit)))
+#define CNODEMASK_SETB(p, bit) ((p) |= 1ULL << (bit))
+
cpumask_t boot_cpumask;
static volatile cpumask_t boot_barrier;
hubreg_t region_mask = 0;
static int fine_mode = 0;
int maxcpus;
+static spinlock_t hub_mask_lock = SPIN_LOCK_UNLOCKED;
+static cnodemask_t hub_init_mask;
cnodeid_t nasid_to_compact_node[MAX_NASIDS];
nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
@@ -194,6 +201,7 @@ void mlreset (void)
initpdas();
gen_region_mask(&region_mask, numnodes);
+ CNODEMASK_CLRALL(hub_init_mask);
/*
* Set all nodes' calias sizes to 8k
@@ -269,28 +277,67 @@ void sn_mp_setup(void)
#endif
}
+void per_hub_init(cnodeid_t cnode)
+{
+ cnodemask_t done;
+
+ spin_lock(&hub_mask_lock);
+ /* Test our bit. */
+ if (!(done = CNODEMASK_TSTB(hub_init_mask, cnode))) {
+ /* Turn our bit on in the mask. */
+ CNODEMASK_SETB(hub_init_mask, cnode);
+ }
+ spin_unlock(&hub_mask_lock);
+
+ /*
+ * Do the actual initialization if it hasn't been done yet.
+ * We don't need to hold a lock for this work.
+ */
+ if (!done) {
+ hub_rtc_init(cnode);
+ }
+}
+
+/*
+ * This is similar to hard_smp_processor_id().
+ */
+cpuid_t getcpuid(void)
+{
+ klcpu_t *klcpu;
+
+ klcpu = nasid_slice_to_cpuinfo(get_nasid(),LOCAL_HUB_L(PI_CPU_NUM));
+ return klcpu->cpu_info.virtid;
+}
+
void per_cpu_init(void)
{
#if 0
cpuid_t cpu = getcpuid();
+#endif
cnodeid_t cnode = get_compact_nodeid();
+#if 0
intr_init();
+#endif
+ set_cp0_status(ST0_IM, 0);
+ cpu_time_init();
per_hub_init(cnode);
+#if 0
install_cpuintr(cpu);
install_tlbintr(cpu);
#endif
}
-/*
- * This is similar to hard_smp_processor_id().
- */
-cpuid_t getcpuid(void)
+cnodeid_t get_compact_nodeid(void)
{
- klcpu_t *klcpu;
+ nasid_t nasid;
- klcpu = nasid_slice_to_cpuinfo(get_nasid(),LOCAL_HUB_L(PI_CPU_NUM));
- return klcpu->cpu_info.virtid;
+ nasid = get_nasid();
+ /*
+ * Map the physical node id to a virtual node id (virtual node ids
+ * are contiguous).
+ */
+ return NASID_TO_COMPACT_NODEID(nasid);
}
#ifdef CONFIG_SMP
@@ -318,8 +365,8 @@ void cboot(void)
{
atomic_inc(&numstarted);
CPUMASK_CLRB(boot_barrier, getcpuid()); /* needs atomicity */
-#if 0
per_cpu_init();
+#if 0
ecc_init();
bte_lateinit();
init_mfhi_war();
@@ -337,7 +384,7 @@ void allowboot(void)
extern void bootstrap(void);
sn_mp_setup();
- per_cpu_init();
+ /* Master has already done per_cpu_init() */
#if 0
bte_lateinit();
ecc_init();
diff --git a/arch/mips64/sgi-ip27/ip27-setup.c b/arch/mips64/sgi-ip27/ip27-setup.c
index 7a72a24bb..217fef099 100644
--- a/arch/mips64/sgi-ip27/ip27-setup.c
+++ b/arch/mips64/sgi-ip27/ip27-setup.c
@@ -20,6 +20,7 @@
#include <asm/ioc3.h>
#include <asm/mipsregs.h>
#include <asm/sn/arch.h>
+#include <asm/sn/sn_private.h>
#include <asm/pci/bridge.h>
#include <asm/paccess.h>
@@ -90,8 +91,6 @@ static void __init verify_mode(void)
static void __init pcibr_setup(void)
{
bridge_t *bridge = (bridge_t *) 0x9200000008000000;
- bridgereg_t devreg;
- int slot;
/*
* Clear all pending interrupts.
@@ -109,7 +108,10 @@ void __init ip27_setup(void)
nasid_t nid;
hubreg_t p, e;
- set_cp0_status(ST0_IM, 0);
+ /*
+ * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
+ */
+ per_cpu_init();
nid = get_nasid();
printk("IP27: Running on node %d.\n", nid);
diff --git a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c
index 6f9abac50..0a98885a5 100644
--- a/arch/mips64/sgi-ip27/ip27-timer.c
+++ b/arch/mips64/sgi-ip27/ip27-timer.c
@@ -19,6 +19,7 @@
#include <asm/sn/klconfig.h>
#include <asm/sn/arch.h>
#include <asm/sn/addrs.h>
+#include <asm/sn/sn_private.h>
#include <asm/sn/sn0/ip27.h>
#include <asm/sn/sn0/hub.h>
@@ -44,7 +45,6 @@ static int set_rtc_mmss(unsigned long nowtime)
{
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
- unsigned char save_control, save_freq_select;
struct m48t35_rtc *rtc;
nasid_t nid;
@@ -223,7 +223,8 @@ static unsigned long __init get_m48t35_time(void)
nasid_t nid;
nid = get_nasid();
- rtc = KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0;
+ rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
+ IOC3_BYTEBUS_DEV0);
rtc->control |= M48T35_RTC_READ;
sec = rtc->sec;
@@ -250,13 +251,16 @@ extern void ioc3_eth_init(void);
void __init time_init(void)
{
+ xtime.tv_sec = get_m48t35_time();
+ xtime.tv_usec = 0;
+}
+
+void __init cpu_time_init(void)
+{
lboard_t *board;
klcpu_t *cpu;
int cpuid;
- xtime.tv_sec = get_m48t35_time();
- xtime.tv_usec = 0;
-
/* Don't use ARCS. ARCS is fragile. Klconfig is simple and sane. */
board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
if (!board)
@@ -267,15 +271,30 @@ void __init time_init(void)
if (!cpu)
panic("No information about myself?");
+ printk("CPU %d clock is %dMHz.\n", cpu->cpu_speed, smp_processor_id());
printk("CPU clock is %dMHz.\n", cpu->cpu_speed);
- /* Don't worry about second CPU, it's disabled. */
- LOCAL_HUB_S(PI_RT_EN_A, 1);
- LOCAL_HUB_S(PI_PROF_EN_A, 0);
- ct_cur = CYCLES_PER_JIFFY;
- LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur);
- LOCAL_HUB_S(PI_RT_COUNT, 0);
- LOCAL_HUB_S(PI_RT_PEND_A, 0);
-
set_cp0_status(SRB_TIMOCLK, SRB_TIMOCLK);
}
+
+void __init hub_rtc_init(cnodeid_t cnode)
+{
+ /*
+ * We only need to initialize the current node.
+ * If this is not the current node then it is a cpuless
+ * node and timeouts will not happen there.
+ */
+ if (get_compact_nodeid() == cnode) {
+ LOCAL_HUB_S(PI_RT_EN_A, 1);
+ LOCAL_HUB_S(PI_RT_EN_B, 1);
+ LOCAL_HUB_S(PI_PROF_EN_A, 0);
+ LOCAL_HUB_S(PI_PROF_EN_B, 0);
+ ct_cur = CYCLES_PER_JIFFY;
+ LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur);
+ LOCAL_HUB_S(PI_RT_COUNT, 0);
+ LOCAL_HUB_S(PI_RT_PEND_A, 0);
+ LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur);
+ LOCAL_HUB_S(PI_RT_COUNT, 0);
+ LOCAL_HUB_S(PI_RT_PEND_B, 0);
+ }
+}