patch-2.1.97 linux/arch/ppc/kernel/setup.c

Next file: linux/arch/ppc/kernel/signal.c
Previous file: linux/arch/ppc/kernel/residual.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.96/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
@@ -1,5 +1,5 @@
 /*
- * $Id: setup.c,v 1.48 1998/01/01 10:04:44 paulus Exp $
+ * $Id: setup.c,v 1.68 1998/04/07 08:20:33 geert Exp $
  * Common prep/pmac/chrp boot and setup code.
  */
 
@@ -13,10 +13,26 @@
 
 #include <asm/adb.h>
 #include <asm/cuda.h>
+#include <asm/pmu.h>
 #include <asm/residual.h>
 #include <asm/io.h>
 #include <asm/ide.h>
 #include <asm/prom.h>
+#include <asm/processor.h>
+#ifdef CONFIG_MBX
+#include <asm/mbx.h>
+#endif
+/* ifdef APUS specific stuff until the merge is completed. -jskov */
+#ifdef CONFIG_APUS
+#include <asm/bootinfo.h>
+#include <asm/setup.h>
+#include <asm/amigappc.h>
+extern unsigned long m68k_machtype;
+extern void amiga_reset (void);
+extern struct mem_info m68k_ramdisk;
+extern int m68k_parse_bootinfo(const struct bi_record *);
+extern char _end[];
+#endif
 
 extern char cmd_line[512];
 char saved_command_line[256];
@@ -26,13 +42,13 @@
 unsigned long ISA_DMA_THRESHOLD;
 unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
 int _machine;
+/* if we have openfirmware */
+unsigned long have_of;
 #endif /* ! CONFIG_MACH_SPECIFIC */
 
 /* copy of the residual data */
 RESIDUAL res;
 int _prep_type;
-/* if we have openfirmware */
-unsigned long have_of;
 
 /*
  * Perhaps we can put the pmac screen_info[] here
@@ -40,6 +56,7 @@
  * Until we get multiple-console support in here
  * that is.  -- Cort
  */ 
+#ifndef CONFIG_MBX
 #if !defined(CONFIG_PMAC_CONSOLE)
 struct screen_info screen_info = {
 	0, 25,			/* orig-x, orig-y */
@@ -65,29 +82,66 @@
 }
 #endif
 
+#else /* CONFIG_MBX */
+
+/* We need this to satisfy some external references until we can
+ * strip the kernel down.
+ */
+struct screen_info screen_info = {
+	0, 25,			/* orig-x, orig-y */
+	{ 0, 0 },		/* unused */
+	0,			/* orig-video-page */
+	0,			/* orig-video-mode */
+	80,			/* orig-video-cols */
+	0,0,0,			/* ega_ax, ega_bx, ega_cx */
+	25,			/* orig-video-lines */
+	0,			/* orig-video-isVGA */
+	16			/* orig-video-points */
+};
+#endif /* CONFIG_MBX */
+
 /* cmd is ignored for now... */
 void machine_restart(char *cmd)
 {
 	struct adb_request req;
 	unsigned long flags;
 	unsigned long i = 10000;
-#if 0	
+#if 0
 	int err;
 #endif	
 
 	switch(_machine)
 	{
 	case _MACH_Pmac:
-		cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM);
-		for (;;)
-			cuda_poll();
+		switch (adb_hardware) {
+		case ADB_VIACUDA:
+			cuda_request(&req, NULL, 2, CUDA_PACKET,
+				     CUDA_RESET_SYSTEM);
+			for (;;)
+				cuda_poll();
+			break;
+		case ADB_VIAPMU:
+			pmu_request(&req, NULL, 1, PMU_RESET);
+			for (;;)
+				pmu_poll();
+			break;
+		default:
+		}
 		break;
+
 	case _MACH_chrp:
 #if 0		/* RTAS doesn't seem to work on Longtrail.
 		   For now, do it the same way as the PReP. */
-		err = call_rtas("system-reboot", 0, 1, NULL);
+	        /*err = call_rtas("system-reboot", 0, 1, NULL);
 		printk("RTAS system-reboot returned %d\n", err);
-		for (;;);
+		for (;;);*/
+		
+		{
+			extern unsigned int rtas_entry, rtas_data, rtas_size;
+			unsigned long status, value;
+			printk("rtas_entry: %08x rtas_data: %08x rtas_size: %08x\n",
+			       rtas_entry,rtas_data,rtas_size);
+	}
 #endif
 	case _MACH_prep:
 		_disable_interrupts();
@@ -104,6 +158,23 @@
 		while ( i != 0 ) i++;
 		panic("restart failed\n");
 		break;
+	case _MACH_apus:
+		cli();
+		/* APUS:FIXME: Reset the system. Apparently there's
+		 * more magic to it than this!?!?
+		 */
+#if 0
+		APUS_WRITE(APUS_REG_SHADOW, REGSHADOW_SELFRESET);
+		APUS_WRITE(APUS_REG_RESET, 
+			   REGRESET_PPCRESET|REGRESET_M68KRESET|
+			   REGRESET_AMIGARESET|REGRESET_AUXRESET|
+			   REGRESET_SCSIRESET);
+#endif
+		printk("\n**************************************\n");
+		printk("*** You can make a hard reset now! ***\n");
+		printk("**************************************\n");
+		for(;;);
+		break;
 	}
 }
 
