patch-2.1.92 linux/arch/alpha/mm/init.c

Next file: linux/arch/arm/config.in
Previous file: linux/arch/alpha/mm/fault.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.91/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c
@@ -26,6 +26,8 @@
 extern void die_if_kernel(char *,struct pt_regs *,long);
 extern void show_net_buffers(void);
 
+struct thread_struct * original_pcb_ptr;
+
 /*
  * BAD_PAGE is the page that is used for page faults when linux
  * is out-of-memory. Older versions of linux just did a
@@ -81,15 +83,22 @@
 
 extern unsigned long free_area_init(unsigned long, unsigned long);
 
-static void load_PCB(struct thread_struct * pcb)
+static struct thread_struct * load_PCB(struct thread_struct * pcb)
 {
+	struct thread_struct *old_pcb;
+
 	__asm__ __volatile__(
-		"stq $30,0(%0)\n\t"
-		"bis %0,%0,$16\n\t"
-		"call_pal %1"
-		: /* no outputs */
+		"stq $30,0(%1)\n\t"
+		"bis %1,%1,$16\n\t"
+#ifdef CONFIG_ALPHA_DP264
+		"zap $16,0xe0,$16\n\t"
+#endif /* DP264 */
+		"call_pal %2\n\t"
+		"bis $0,$0,%0"
+		: "=r" (old_pcb)
 		: "r" (pcb), "i" (PAL_swpctx)
 		: "$0", "$1", "$16", "$22", "$23", "$24", "$25");
+	return old_pcb;
 }
 
 /*
@@ -107,7 +116,8 @@
 	start_mem = free_area_init(start_mem, end_mem);
 
 	/* find free clusters, update mem_map[] accordingly */
-	memdesc = (struct memdesc_struct *) (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
+	memdesc = (struct memdesc_struct *)
+		(INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
 	cluster = memdesc->cluster;
 	for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
 		unsigned long pfn, nr;
@@ -129,15 +139,46 @@
 	memset((void *) ZERO_PAGE, 0, PAGE_SIZE);
 	memset(swapper_pg_dir, 0, PAGE_SIZE);
 	newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
-	pgd_val(swapper_pg_dir[1023]) = (newptbr << 32) | pgprot_val(PAGE_KERNEL);
+	pgd_val(swapper_pg_dir[1023]) =
+		(newptbr << 32) | pgprot_val(PAGE_KERNEL);
 	init_task.tss.ptbr = newptbr;
 	init_task.tss.pal_flags = 1;	/* set FEN, clear everything else */
 	init_task.tss.flags = 0;
-	load_PCB(&init_task.tss);
+	original_pcb_ptr =
+	  phys_to_virt((unsigned long)load_PCB(&init_task.tss));
+#if 0
+printk("OKSP 0x%lx OPTBR 0x%lx\n",
+       original_pcb_ptr->ksp, original_pcb_ptr->ptbr);
+#endif
 
-	flush_tlb_all();
+	tbia();
 	return start_mem;
 }
+
+#ifdef __SMP__
+/*
+ * paging_init_secondary(), called ONLY by secondary CPUs,
+ * sets up current->tss contents appropriately and does a load_PCB.
+ * note that current should be pointing at the idle thread task struct
+ * for this CPU.
+ */
+void paging_init_secondary(void)
+{
+	current->tss.ptbr = init_task.tss.ptbr;
+	current->tss.pal_flags = 1;
+	current->tss.flags = 0;
+
+#if 0
+printk("paging_init_secondary: KSP 0x%lx PTBR 0x%lx\n",
+       current->tss.ksp, current->tss.ptbr);
+#endif
+
+	load_PCB(&current->tss);
+	tbia();
+
+	return;
+}
+#endif /* __SMP__ */
 
 void mem_init(unsigned long start_mem, unsigned long end_mem)
 {

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov