[parisc-linux-cvs] [PATCH] 32-bit PDC wrapper patch

Ryan Bradetich rbradetich@uswest.net
Tue, 13 Mar 2001 18:41:31 -0700


This is a multi-part message in MIME format.
--------------245A58F7036CCFCA46973B07
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I have had this patch sitting in my local tree for a couple
of weeks, but I was unable to make my C200 boot
all the way with a 64-bit kernel because of driver
issues.  I will continue working through these driver
issues as I have time, but wanted to have this patch
reviewed/committed so others can also attempt to
boot a 64-bit kernel with 32-bit firmware.

The patch will only work for machines that are
capable of running a 64-bit kernel but have 32-bit
firmware like the C180, C200, C240, C360, and the
J2240  (I hope this list is complete/correct).  This
patch adds a configure option under the 64-bit
kernel option that defaults to no.

Here is the patch.

- Ryan




--------------245A58F7036CCFCA46973B07
Content-Type: text/plain; charset=us-ascii;
 name="pdc.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="pdc.patch"

? pdc.patch
Index: arch/parisc/config.in
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/config.in,v
retrieving revision 1.33
diff -u -p -r1.33 config.in
--- config.in	2001/03/02 01:41:03	1.33
+++ config.in	2001/03/13 04:08:15
@@ -33,6 +33,9 @@ choice 'Processor family' \
 if [ "$CONFIG_PA8X00" = "y" ] ; then
    define_bool CONFIG_PA20 y
    bool '64-bit kernel' CONFIG_PARISC64 n
+   if [ "$CONFIG_PARISC64" = "y" ] ; then
+      bool '32-bit PDC Translator' CONFIG_PDC_TRANSLATOR n
+   fi
 else
    define_bool CONFIG_PA11 y
 fi
Index: arch/parisc/kernel/pdc.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/pdc.c,v
retrieving revision 1.24
diff -u -p -r1.24 pdc.c
--- pdc.c	2001/03/08 13:30:33	1.24
+++ pdc.c	2001/03/13 04:08:15
@@ -51,170 +51,190 @@
 		return -1;						\
 	} } while(0)
 	
-/* verify address can be accessed without an HPMC */
-int pdc_add_valid(void *address)
+#ifdef CONFIG_PDC_TRANSLATOR
+static inline unsigned long f_extend(unsigned int address)
 {
-	ASSERT_ALIGN(address, 4);
+	if((address & 0xff000000) == 0xf0000000)
+		return 0xf0f0f0f000000000 | address;
 
-	return mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, (unsigned long)address);
+	if((address & 0xf0000000) == 0xf0000000)
+		return 0xffffffff00000000 | address;
+	
+	return address;
 }
+#endif
 
-#if 0
-int pdc_chassis_warn(struct pdc_chassis_warn *address)
+/* verify address can be accessed without an HPMC */
+int pdc_add_valid(void *address)
 {
 	ASSERT_ALIGN(address, 4);
-
-	return mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(address), 0);
+	return mem_pdc_call(PDC_ARG2_IS_NOT_RADDR, PDC_ADD_VALID, PDC_ADD_VALID_VERIFY,
+			    (unsigned long)address);
 }
-#endif
 
 int pdc_chassis_disp(unsigned long disp)
 {
-	return mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp);
+	return mem_pdc_call(PDC_ARG2_IS_NOT_RADDR, PDC_CHASSIS, PDC_CHASSIS_DISP, disp);
 }
 
 int pdc_chassis_info(void *pdc_result, void *chassis_info, unsigned long len)
 {
 	ASSERT_ALIGN(pdc_result, 4);
 	ASSERT_ALIGN(chassis_info, 4);
-	return mem_pdc_call(PDC_CHASSIS,PDC_RETURN_CHASSIS_INFO, 
-	        __pa(pdc_result), __pa(chassis_info), len);
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
+			    __pa(pdc_result), __pa(chassis_info), len);
 }
 
-int pdc_hpa_processor(void *address)
+int pdc_hpa_processor(struct pdc_hpa *address)
 {
+	int retval;
+
 	/* We're using 0 for the last parameter just to make sure.
 	   It's actually HVERSION dependant.  And remember, life is
 	   hard without a backspace. */
 	ASSERT_ALIGN(address, 4);
+	retval = mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_HPA, PDC_HPA_PROCESSOR,
+			      __pa(address), 0);
 