@@ -116,9 +187,23 @@
 
 	switch (_machine) {
 	case _MACH_Pmac:
-		cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN);
-		for (;;)
-			cuda_poll();
+		switch (adb_hardware) {
+		case ADB_VIACUDA:
+			cuda_request(&req, NULL, 2, CUDA_PACKET,
+				     CUDA_POWERDOWN);
+			for (;;)
+				cuda_poll();
+			break;
+		case ADB_VIAPMU:
+			pmu_request(&req, NULL, 5, PMU_SHUTDOWN,
+				    'M', 'A', 'T', 'T');
+			for (;;)
+				pmu_poll();
+			break;
+		default:
+		}
+		break;
+
 	case _MACH_chrp:
 #if 0		/* RTAS doesn't seem to work on Longtrail.
 		   For now, do it the same way as the PReP. */
@@ -126,9 +211,19 @@
 		printk("RTAS system-reboot returned %d\n", err);
 		for (;;);
 #endif
+
 	case _MACH_prep:
 		machine_restart(NULL);
+#ifdef CONFIG_APUS
+	case _MACH_apus:
+#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
+		apm_set_power_state(APM_STATE_OFF);
+		for (;;);
+#endif
+#endif
 	}
+	for (;;)
+		;
 }
 
 void machine_halt(void)
@@ -141,18 +236,90 @@
 		machine_power_off();	/* for now */
 #endif
 	}
-	else /* prep or chrp */
+	else /* prep, chrp or apus */
 		machine_restart(NULL);
 
 }
 
+#ifdef CONFIG_BLK_DEV_IDE
 void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq)
 {
-	if ( _machine == _MACH_Pmac )
+	switch (_machine) {
+	case _MACH_Pmac:
 		pmac_ide_init_hwif_ports(p,base,irq);
-	else /* prep or chrp */
+		break;
+	case _MACH_chrp:
+		chrp_ide_init_hwif_ports(p,base,irq);
+		break;
+	case _MACH_prep:
 		prep_ide_init_hwif_ports(p,base,irq);
+		break;
+	}
+}
+#endif
+
+unsigned long cpu_temp(void)
+{
+	unsigned long i, temp, thrm1, dir;
+	int sanity;
 	
+	/*
+	 * setup thrm3 - need to give TAU at least 20us
+	 * to do the compare so assume a 300MHz clock.
+	 * We need 300*20 ticks then.
+	 * -- Cort
+	 */
+	asm("mtspr 1020, %1\n\t"
+	    "mtspr 1021, %1\n\t"
+	    "mtspr 1022, %0\n\t"::
+	    "r" ( ((300*20)<<18) | THRM3_E), "r" (0) );
+		
+#if 0
+	for ( i = 127 ; i >= 0 ; i-- )
+	{
+		asm("mtspr 1020, %0\n\t"::
+		    "r" (THRM1_TID|THRM1_V|(i<<2)) );
+		/* check value */
+		while ( !( thrm1 & THRM1_TIV) )
+			asm("mfspr %0, 1020 \n\t": "=r" (thrm1) );
+		if ( thrm1 & THRM1_TIN )
+		{
+			printk("tin set: %x tiv %x\n", thrm1,thrm1&THRM1_TIV);
+			goto out;
+		}
+
+	}
+#endif
+#if 0
+	i = 32;			/* increment */
+	dir = 1;		/* direction we're checking 0=up 1=down */
+	temp = 64;		/* threshold checking against */
+	while ( i )
+	{
+		_set_THRM1((1<<29) | THRM1_V | (temp<<2) );
+		printk("checking %d in dir %d thrm set to %x/%x\n", temp,dir,
+		       ( (1<<29) | THRM1_V | (temp<<2)),_get_THRM1());
+		/* check value */
+		sanity = 0x0fffffff;
+		while ( (!( thrm1 & THRM1_TIV)) && (sanity--) )
+			thrm1 = _get_THRM1();
+			/*asm("mfspr %0, 1020 \n\t": "=r" (thrm1) );*/
+		if ( ! sanity || sanity==0xffffffff ) printk("no sanity\n");
+		/* temp is not in that direction */
+		if ( !(thrm1 & THRM1_TIN) )
+		{
+			printk("not in that dir thrm1 %x\n",thrm1);
+			if ( dir == 0 ) dir = 1;
+			else dir = 0;
+		}
+		if ( dir ) temp -= i;
+		else temp += i;
+		i /= 2;
+	}
+	asm("mtspr 1020, %0\n\t"
+	    "mtspr 1022, %0\n\t" ::"r" (0) );
+#endif	
+	return temp;
 }
 
 int get_cpuinfo(char *buffer)
@@ -160,9 +327,11 @@
 	extern int pmac_get_cpuinfo(char *);
 	extern int chrp_get_cpuinfo(char *);	
 	extern int prep_get_cpuinfo(char *);
+	extern int apus_get_cpuinfo(char *);
 	unsigned long len = 0;
 	unsigned long bogosum = 0;
 	unsigned long i;
+	unsigned long cr;
 #ifdef __SMP__
 	extern unsigned long cpu_present_map;	
 	extern struct cpuinfo_PPC cpu_data[NR_CPUS];
@@ -202,7 +371,18 @@
 			len += sprintf(len+buffer, "603ev\n");
 			break;
 		case 8:
-			len += sprintf(len+buffer, "750 (Arthur)\n");
+			len += sprintf(len+buffer,"750\n");
+			cr = _get_L2CR();
+			len += sprintf(len+buffer,"L2CR\t\t: %lx\n",cr);
+			if ( cr & (0x1<<1)) cr = 256;
+			else if ( cr & (0x2<<1)) cr = 512;
+			else if ( cr & (0x3<<1)) cr = 1024;
+			else cr = 0;
+			len += sprintf(len+buffer,"on-chip l2\t: "
+				       "%ld KB (%s)\n",
+				       cr,(_get_L2CR()&1) ? "on" : "off");
+			len += sprintf(len+buffer,"temperature \t: %lu C\n",
+				       cpu_temp());
 			break;
 		case 9:
 			len += sprintf(len+buffer, "604e\n");
@@ -216,6 +396,7 @@
 			break;
 		}
 
+
 		/*
 		 * Assume here that all clock rates are the same in a
 		 * smp system.  -- Cort
@@ -290,6 +471,11 @@
 	case _MACH_chrp:
 		len += chrp_get_cpuinfo(buffer+len);
 		break;
+#ifdef CONFIG_APUS
+	case _MACH_apus:
+		len += apus_get_cpuinfo(buffer+len);
+		break;
+#endif
 	}
 	return len;
 }
@@ -302,43 +488,63 @@
 identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
 		 unsigned long r6, unsigned long r7))
 {
-	extern unsigned long initrd_start, initrd_end;
 	extern setup_pci_ptrs(void);
-	unsigned long boot_sdr1;
-	ihandle prom_root;
-	unsigned char type[16], model[16];
-
-	asm("mfspr %0,25\n\t" :"=r" (boot_sdr1));
-
-	/* 
-	 * if we have a sdr1 then we have openfirmware 
-	 * and can ask it what machine we are (chrp/pmac/prep).
-	 * otherwise we're definitely prep. -- Cort
-	 */
-	if ( !boot_sdr1 )
+#ifndef CONFIG_MBX8xx
+
+#ifdef CONFIG_APUS
+	if ( r3 == 0x61707573 )
 	{
-		/* we know for certain we're prep if no OF */
+		/* Parse bootinfo. The bootinfo is located right after
+                   the kernel bss */
+		m68k_parse_bootinfo((const struct bi_record *)&_end);
+
 		have_of = 0;
-		/* make a copy of residual data */
-		if ( r3 )
-			memcpy((void *)&res,(void *)(r3+KERNELBASE),
-			       sizeof(RESIDUAL));
+		
+#ifdef CONFIG_BLK_DEV_INITRD
+		/* Take care of initrd if we have one. Use data from
+		   bootinfo to avoid the need to initialize PPC
+		   registers when kernel is booted via a PPC reset. */
+		if ( m68k_ramdisk.addr ) {
+			initrd_start = (unsigned long) __va(m68k_ramdisk.addr);
+			initrd_end = (unsigned long) 
+				__va(m68k_ramdisk.size + m68k_ramdisk.addr);
+		}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+		return 0;
+	}
+#endif
+
 #ifndef CONFIG_MACH_SPECIFIC
+	/* prep boot loader tells us if we're prep or not */
+	if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
+	{
 		_machine = _MACH_prep;
-#endif /* CONFIG_MACH_SPECIFIC */
+		have_of = 0;
+	} else
+	{
+		/* need to ask OF if we're chrp or pmac */
+		extern unsigned char OF_type[16], OF_model[16];
+		prom_print(OF_type);
+		prom_print(OF_model);
+		if ( !strncmp("chrp", OF_type,4) )
+		{
+			_machine = _MACH_chrp;
+		}
+		else 
+		{
+		        /*if ( !strncmp("Power Macintosh", type,15) )*/
+			_machine = _MACH_Pmac;
+                }
+		_machine = _MACH_Pmac;
+
 	}
-	else
+#endif /* CONFIG_MACH_SPECIFIC */		
+
+	if ( have_of )
 	{
-		/*
-		 * init prom here, then ask the openfirmware
-		 * what machine we are (prep/chrp/pmac).  We don't use
-		 * OF on prep just yet.  -- Cort
-		 */
-#ifndef CONFIG_PREP		/* don't use OF on prep yet */
-		have_of = 1;
 		/* prom_init has already been called from __start */
 		finish_device_tree();
-
 		/*
 		 * If we were booted via quik, r3 points to the physical
 		 * address of the command-line parameters.
@@ -356,7 +562,7 @@
 		} else {
 			struct device_node *chosen;
 			char *p;
-
+			
 #ifdef CONFIG_BLK_DEV_INITRD
 			if (r3 - KERNELBASE < 0x800000
 			    && r4 != 0 && r4 != 0xdeadbeef) {
@@ -365,7 +571,7 @@
 				ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
 			}
 #endif
-			chosen = find_path_device("/chosen");
+			chosen = find_devices("chosen");
 			if (chosen != NULL) {
 				p = get_property(chosen, "bootargs", NULL);
 				if (p != NULL)
@@ -373,47 +579,18 @@
 			}
 		}
 		cmd_line[sizeof(cmd_line) - 1] = 0;
-#endif /* CONFIG_PREP */
-
-#ifndef CONFIG_MACH_SPECIFIC
-#if 0
-		prom_root = call_prom("finddevice", 1, 1, "/");		
-		call_prom("getprop", 4, 1, prom_root, "device_type", &type,
-			  (void *) sizeof(type));
-		call_prom("getprop", 4, 1, prom_root, "model", &type,
-			  (void *) sizeof(model));
-		if ( !strncmp("chrp", type,4) )
-		{
-			_machine = _MACH_chrp;
-		}
-		else 
-		{
-		        /*if ( !strncmp("Power Macintosh", type,15) )*/
-			_machine = _MACH_Pmac;
-                }
-#else
-
-#ifdef CONFIG_CHRP		
-		_machine = _MACH_chrp;
-#endif /* CONFIG_CHRP */
-#ifdef CONFIG_PMAC		
-		_machine = _MACH_Pmac;
-#endif /* CONFIG_PMAC */
-#ifdef CONFIG_PREP
-		_machine = _MACH_Prep;
-#endif /* CONFIG_PREP */
-#endif /* #if */		
-#endif /* CONFIG_MACH_SPECIFIC */
 	}
 
+#ifdef CONFIG_PCI
 	/* so that pmac/chrp can use pci to find its console -- Cort */
 	setup_pci_ptrs();
