void __init smp_store_cpu_info(int id)
{
- int cpu_node;
+ int cpu_node, def;
/* multiplier and counter set by
smp_setup_percpu_timer() */
cpu_data(id).idle_volume = 1;
+ def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024));
cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size",
- 16 * 1024);
+ def);
+
+ def = 32;
cpu_data(id).dcache_line_size =
- prom_getintdefault(cpu_node, "dcache-line-size", 32);
+ prom_getintdefault(cpu_node, "dcache-line-size", def);
+
+ def = 16 * 1024;
cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size",
- 16 * 1024);
+ def);
+
+ def = 32;
cpu_data(id).icache_line_size =
- prom_getintdefault(cpu_node, "icache-line-size", 32);
+ prom_getintdefault(cpu_node, "icache-line-size", def);
+
+ def = ((tlb_type == hypervisor) ?
+ (3 * 1024 * 1024) :
+ (4 * 1024 * 1024));
cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size",
- 4 * 1024 * 1024);
+ def);
+
+ def = 64;
cpu_data(id).ecache_line_size =
- prom_getintdefault(cpu_node, "ecache-line-size", 64);
+ prom_getintdefault(cpu_node, "ecache-line-size", def);
+
printk("CPU[%d]: Caches "
"D[sz(%d):line_sz(%d)] "
"I[sz(%d):line_sz(%d)] "
__local_per_cpu_offset = __per_cpu_offset(cpuid);
if (tlb_type == hypervisor)
- sun4v_register_fault_status();
+ sun4v_ktsb_register();
__flush_tlb_all();
spin_unlock_irqrestore(&itc_sync_lock, flags);
}
+extern void sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int load);
+
extern unsigned long sparc64_cpu_startup;
/* The OBP cpu startup callback truncates the 3rd arg cookie to
unsigned long cookie =
(unsigned long)(&cpu_new_thread);
struct task_struct *p;
- int timeout, ret, cpu_node;
+ int timeout, ret;
p = fork_idle(cpu);
callin_flag = 0;
cpu_new_thread = task_thread_info(p);
cpu_set(cpu, cpu_callout_map);
- cpu_find_by_mid(cpu, &cpu_node);
- prom_startcpu(cpu_node, entry, cookie);
+ if (tlb_type == hypervisor) {
+ /* Alloc the mondo queues, cpu will load them. */
+ sun4v_init_mondo_queues(0, cpu, 1, 0);
+
+ prom_startcpu_cpuid(cpu, entry, cookie);
+ } else {
+ int cpu_node;
+
+ cpu_find_by_mid(cpu, &cpu_node);
+ prom_startcpu(cpu_node, entry, cookie);
+ }
for (timeout = 0; timeout < 5000000; timeout++) {
if (callin_flag)
break;
udelay(100);
}
+
if (callin_flag) {
ret = 0;
} else {
}
}
-#if 0
/* Multi-cpu list version. */
static int init_cpu_list(u16 *list, cpumask_t mask)
{
"2" (arg1), "3" (arg2),
"i" (HV_FAST_TRAP)
: "memory");
- if (likely(func == HV_EOK))
+ if (likely(arg0 == HV_EOK))
break;
if (unlikely(++retries > 100)) {
put_cpu();
}
-#else
-/* Single-cpu list version. */
-static void hypervisor_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
-{
- int this_cpu = get_cpu();
- struct trap_per_cpu *tb = &trap_block[this_cpu];
- u64 *mondo = __va(tb->cpu_mondo_block_pa);
- u16 *cpu_list = __va(tb->cpu_list_pa);
- int i;
-
- mondo[0] = data0;
- mondo[1] = data1;
- mondo[2] = data2;
- wmb();
-
- for_each_cpu_mask(i, mask) {
- int retries = 0;
-
- do {
- register unsigned long func __asm__("%o5");
- register unsigned long arg0 __asm__("%o0");
- register unsigned long arg1 __asm__("%o1");
- register unsigned long arg2 __asm__("%o2");
-
- cpu_list[0] = i;
- func = HV_FAST_CPU_MONDO_SEND;
- arg0 = 1;
- arg1 = tb->cpu_list_pa;
- arg2 = tb->cpu_mondo_block_pa;
-
- __asm__ __volatile__("ta %8"
- : "=&r" (func), "=&r" (arg0),
- "=&r" (arg1), "=&r" (arg2)
- : "0" (func), "1" (arg0),
- "2" (arg1), "3" (arg2),
- "i" (HV_FAST_TRAP)
- : "memory");
- if (likely(func == HV_EOK))
- break;
-
- if (unlikely(++retries > 100)) {
- printk("CPU[%d]: sun4v mondo error %lu\n",
- this_cpu, func);
- break;
- }
-
- udelay(2 * i);
- } while (1);
- }
-
- put_cpu();
-}
-#endif
/* Send cross call to all processors mentioned in MASK
* except self.
if (!cpu_isset(cpu, cpu_online_map)) {
ret = -ENODEV;
} else {
- smp_synchronize_one_tick(cpu);
+ /* On SUN4V, writes to %tick and %stick are
+ * not allowed.
+ */
+ if (tlb_type != hypervisor)
+ smp_synchronize_one_tick(cpu);
}
}
return ret;