-	return mem_pdc_call(PDC_HPA, PDC_HPA_PROCESSOR, __pa(address),0);
-}
-
-#if 0
-int pdc_hpa_modules(void *address)
-{
-	return mem_pdc_call(PDC_HPA, PDC_HPA_MODULES, address);
-}
+#ifdef CONFIG_PDC_TRANSLATOR
+	address->hpa = f_extend(address->hpa);
 #endif
+	return retval;
+}
 
 int pdc_coproc_cfg(void *address)
 {
 	ASSERT_ALIGN(address, 8);
-	return mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(address));
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_COPROC, PDC_COPROC_CFG,
+			    __pa(address));
 }
 
 
-int pdc_iodc_read(void *address, void * hpa, unsigned int index,
-	void * iodc_data, unsigned int iodc_data_size)
+int pdc_iodc_read(void *address, void *hpa, unsigned int index,
+		  void *iodc_data, unsigned int iodc_data_size)
 {
 	ASSERT_ALIGN(address, 4);
 	ASSERT_ALIGN(iodc_data, 8);
-	return mem_pdc_call(PDC_IODC, PDC_IODC_READ, 
-		__pa(address), hpa, index, __pa(iodc_data), iodc_data_size);
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_IODC, PDC_IODC_READ,
+			    __pa(address), hpa, index, __pa(iodc_data), 
+			    iodc_data_size);
 }
-
 
-int pdc_psw_get_mask(void *mask_ret)
+int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
+			     struct pdc_module_path *mod_path, long mod_index)
 {
-	return mem_pdc_call(PDC_PSW, PDC_PSW_MASK, __pa(mask_ret));
-}
-
-
-int pdc_psw_get_defaults(void *psw_ret)
-{
-	return mem_pdc_call(PDC_PSW, PDC_PSW_GET_DEFAULTS, __pa(psw_ret));
-}
-
+	int retval;
 
-int pdc_psw_set_defaults(unsigned long psw_val)
-{
-	return mem_pdc_call(PDC_PSW, PDC_PSW_SET_DEFAULTS, psw_val);
+	retval = mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_SYSTEM_MAP, PDC_FIND_MODULE,
+			      __pa(pdc_mod_info), __pa(mod_path), mod_index);
+     
+#ifdef CONFIG_PDC_TRANSLATOR
+	pdc_mod_info->mod_addr = (void *)f_extend((unsigned long)pdc_mod_info->mod_addr);
+#endif
+	return retval;
 }
 
-int pdc_system_map_find_mods(void *pdc_mod_info,
-	void *mod_path, long mod_index)
+int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info, 
+			      long mod_index, long addr_index)
 {
-	return mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE,
-		__pa(pdc_mod_info), __pa(mod_path), mod_index);
-}
+	int retval;
 
-int pdc_system_map_find_addrs(void *pdc_addr_info,
-	long mod_index, long addr_index)
-{
-	return mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS,
-		__pa(pdc_addr_info), mod_index, addr_index);
+	retval = mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_SYSTEM_MAP, PDC_FIND_ADDRESS,
+			      __pa(pdc_addr_info), mod_index, addr_index);
+#ifdef CONFIG_PDC_TRANSLATOR
+	pdc_addr_info->mod_addr = (void *)f_extend((unsigned long)pdc_addr_info->mod_addr);
+#endif
+	return retval;
 }
 
 
-int pdc_model_info(struct pdc_model *model) {
+int pdc_model_info(struct pdc_model *model) 
+{
 	ASSERT_ALIGN(model, 8);
-	return mem_pdc_call(PDC_MODEL,PDC_MODEL_INFO,__pa(model),0);
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_MODEL, PDC_MODEL_INFO,
+			   __pa(model), 0);
 }
 
 /* get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L) */ 
-int pdc_model_sysmodel(char * name)
+int pdc_model_sysmodel(char *name)
 {
-	struct pdc_model_sysmodel sys_model;
 	int retval;
+	struct pdc_model_sysmodel sys_model;
 	
 	ASSERT_ALIGN(&sys_model, 8);
 	ASSERT_ALIGN(name, 4);
-
+	
 	sys_model.mod_len = 0;
-	retval = mem_pdc_call(PDC_MODEL,PDC_MODEL_SYSMODEL,__pa(&sys_model),
-		    OS_ID_HPUX,__pa(name));
+	retval = mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_MODEL, PDC_MODEL_SYSMODEL,
+			      __pa(&sys_model), OS_ID_HPUX,__pa(name));
 	
 	if (retval == PDC_RET_OK) 
-	    name[sys_model.mod_len] = '\0'; /* add trailing '\0' */
+		name[sys_model.mod_len] = '\0'; /* add trailing '\0' */
 	else
-	    name[0] = 0;
+		name[0] = 0;
 	
 	return retval;
 }
 
 /* id: 0 = cpu revision, 1 = boot-rom-version */
-int pdc_model_versions(struct pdc_model_cpuid *cpu_id, int id) {
-	return mem_pdc_call(PDC_MODEL,PDC_MODEL_VERSIONS,__pa(cpu_id),id);
+int pdc_model_versions(struct pdc_model_cpuid *cpu_id, int id) 
+{
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_MODEL, PDC_MODEL_VERSIONS,
+			    __pa(cpu_id), id);
 }
 
-int pdc_model_cpuid(struct pdc_model_cpuid *cpu_id) {
+int pdc_model_cpuid(struct pdc_model_cpuid *cpu_id) 
+{
 	cpu_id->cpuid = 0; /* preset zero (call maybe not implemented!) */
-	return mem_pdc_call(PDC_MODEL,6,__pa(cpu_id),0);  /* 6="return CPU ID" */
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_MODEL, PDC_MODEL_CPU_ID,
+			    __pa(cpu_id), 0);
 }
 
-int pdc_cache_info(struct pdc_cache_info *cache_info) {
+int pdc_cache_info(struct pdc_cache_info *cache_info) 
+{
 	ASSERT_ALIGN(cache_info, 8);
-
-	return mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_CACHE, PDC_CACHE_INFO,
+			    __pa(cache_info), 0);
 }
 
 #ifndef __LP64__
-int pdc_btlb_info( struct pdc_btlb_info *btlb ) {
-	int status;
-	status = mem_pdc_call(PDC_BLOCK_TLB,PDC_BTLB_INFO,__pa(btlb),0);
-	if (status<0) btlb->max_size = 0;
-	return status;
+int pdc_btlb_info(struct pdc_btlb_info *btlb) 
+{
+	int retval;
+	retval = mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_BLOCK_TLB, PDC_BTLB_INFO,
+			      __pa(btlb), 0);
+	if(retval < 0) 
+		btlb->max_size = 0;
+
+	return retval;
 }
 
-int pdc_mem_map_hpa(void *r_addr, void *mod_path) {
-	return mem_pdc_call(PDC_MEM_MAP,PDC_MEM_MAP_HPA,
-		__pa(r_addr),__pa(mod_path));
+int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path) 
+{
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_MEM_MAP, PDC_MEM_MAP_HPA,
+			    __pa(r_addr), __pa(mod_path));
 }
 
-int pdc_lan_station_id(char *lan_addr, void *net_hpa) {
-	struct pdc_lan_station_id id;
+int pdc_lan_station_id(char *lan_addr, void *net_hpa) 
+{
+	int retval;
 	unsigned char *addr;
+	struct pdc_lan_station_id id;
 	
-	if (mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
-			__pa(&id), net_hpa) < 0)
+	retval = mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_LAN_STATION_ID, 
+			      PDC_LAN_STATION_ID_READ, __pa(&id), net_hpa);
+
+	if(retval < 0) {
 		addr = 0;	/* FIXME: else read MAC from NVRAM */
-	    else
+	} else {
 		addr = id.addr;
-	if (addr)
-		memmove( lan_addr, addr, PDC_LAN_STATION_ID_SIZE);
-	    else
-		memset( lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
+	}
+
+	if(addr) {
+		memmove(lan_addr, addr, PDC_LAN_STATION_ID_SIZE);
+	} else {
+		memset(lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
+	}
 	return (addr != 0);
 }
 #endif
@@ -223,33 +243,34 @@ int pdc_lan_station_id(char *lan_addr, v
 /* Similar to PDC_PAT stuff in pdcpat.c - but added for Forte/Allegro boxes */
 int pdc_pci_irt_size(void *r_addr, void *hpa)
 {
-	return mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE,
-		__pa(r_addr), hpa);
-
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE,
+			    __pa(r_addr), hpa);
 }
 
 int pdc_pci_irt(void *r_addr, void *hpa, void *tbl)
 {
-	return mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL,
-		__pa(r_addr), hpa, __pa(tbl));
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL,
+			    __pa(r_addr), hpa, __pa(tbl));
 }
 
 /* access the TOD clock */
 int pdc_tod_read(struct pdc_tod *tod)
 {
 	ASSERT_ALIGN(tod, 8);
-	return mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(tod), 0);
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_TOD, PDC_TOD_READ,
+			    __pa(tod), 0);
 }
 
 int pdc_tod_set(unsigned long sec, unsigned long usec)
 {
-	return mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_TOD, PDC_TOD_WRITE,
+			    sec, usec);
 }
 
 #ifdef __LP64__
 int pdc_mem_mem_table(void *r_addr, void *tbl, unsigned long entries)
 {
-	return mem_pdc_call(PDC_MEM, PDC_MEM_TABLE,__pa(r_addr),
-				__pa(tbl), entries);
+	return mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_MEM, PDC_MEM_TABLE,
+			    __pa(r_addr), __pa(tbl), entries);
 }
 #endif