-	
+#endif
+
 	switch (_machine)
 	{
 	case _MACH_Pmac:
 #if !defined(CONFIG_MACH_SPECIFIC)
-		isa_io_base = PMAC_ISA_IO_BASE;
+		/* isa_io_base gets set in pmac_find_bridges */
 		isa_mem_base = PMAC_ISA_MEM_BASE;
 		pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
 		ISA_DMA_THRESHOLD = ~0L;
@@ -422,6 +599,10 @@
 #endif /* ! CONFIG_MACH_SPECIFIC */
 		break;
 	case _MACH_prep:
+		/* make a copy of residual data */
+		if ( r3 )
+			memcpy((void *)&res,(void *)(r3+KERNELBASE),
+			       sizeof(RESIDUAL));
 #if !defined(CONFIG_MACH_SPECIFIC)
 		isa_io_base = PREP_ISA_IO_BASE;
 		isa_mem_base = PREP_ISA_MEM_BASE;
@@ -434,13 +615,12 @@
 		if ( res.ResidualLength != 0 )
 		{
 			if ( !strncmp(res.VitalProductData.PrintableModel,"IBM",3) )
-				_prep_type = 0x00;
+				_prep_type = _PREP_IBM;
 			else
-				_prep_type = 0x01;
+				_prep_type = _PREP_Motorola;
 		}
 		else /* assume motorola if no residual (netboot?) */
 			_prep_type = _PREP_Motorola;
-
 #ifdef CONFIG_BLK_DEV_RAM
 		/* take care of initrd if we have one */
 		if ( r4 )
@@ -457,7 +637,14 @@
 		}
 		break;
 	case _MACH_chrp:
-		/* LongTrail */
+#ifdef CONFIG_BLK_DEV_RAM
+		/* take care of initrd if we have one */
+		if ( r3 )
+		{
+			initrd_start = r3 + KERNELBASE;
+			initrd_end = r3+ r4 + KERNELBASE;
+		}
+#endif /* CONFIG_BLK_DEV_RAM */
 #if !defined(CONFIG_MACH_SPECIFIC)
 		isa_io_base = CHRP_ISA_IO_BASE;
 		isa_mem_base = CHRP_ISA_MEM_BASE;
@@ -470,13 +657,33 @@
 	default:
 		printk("Unknown machine type in identify_machine!\n");
 	}
-	return 0;
-}
+#else /* CONFIG_MBX8xx */
+	extern setup_pci_ptrs(void);
 
-__initfunc(unsigned long
-bios32_init(unsigned long memory_start, unsigned long memory_end))
-{
-	return memory_start;
+	if ( r3 )
+		memcpy( (void *)&res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
+
+	setup_pci_ptrs();
+
+#ifdef CONFIG_BLK_DEV_RAM
+	/* take care of initrd if we have one */
+	if ( r4 )
+	{
+		initrd_start = r4 + KERNELBASE;
+		initrd_end = r5 + KERNELBASE;
+	}
+#endif /* CONFIG_BLK_DEV_RAM */
+	/* take care of cmd line */
+	if ( r6 )
+	{
+		
+		*(char *)(r7+KERNELBASE) = 0;
+		strcpy(cmd_line, (char *)(r6+KERNELBASE));
+	}
+
+#endif /* CONFIG_MBX */
+	
+	return 0;
 }
 
 __initfunc(void setup_arch(char **cmdline_p,
@@ -485,12 +692,18 @@
 	extern void pmac_setup_arch(unsigned long *, unsigned long *);
 	extern void chrp_setup_arch(unsigned long *, unsigned long *);
 	extern void prep_setup_arch(unsigned long *, unsigned long *);
+	extern void apus_setup_arch(char **, unsigned long *, unsigned long *);
 	extern int panic_timeout;
 	extern char _etext[], _edata[];
 	extern char *klimit;
 	extern unsigned long find_available_memory(void);
 	extern unsigned long *end_of_DRAM;
 
+#ifdef CONFIG_XMON
+	extern void xmon_map_scc(void);
+	xmon_map_scc();
+#endif /* CONFIG_XMON */
+
 	/* reboot on panic */	
 	panic_timeout = 180;
 	
@@ -516,6 +729,12 @@
 	case _MACH_chrp:
 		chrp_setup_arch(memory_start_p, memory_end_p);
 		break;
+#ifdef CONFIG_APUS
+	case _MACH_apus:
+		m68k_machtype = MACH_AMIGA;
+		apus_setup_arch(cmdline_p,memory_start_p,memory_end_p);
+		break;
+#endif
 	default:
 		printk("Unknown machine %d in setup_arch()\n", _machine);
 	}

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