patch-2.2.3 linux/arch/alpha/boot/main.c

Next file: linux/arch/alpha/defconfig
Previous file: linux/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.2/linux/arch/alpha/boot/main.c linux/arch/alpha/boot/main.c
@@ -22,61 +22,27 @@
 extern int vsprintf(char *, const char *, va_list);
 extern unsigned long switch_to_osf_pal(unsigned long nr,
 	struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
-	unsigned long vptb, unsigned long *kstk);
-
-int printk(const char * fmt, ...)
-{
-	va_list args;
-	int i, j, written, remaining, num_nl;
-	static char buf[1024];
-	char * str;
-
-	va_start(args, fmt);
-	i = vsprintf(buf, fmt, args);
-	va_end(args);
-
-	/* expand \n into \r\n: */
-
-	num_nl = 0;
-	for (j = 0; j < i; ++j) {
-	    if (buf[j] == '\n')
-	    	++num_nl;
-	}
-	remaining = i + num_nl;
-	for (j = i - 1; j >= 0; --j) {
-	    buf[j + num_nl] = buf[j];
-	    if (buf[j] == '\n') {
-	    	--num_nl;
-		buf[j + num_nl] = '\r';
-	    }
-	}
-
-	str = buf;
-	do {
-	    written = puts(str, remaining);
-	    remaining -= written;
-	    str += written;
-	} while (remaining > 0);
-	return i;
-}
-
-#define hwrpb (*INIT_HWRPB)
+	unsigned long *vptb);
+struct hwrpb_struct *hwrpb = INIT_HWRPB;
+static struct pcb_struct pcb_va[1];
 
 /*
  * Find a physical address of a virtual object..
  *
  * This is easy using the virtual page table address.
  */
-struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
+
+static inline void *
+find_pa(unsigned long *vptb, void *ptr)
 {
-	unsigned long address = (unsigned long) pcb;
+	unsigned long address = (unsigned long) ptr;
 	unsigned long result;
 
 	result = vptb[address >> 13];
 	result >>= 32;
 	result <<= 13;
 	result |= address & 0x1fff;
-	return (struct pcb_struct *) result;
+	return (void *) result;
 }	
 
 /*
@@ -88,30 +54,19 @@
  * code has the L1 page table identity-map itself in the second PTE
  * in the L1 page table. Thus the L1-page is virtually addressable
  * itself (through three levels) at virtual address 0x200802000.
- *
- * As we don't want it there anyway, we also move the L1 self-map
- * up as high as we can, so that the last entry in the L1 page table
- * maps the page tables.
- *
- * As a result, the OSF/1 pal-code will instead use a virtual page table
- * map located at 0xffffffe00000000.
  */
-#define pcb_va ((struct pcb_struct *) 0x20000000)
-#define old_vptb (0x0000000200000000UL)
-#define new_vptb (0xfffffffe00000000UL)
-void pal_init(void)
+
+#define VPTB	((unsigned long *) 0x200000000)
+#define L1	((unsigned long *) 0x200802000)
+
+void
+pal_init(void)
 {
-	unsigned long i, rev, sum;
-	unsigned long *L1, *l;
+	unsigned long i, rev;
 	struct percpu_struct * percpu;
 	struct pcb_struct * pcb_pa;
 
-	/* Find the level 1 page table and duplicate it in high memory */
-	L1 = (unsigned long *) 0x200802000UL; /* (1<<33 | 1<<23 | 1<<13) */
-	L1[1023] = L1[1];
-
-	percpu = (struct percpu_struct *) (hwrpb.processor_offset + (unsigned long) &hwrpb),
-		
+	/* Create the dummy PCB.  */
 	pcb_va->ksp = 0;
 	pcb_va->usp = 0;
 	pcb_va->ptbr = L1[1] >> 32;
@@ -119,39 +74,32 @@
 	pcb_va->pcc = 0;
 	pcb_va->unique = 0;
 	pcb_va->flags = 1;
-	pcb_pa = find_pa((unsigned long *) old_vptb, pcb_va);
-	printk("Switching to OSF PAL-code .. ");
+	pcb_va->res1 = 0;
+	pcb_va->res2 = 0;
+	pcb_pa = find_pa(VPTB, pcb_va);
+
 	/*
 	 * a0 = 2 (OSF)
-	 * a1 = return address, but we give the asm the virtual addr of the PCB
+	 * a1 = return address, but we give the asm the vaddr of the PCB
 	 * a2 = physical addr of PCB
 	 * a3 = new virtual page table pointer
-	 * a4 = KSP (but we give it 0, asm sets it)
+	 * a4 = KSP (but the asm sets it)
 	 */
-	i = switch_to_osf_pal(
-		2,
-		pcb_va,
-		pcb_pa,
-		new_vptb,
-		0);
+	srm_printk("Switching to OSF PAL-code .. ");
+
+	i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
 	if (i) {
-		printk("failed, code %ld\n", i);
+		srm_printk("failed, code %ld\n", i);
 		halt();
 	}
+
+	percpu = (struct percpu_struct *)
+		(INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
 	rev = percpu->pal_revision = percpu->palcode_avail[2];
 
-	hwrpb.vptb = new_vptb;
+	srm_printk("Ok (rev %lx)\n", rev);
 
-	/* update checksum: */
-	sum = 0;
-	for (l = (unsigned long *) &hwrpb; l < (unsigned long *) &hwrpb.chksum; ++l)
-		sum += *l;
-	hwrpb.chksum = sum;
-
-	printk("Ok (rev %lx)\n", rev);
-	/* remove the old virtual page-table mapping */
-	L1[1] = 0;
-	flush_tlb_all();
+	tbia(); /* do it directly in case we are SMP */
 }
 
 static inline long openboot(void)
@@ -159,15 +107,15 @@
 	char bootdev[256];
 	long result;
 
-	result = dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255);
+	result = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255);
 	if (result < 0)
 		return result;
