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
- Lines: 97
- Date:
Mon Mar 30 00:21:39 1998
- Orig file:
v2.1.91/linux/arch/alpha/mm/init.c
- Orig date:
Tue May 13 22:41:00 1997
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(¤t->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