Index: arch/parisc/kernel/pdc_cons.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/pdc_cons.c,v
retrieving revision 1.24
diff -u -p -r1.24 pdc_cons.c
--- pdc_cons.c	2001/03/08 13:30:33	1.24
+++ pdc_cons.c	2001/03/13 04:08:16
@@ -53,10 +53,10 @@ void pdc_putc(unsigned char c)
 		break;
 	}
 	{
-		real32_call(PAGE0->mem_cons.iodc_io,
-			(unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
-			PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
-			__pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
+		real32_call(PAGE0->mem_cons.iodc_io, PDC_ARG2_IS_RADDR,
+			    (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
+			    PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
+			    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
 	}
 }
 
@@ -81,10 +81,10 @@ int pdc_console_wait_key(struct console 
 
 		save_flags(flags);
 		cli();
-		status = real32_call(PAGE0->mem_kbd.iodc_io,
-			(unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
-			PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
-			__pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
+		status = real32_call(PAGE0->mem_kbd.iodc_io, PDC_ARG2_IS_RADDR,
+				     (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
+				     PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers), 
+				     __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
 		restore_flags(flags);
 		ch = *iodc_dbuf;	/* save the character directly to ch */
 	} while (*iodc_retbuf == 0);	/* wait for a key */
Index: arch/parisc/kernel/real1.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/real1.c,v
retrieving revision 1.2
diff -u -p -r1.2 real1.c
--- real1.c	2000/12/02 20:52:38	1.2
+++ real1.c	2001/03/13 04:08:16
@@ -28,127 +28,140 @@ static spinlock_t pdc_lock = SPIN_LOCK_U
  */
 
 struct narrow_stack {
-    /* use int, not long which is 64 bits */
-    unsigned int arg13;
-    unsigned int arg12;
-    unsigned int arg11;
-    unsigned int arg10;
-    unsigned int arg9;
-    unsigned int arg8;
-    unsigned int arg7;
-    unsigned int arg6;
-    unsigned int arg5;
-    unsigned int arg4;
-    unsigned int arg3;
-    unsigned int arg2;
-    unsigned int arg1;
-    unsigned int arg0;
-    unsigned int frame_marker[8];
-    unsigned int sp;
-    /* in reality, there's nearly 8k of stack after this */
+	/* use int, not long which is 64 bits */
+	unsigned int arg13;
+	unsigned int arg12;
+	unsigned int arg11;
+	unsigned int arg10;
+	unsigned int arg9;
+	unsigned int arg8;
+	unsigned int arg7;
+	unsigned int arg6;
+	unsigned int arg5;
+	unsigned int arg4;
+	unsigned int arg3;
+	unsigned int arg2;
+	unsigned int arg1;
+	unsigned int arg0;
+	unsigned int frame_marker[8];
+	unsigned int sp;
+	/* in reality, there's nearly 8k of stack after this */
 };
 
-long
-real32_call(unsigned long fn, ...)
+long real32_call(unsigned long fn, int pdc_arg2_is_raddr, ...)
 {
-    unsigned long r;
-    va_list args;
-    unsigned long flags;
-    extern struct narrow_stack real_stack;
-    extern unsigned long real32_call_asm(unsigned int *,
-				unsigned int *, unsigned int);
-    
-    va_start(args, fn);
-    real_stack.arg0 = va_arg(args, unsigned int);
-    real_stack.arg1 = va_arg(args, unsigned int);
-    real_stack.arg2 = va_arg(args, unsigned int);
-    real_stack.arg3 = va_arg(args, unsigned int);
-    real_stack.arg4 = va_arg(args, unsigned int);
-    real_stack.arg5 = va_arg(args, unsigned int);
-    real_stack.arg6 = va_arg(args, unsigned int);
-    real_stack.arg7 = va_arg(args, unsigned int);
-    real_stack.arg8 = va_arg(args, unsigned int);
-    real_stack.arg9 = va_arg(args, unsigned int);
-    real_stack.arg10 = va_arg(args, unsigned int);
-    real_stack.arg11 = va_arg(args, unsigned int);
-    real_stack.arg12 = va_arg(args, unsigned int);
-    real_stack.arg13 = va_arg(args, unsigned int);
-    va_end(args);
-
-    if (fn == 0) {
-	    /* mem_pdc call */
-	    fn = PAGE0->mem_pdc;
-    }
-
-    spin_lock_irqsave(&pdc_lock, flags);
-    r = real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
-    spin_unlock_irqrestore(&pdc_lock, flags);
-
-    return r;
+#ifdef CONFIG_PDC_TRANSLATOR
+	int i;
+	unsigned *p;
+	unsigned long *q;
+#endif
+	unsigned long r;
+	va_list args;
+	unsigned long flags;
+	extern struct narrow_stack real_stack;
+	extern unsigned long real32_call_asm(unsigned int *,
+					     unsigned int *, 
+					     unsigned int);
+	
+	va_start(args, fn);
+	real_stack.arg0 = va_arg(args, unsigned int);
+	real_stack.arg1 = va_arg(args, unsigned int);
+	real_stack.arg2 = va_arg(args, unsigned int);
+	real_stack.arg3 = va_arg(args, unsigned int);
+	real_stack.arg4 = va_arg(args, unsigned int);
+	real_stack.arg5 = va_arg(args, unsigned int);
+	real_stack.arg6 = va_arg(args, unsigned int);
+	real_stack.arg7 = va_arg(args, unsigned int);
+	real_stack.arg8 = va_arg(args, unsigned int);
+	real_stack.arg9 = va_arg(args, unsigned int);
+	real_stack.arg10 = va_arg(args, unsigned int);
+	real_stack.arg11 = va_arg(args, unsigned int);
+	real_stack.arg12 = va_arg(args, unsigned int);
+	real_stack.arg13 = va_arg(args, unsigned int);
+	va_end(args);
+	
+	if (fn == 0) {
+		/* mem_pdc call */
+		fn = PAGE0->mem_pdc;
+	}
+	
+	spin_lock_irqsave(&pdc_lock, flags);
+	r = real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+	
+#ifdef CONFIG_PDC_TRANSLATOR
+	if(pdc_arg2_is_raddr) {
+		p = (unsigned int *)__va(real_stack.arg2);
+		q = (unsigned long *)__va(real_stack.arg2);
+		for(i = 31; i >= 0; --i)
+			q[i] = p[i];
+	}
+#endif
+	return r;
 }
 
 #ifdef __LP64__
 /***************** 64-bit real-mode calls ***********/
 
 struct wide_stack {
-    unsigned long arg0;
-    unsigned long arg1;
-    unsigned long arg2;
-    unsigned long arg3;
-    unsigned long arg4;
-    unsigned long arg5;
-    unsigned long arg6;
-    unsigned long arg7;
-    unsigned long arg8;
-    unsigned long arg9;
-    unsigned long arg10;
-    unsigned long arg11;
-    unsigned long arg12;
-    unsigned long arg13;
-    unsigned long frame_marker[2];	/* rp, previous sp */
-    unsigned long sp;
-    /* in reality, there's nearly 8k of stack after this */
+	unsigned long arg0;
+	unsigned long arg1;
+	unsigned long arg2;
+	unsigned long arg3;
+	unsigned long arg4;
+	unsigned long arg5;
+	unsigned long arg6;
+	unsigned long arg7;
+	unsigned long arg8;
+	unsigned long arg9;
+	unsigned long arg10;
+	unsigned long arg11;
+	unsigned long arg12;
+	unsigned long arg13;
+	unsigned long frame_marker[2];	/* rp, previous sp */
+	unsigned long sp;
+	/* in reality, there's nearly 8k of stack after this */
 };
 
-long
-real64_call(unsigned long fn, ...)
+long real64_call(unsigned long fn, int pdc_arg2_is_raddr, ...)
 {
-    unsigned long r;
-    va_list args;
-    unsigned long flags;
-    extern struct wide_stack real_stack;
-    extern unsigned long real64_call_asm(unsigned long *,
-				unsigned long *, unsigned long);
+	unsigned long r;
+	va_list args;
+	unsigned long flags;
+	extern struct wide_stack real_stack;
+	extern unsigned long real64_call_asm(unsigned long *,
+					     unsigned long *, 
+					     unsigned long);
     
-    va_start(args, fn);
-    real_stack.arg0 = va_arg(args, unsigned long);
-    real_stack.arg1 = va_arg(args, unsigned long);
-    real_stack.arg2 = va_arg(args, unsigned long);
-    real_stack.arg3 = va_arg(args, unsigned long);
-    real_stack.arg4 = va_arg(args, unsigned long);
-    real_stack.arg5 = va_arg(args, unsigned long);
-    real_stack.arg6 = va_arg(args, unsigned long);
-    real_stack.arg7 = va_arg(args, unsigned long);
-    real_stack.arg8 = va_arg(args, unsigned long);
-    real_stack.arg9 = va_arg(args, unsigned long);
-    real_stack.arg10 = va_arg(args, unsigned long);
-    real_stack.arg11 = va_arg(args, unsigned long);
-    real_stack.arg12 = va_arg(args, unsigned long);
-    real_stack.arg13 = va_arg(args, unsigned long);
-    va_end(args);
-
-    if (fn == 0) {
-	    /* mem_pdc call */
-	    fn = PAGE0->mem_pdc_hi;
-	    fn <<= 32;
-	    fn |= PAGE0->mem_pdc;
-    }
-
-    spin_lock_irqsave(&pdc_lock, flags);
-    r = real64_call_asm(&real_stack.sp, &real_stack.arg0, fn);
-    spin_unlock_irqrestore(&pdc_lock, flags);
-
-    return r;
+	va_start(args, fn);
+	real_stack.arg0 = va_arg(args, unsigned long);
+	real_stack.arg1 = va_arg(args, unsigned long);
+	real_stack.arg2 = va_arg(args, unsigned long);
+	real_stack.arg3 = va_arg(args, unsigned long);
+	real_stack.arg4 = va_arg(args, unsigned long);
+	real_stack.arg5 = va_arg(args, unsigned long);
+	real_stack.arg6 = va_arg(args, unsigned long);
+	real_stack.arg7 = va_arg(args, unsigned long);
+	real_stack.arg8 = va_arg(args, unsigned long);
+	real_stack.arg9 = va_arg(args, unsigned long);
+	real_stack.arg10 = va_arg(args, unsigned long);
+	real_stack.arg11 = va_arg(args, unsigned long);
+	real_stack.arg12 = va_arg(args, unsigned long);
+	real_stack.arg13 = va_arg(args, unsigned long);
+	va_end(args);
+	
+	if (fn == 0) {
+		/* mem_pdc call */
+		fn = PAGE0->mem_pdc_hi;
+		fn <<= 32;
+		fn |= PAGE0->mem_pdc;
+	}
+	
+	spin_lock_irqsave(&pdc_lock, flags);
+	r = real64_call_asm(&real_stack.sp, &real_stack.arg0, fn);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+	
+	return r;
 }
 
 #endif
Index: arch/parisc/kernel/setup.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/setup.c,v
retrieving revision 1.79
diff -u -p -r1.79 setup.c
--- setup.c	2001/03/08 13:30:33	1.79
+++ setup.c	2001/03/13 04:08:16
@@ -145,8 +145,8 @@ cpu_driver_callback(struct hp_device *d,
 		txn_addr = pa_pdc_cell.mod[0];   /* id_eid for IO sapic */
 
 		/* get the cpu number */
-		status = mem_pdc_call( PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
-				__pa(& pdc_result), d->hpa);
+		status = mem_pdc_call(PDC_ARG2_IS_RADDR, PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
+				__pa(&pdc_result), d->hpa);
 
 		ASSERT(PDC_RET_OK == status);
 
Index: include/asm-parisc/pdc.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/pdc.h,v
retrieving revision 1.26
diff -u -p -r1.26 pdc.h
--- pdc.h	2001/03/02 10:31:51	1.26
+++ pdc.h	2001/03/13 04:08:18
@@ -70,6 +70,20 @@
 #define	PDC_TOD_WRITE		1	/* write TOD */
 #define	PDC_TOD_ITIMER		2	/* calibrate Interval Timer (CR16) */
 
+#define PDC_STABLE	10		/* stable storage */
+#define PDC_STABLE_READ		0	/* read stable storage */
+#define PDC_STABLE_WRITE	1	/* write stable storage */
+#define PDC_STABLE_SIZE		2	/* get size of stable storage */
+#define PDC_STABLE_VERIFY	3	/* verify stable storage */
+#define PDC_STABLE_INIT		4	/* initialize stable storage */
+
+#define PDC_NVRAM	11
+#define PDC_NVRAM_READ		0	/* read NVRAM */
+#define PDC_NVRAM_WRITE		1	/* write NVRAM */
+#define PDC_NVRAM_SIZE		2	/* get size of NVRAM */
+#define PDC_NVRAM_VERIFY	3	/* verify NVRAM */
+#define PDC_NVRAM_INIT		4	/* initialize NVRAM */
+
 #define PDC_ADD_VALID	12    		/* Memory validation PDC call */
 #define PDC_ADD_VALID_VERIFY  0    	/* Make PDC_ADD_VALID verify region */
 
@@ -178,6 +192,15 @@ compatibility */
 #define OSTAT_RUN		      6
 #define OSTAT_ON		       7
 
+
+/* ioctl constants for /dev interfaces */
+#define NVRAM_INIT		_IO('N', 0x01)		/* initialize */
+#define NVRAM_SIZE		_IOR('N', 0x02, unsigned long)	/* get size */
+#define NVRAM_VERIFY		_IO('N', 0x03)		/* verify contents */
+#define STABLE_INIT		_IO('S', 0x01)		/* initialize */
+#define STABLE_SIZE		_IOR('S', 0x02, unsigned long)	/* get size */
+#define STABLE_VERIFY		_IO('S', 0x03)		/* verify contents */
+
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
@@ -207,13 +230,6 @@ struct pdc_model {		/* for PDC_MODEL */
 } __attribute__((aligned(8))) ;
 
 
-#if 0
-struct pdc_chassis_warn {		/* for PDC_CHASSIS */
-	unsigned long warn;
-	unsigned long pad[32-1];
-} __attribute__((aligned(8))) ;
-#endif
-
 struct pdc_model_sysmodel {	/* for PDC_MODEL_SYSMODEL */
 	unsigned long mod_len;
 	unsigned long pad[32-1];
@@ -385,8 +401,8 @@ struct pdc_module_path {
 #ifndef __LP64__
 /* Probably needs 64-bit porting -PB */
 struct pdc_memory_map {		/* PDC_MEMORY_MAP */
-	unsigned int hpa;	/* mod's register set address */
-	unsigned int more_pgs;	/* number of additional I/O pgs */
+	unsigned long hpa;	/* mod's register set address */
+	unsigned long more_pgs;	/* number of additional I/O pgs */
 	int pad1[30];
 } __attribute__((aligned(8))) ;
 
@@ -403,6 +419,7 @@ struct pdc_tod {
 	long pad[30];
 } __attribute__((aligned(8))) ;
 
+
 /* architected results from PDC_PIM/transfer hpmc on a PA1.1 machine */
 
 struct pdc_hpmc_pim_11 { /* PDC_PIM */
@@ -604,8 +621,6 @@ struct zeropage {
 #define BOOT_CONSOLE_PATH_OFFSET 0x3a8
 
 #ifndef __ASSEMBLY__
-
-extern void setup_pdc(void);
 extern void pdc_console_init(void);
 /* pdc_get/put are NOT SMP safe - use at your own risk! */
 extern int  pdc_getc(void);		/* wait for char */
@@ -615,18 +630,17 @@ extern void pdc_putc(unsigned char);	/* 
 /* wrapper-functions from pdc.c */
 
 int pdc_add_valid(void *address);
-int pdc_hpa_processor(void *address);
-#if 0
-int pdc_hpa_modules(void *address);
-#endif
+int pdc_hpa_processor(struct pdc_hpa *address);
 int pdc_coproc_cfg(void *address);
 int pdc_iodc_read(void *address, void *hpa, unsigned int index,
 		  void *iodc_data, unsigned int iodc_data_size);
 int pdc_psw_get_mask(void *address);
 int pdc_psw_get_defaults(void *address);
 int pdc_psw_set_defaults(unsigned long val);
-int pdc_system_map_find_mods(void *pdc_mod_info, void *mod_path, long mod_index);
-int pdc_system_map_find_addrs(void *pdc_addr_info, long mod_index, long addr_index);
+int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
+			     struct pdc_module_path *mod_path, long mod_index);
+int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info, 
+			      long mod_index, long addr_index);
 int pdc_model_info(struct pdc_model *model);
 int pdc_model_sysmodel(char  *name);
 int pdc_model_cpuid(struct pdc_model_cpuid *cpu_id);
@@ -635,8 +649,8 @@ int pdc_cache_info(struct pdc_cache_info
 #ifndef __LP64__
 int pdc_btlb_info( struct pdc_btlb_info *btlb);
 int pdc_lan_station_id( char *lan_addr, void *net_hpa);
+int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path);
 #endif
-int pdc_mem_map_hpa(void *r_addr, void *mod_path);
 
 extern int pdc_chassis_disp(unsigned long disp);
 extern int pdc_chassis_info(void *pdc_result, void *chassis_info, unsigned long len);
@@ -647,6 +661,18 @@ int pdc_pci_irt(void *r_addr, void *hpa,
 int pdc_tod_read(struct pdc_tod *tod);
 int pdc_tod_set(unsigned long sec, unsigned long usec);
 
+int pdc_stable_read(void *staddr, void *memaddr, unsigned long count);
+int pdc_stable_write(void *staddr, void *memaddr, unsigned long count);
+int pdc_stable_size(unsigned long *size);
+int pdc_stable_verify(void);
+int pdc_stable_init(void);
+
+int pdc_nvram_read(void *nvaddr, void *memaddr, unsigned long count);
+int pdc_nvram_write(void *nvaddr, void *memaddr, unsigned long count);
+int pdc_nvram_size(unsigned long *size);
+int pdc_nvram_verify(void);
+int pdc_nvram_init(void);
+
 #ifdef __LP64__
 int pdc_mem_mem_table(void *r_addr, void *tbl, unsigned long entries);
 #endif
@@ -657,16 +683,21 @@ int pdc_mem_mem_table(void *r_addr, void
  *
  * Note that some PAT boxes may have 64-bit IODC I/O...
  */
-#ifdef __LP64__
+
+#define PDC_ARG2_IS_RADDR 1
+#define PDC_ARG2_IS_NOT_RADDR 0
+
+#if defined(__LP64__) && ! defined(CONFIG_PDC_TRANSLATOR) 
 #   define mem_pdc_call(args...) real64_call(0L, ##args)
 #else
 #   define mem_pdc_call(args...) real32_call(0L, ##args)
 #endif
 /* yes 'int', not 'long' -- IODC I/O is always 32-bit stuff */
-extern long real64_call(unsigned long function, ...);
-extern long real32_call(unsigned long function, ...);
+extern long real64_call(unsigned long function, int pdc_arg2_is_raddr, ...);
+extern long real32_call(unsigned long function, int pdc_arg2_is_raddr, ...);
 extern void pdc_init(void);
 
 #endif /* __ASSEMBLY__ */
 
 #endif /* _PARISC_PDC_H */
+

--------------245A58F7036CCFCA46973B07--