-	return dispatch(CCB_OPEN, bootdev, result & 255);
+	return srm_dispatch(CCB_OPEN, bootdev, result & 255);
 }
 
 static inline long close(long dev)
 {
-	return dispatch(CCB_CLOSE, dev);
+	return srm_dispatch(CCB_CLOSE, dev);
 }
 
 static inline long load(long dev, unsigned long addr, unsigned long count)
@@ -176,15 +124,15 @@
 	extern char _end;
 	long result, boot_size = &_end - (char *) BOOT_ADDR;
 
-	result = dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255);
+	result = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255);
 	if (result < 0)
 		return result;
 	result &= 255;
 	bootfile[result] = '\0';
 	if (result)
-		printk("Boot file specification (%s) not implemented\n",
+		srm_printk("Boot file specification (%s) not implemented\n",
 		       bootfile);
-	return dispatch(CCB_READ, dev, count, addr, boot_size/512 + 1);
+	return srm_dispatch(CCB_READ, dev, count, addr, boot_size/512 + 1);
 }
 
 /*
@@ -208,27 +156,27 @@
 	int nbytes;
 	char envval[256];
 
-	printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n");
-	if (hwrpb.pagesize != 8192) {
-		printk("Expected 8kB pages, got %ldkB\n", hwrpb.pagesize >> 10);
+	srm_printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n");
+	if (INIT_HWRPB->pagesize != 8192) {
+		srm_printk("Expected 8kB pages, got %ldkB\n", INIT_HWRPB->pagesize >> 10);
 		return;
 	}
 	pal_init();
 	dev = openboot();
 	if (dev < 0) {
-		printk("Unable to open boot device: %016lx\n", dev);
+		srm_printk("Unable to open boot device: %016lx\n", dev);
 		return;
 	}
 	dev &= 0xffffffff;
-	printk("Loading vmlinux ...");
+	srm_printk("Loading vmlinux ...");
 	i = load(dev, START_ADDR, KERNEL_SIZE);
 	close(dev);
 	if (i != KERNEL_SIZE) {
-		printk("Failed (%lx)\n", i);
+		srm_printk("Failed (%lx)\n", i);
 		return;
 	}
 
-	nbytes = dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
+	nbytes = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
 			  envval, sizeof(envval));
 	if (nbytes < 0) {
 		nbytes = 0;
@@ -236,7 +184,7 @@
 	envval[nbytes] = '\0';
 	strcpy((char*)ZERO_PAGE, envval);
 
-	printk(" Ok\nNow booting the kernel\n");
+	srm_printk(" Ok\nNow booting the kernel\n");
 	runkernel();
 	for (i = 0 ; i < 0x100000000 ; i++)
 		/* nothing */;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)