[parisc-linux-cvs] [PATCH] PDC Wrappers for 32-bit firmware using 64-bit kernels

Ryan Bradetich rbrad@beavis.ybsoft.com
Wed, 21 Mar 2001 23:46:22 -0700


--T4sUOijqQbZv57TR
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

This is the final version of the 32-bit PDC wrapper patch
after Paul Bame tested it on a true 64-bit system.  After
fixing the problem Paul discovered, this patch appears to
work fine on 32-bit, 64-bit + WRAPPERS, and 64-bit kernels.

Things left on my TODO list for PDC:
	- real1.c is not used any more, remove it from CVS.
	  [Note: I need the help of a cvs ninja here....]
	- pdc.c should be renamed to firmware.c
	  [Note: I also need the help of a cvs ninja here...]
	- Fix the few instances of real32_call that does
	  not reside in pdc.c/firmware.c so I can make the
	  real*_calls static.
	- Add kernel documentation to the pdc calls.
	- Use a copyin/copyout scheme so the caller does 
	  not have to worry about alignment issues.
	- Redo the ASSERT_ALIGNED so it does not require
	  gcc extensions.

Hopefully this commit will not cause anyone any problems,
and will be usefull for others in helping to get the 64-bit
kernel to boot on machines with 32-bit firmware.

Thanks,

- Ryan

--T4sUOijqQbZv57TR
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="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/22 06:30:14
@@ -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' CONFIG_PDC_NARROW n
+   fi
 else
    define_bool CONFIG_PA11 y
 fi
Index: arch/parisc/kernel/Makefile
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/Makefile,v
retrieving revision 1.31
diff -u -p -r1.31 Makefile
--- Makefile	2001/03/02 00:48:47	1.31
+++ Makefile	2001/03/22 06:30:14
@@ -23,7 +23,7 @@ obj-		:=
 obj-y           += cache.o pacache.o setup.o traps.o time.o irq.o \
 		syscall.o entry.o sys_parisc.o pdc.o ptrace.o hardware.o \
 		inventory.o drivers.o semaphore.o pa7300lc.o pci-dma.o \
-		signal.o hpmc.o real1.o real2.o parisc_ksyms.o
+		signal.o hpmc.o real2.o parisc_ksyms.o
 
 export-objs	:= parisc_ksyms.o
 
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/22 06:30:15
@@ -36,11 +36,13 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/spinlock.h>
 
 #include <asm/page.h>
 #include <asm/pdc.h>
 #include <asm/system.h>
 
+#include <stdarg.h>
 
 #define ASSERT_ALIGN(ptr, align)					\
 	do { if(((unsigned long)(ptr)) & (align-1)) {			\
@@ -51,22 +53,34 @@
 		return -1;						\
 	} } while(0)
 	
-/* verify address can be accessed without an HPMC */
-int pdc_add_valid(void *address)
+static unsigned long f_extend(unsigned long address)
 {
-	ASSERT_ALIGN(address, 4);
+#ifdef CONFIG_PDC_NARROW
+	if((address & 0xff000000) == 0xf0000000)
+		return 0xf0f0f0f000000000 | (u32)address;
 
-	return mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, (unsigned long)address);
+	if((address & 0xf0000000) == 0xf0000000)
+		return 0xffffffff00000000 | (u32)address;
+#endif
+	return address;
 }
 
-#if 0
-int pdc_chassis_warn(struct pdc_chassis_warn *address)
+static void convert_to_wide(unsigned long *addr)
 {
-	ASSERT_ALIGN(address, 4);
+#ifdef CONFIG_PDC_NARROW
+	int i;
+	unsigned *p = (unsigned int *)addr;
+	for(i = 31; i >= 0; --i)
+		addr[i] = p[i];
+#endif
+}
 
-	return mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(address), 0);
+/* verify address can be accessed without an HPMC */
+int pdc_add_valid(void *address)
+{
+	ASSERT_ALIGN(address, 4);
+	return mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
 }
-#endif
 
 int pdc_chassis_disp(unsigned long disp)
 {
@@ -75,146 +89,193 @@ int pdc_chassis_disp(unsigned long disp)
 
 int pdc_chassis_info(void *pdc_result, void *chassis_info, unsigned long len)
 {
+	int retval;
+
 	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);
+	retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
+			      __pa(pdc_result), __pa(chassis_info), len);
+	convert_to_wide(pdc_result);
+	return retval;
 }
 
-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);
-
-	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);
+	retval = mem_pdc_call(PDC_HPA, PDC_HPA_PROCESSOR, __pa(address), 0);
+	convert_to_wide((unsigned long *)address);
+	address->hpa = f_extend(address->hpa);
+	return retval;
 }
-#endif
 
 int pdc_coproc_cfg(void *address)
 {
-	ASSERT_ALIGN(address, 8);
-	return mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(address));
-}
-
+	int retval;
 
-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);
+	retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(address));
+	convert_to_wide(address);
+	return retval;
 }
 
 
-int pdc_psw_get_mask(void *mask_ret)
+int pdc_iodc_read(void *address, void *hpa, unsigned int index,
+		  void *iodc_data, unsigned int iodc_data_size)
 {
-	return mem_pdc_call(PDC_PSW, PDC_PSW_MASK, __pa(mask_ret));
-}
-
+	int retval;
 
-int pdc_psw_get_defaults(void *psw_ret)
-{
-	return mem_pdc_call(PDC_PSW, PDC_PSW_GET_DEFAULTS, __pa(psw_ret));
+	ASSERT_ALIGN(address, 4);
+	ASSERT_ALIGN(hpa, 4);
+	ASSERT_ALIGN(iodc_data, 4);
+	retval = mem_pdc_call(PDC_IODC, PDC_IODC_READ, __pa(address), hpa, 
+			      index, __pa(iodc_data), iodc_data_size);
+	convert_to_wide(address);
+	return retval;
 }
 
-
-int pdc_psw_set_defaults(unsigned long psw_val)
+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_SET_DEFAULTS, psw_val);
-}
+	int retval;
 
-int pdc_system_map_find_mods(void *pdc_mod_info,
-	void *mod_path, long mod_index)
-{
-	return mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE,
-		__pa(pdc_mod_info), __pa(mod_path), mod_index);
+	ASSERT_ALIGN(pdc_mod_info, 8);
+	ASSERT_ALIGN(mod_path, 8);
+	retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_mod_info), 
+			      __pa(mod_path), mod_index);
+	convert_to_wide((unsigned long *)pdc_mod_info);
+	pdc_mod_info->mod_addr = (void *)f_extend((unsigned long)pdc_mod_info->mod_addr);
+	return retval;
 }
 
-int pdc_system_map_find_addrs(void *pdc_addr_info,
-	long mod_index, long addr_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_ADDRESS,
-		__pa(pdc_addr_info), mod_index, addr_index);
+	int retval;
+
+	ASSERT_ALIGN(pdc_addr_info, 8);
+	retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS, __pa(pdc_addr_info), 
+			      mod_index, addr_index);
+	convert_to_wide((unsigned long *)pdc_addr_info);
+	pdc_addr_info->mod_addr = (void *)f_extend((unsigned long)pdc_addr_info->mod_addr);
+	return retval;
 }
 
 
-int pdc_model_info(struct pdc_model *model) {
+int pdc_model_info(struct pdc_model *model) 
+{
+	int retval;
+
 	ASSERT_ALIGN(model, 8);
-	return mem_pdc_call(PDC_MODEL,PDC_MODEL_INFO,__pa(model),0);
+	retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_INFO, __pa(model), 0);
+	convert_to_wide((unsigned long *)model);
+	return retval;
 }
 
 /* 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));
-	
-	if (retval == PDC_RET_OK) 
-	    name[sys_model.mod_len] = '\0'; /* add trailing '\0' */
-	else
-	    name[0] = 0;
-	
+	retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_SYSMODEL, __pa(&sys_model), 
+			      OS_ID_HPUX,__pa(name));
+	convert_to_wide((unsigned long *)&sys_model);
+
+	if (retval == PDC_RET_OK) {
+		name[sys_model.mod_len] = '\0'; /* add trailing '\0' */
+	} else {
+		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) 
+{
+	int retval;
+	
+	ASSERT_ALIGN(cpu_id, 8);
+	retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_VERSIONS, __pa(cpu_id), id);
+	convert_to_wide((unsigned long *)cpu_id);
+	return retval;
 }
 
-int pdc_model_cpuid(struct pdc_model_cpuid *cpu_id) {
+int pdc_model_cpuid(struct pdc_model_cpuid *cpu_id) 
+{
+	int retval;
+
+	ASSERT_ALIGN(cpu_id, 8);
 	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" */
+	retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(cpu_id), 0);
+	convert_to_wide((unsigned long *)cpu_id);
+	return retval;
 }
 
-int pdc_cache_info(struct pdc_cache_info *cache_info) {
+int pdc_cache_info(struct pdc_cache_info *cache_info) 
+{
+	int retval;
+	
 	ASSERT_ALIGN(cache_info, 8);
-
-	return mem_pdc_call(PDC_CACHE,PDC_CACHE_INFO,__pa(cache_info),0);
+	retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(cache_info), 0);
+	convert_to_wide((unsigned long *)cache_info);
+	return retval;
 }
 
 #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;
+
+	ASSERT_ALIGN(btlb, 8);
+	retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(btlb), 0);
+	convert_to_wide((unsigned long *)btlb);
+
+	if(retval < 0) {
+		btlb->max_size = 0;
+	}
+	return retval;
 }
+
+int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path) 
+{
+	int 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));
+	ASSERT_ALIGN(r_addr, 8);
+	ASSERT_ALIGN(mod_path, 8);
+	retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(r_addr), __pa(mod_path));
+	convert_to_wide((unsigned long *)r_addr);
+	return retval;
 }
 
-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)
+	ASSERT_ALIGN(lan_addr, 4);
+	ASSERT_ALIGN(net_hpa, 4);
+	retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ, __pa(&id), net_hpa);
+	convert_to_wide((unsigned long *)&id);
+
+	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,22 +284,36 @@ 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);
+	int retval;
 
+	ASSERT_ALIGN(r_addr, 4);
+	ASSERT_ALIGN(hpa, 4);
+	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE, __pa(r_addr), hpa);
+	convert_to_wide(r_addr);
+	return retval;
 }
 
 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));
+	int retval;
+
+	ASSERT_ALIGN(r_addr, 4);
+	ASSERT_ALIGN(hpa, 4);
+	ASSERT_ALIGN(tbl, 4);
+	retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL, __pa(r_addr), hpa, __pa(tbl));
+	convert_to_wide(r_addr);
+	return retval;
 }
 
 /* access the TOD clock */
 int pdc_tod_read(struct pdc_tod *tod)
 {
+	int retval;
+
 	ASSERT_ALIGN(tod, 8);
-	return mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(tod), 0);
+	retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(tod), 0);
+	convert_to_wide((unsigned long *)tod);
+	return retval;
 }
 
 int pdc_tod_set(unsigned long sec, unsigned long usec)
@@ -249,7 +324,136 @@ int pdc_tod_set(unsigned long sec, unsig
 #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);
+	int retval;
+
+	ASSERT_ALIGN(r_addr, 4);
+	ASSERT_ALIGN(tbl, 4);
+	retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(r_addr), __pa(tbl), entries);
+	convert_to_wide(r_addr);
+	return retval;
+}
+#endif
+
+
+static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED;
+
+/***************** 32-bit real-mode calls ***********/
+/* The struct below is used
+ * to overlay real_stack (real2.S), preparing a 32-bit call frame.
+ * real32_call_asm() then uses this stack in narrow real mode
+ */
+
+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 */
+};
+
+long real32_call(unsigned long fn, ...)
+{
+	va_list args;
+	unsigned long r, flags;
+	extern struct narrow_stack real_stack;
+	extern unsigned long real32_call_asm(unsigned int *,
+					     unsigned int *, 
+					     unsigned int);
+	
+	spin_lock_irqsave(&pdc_lock, flags);
+
+	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);
+	
+	r = real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
+	spin_unlock_irqrestore(&pdc_lock, flags);
+	
+	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 */
+};
+
+long real64_call(unsigned long fn, ...)
+{
+	va_list args;
+	unsigned long r, flags;
+	extern struct wide_stack real_stack;
+	extern unsigned long real64_call_asm(unsigned long *,
+					     unsigned long *, 
+					     unsigned long);
+    
+	spin_lock_irqsave(&pdc_lock, flags);
+
+	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);
+	
+	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/22 06:30:15
@@ -406,6 +406,9 @@ void __init setup_arch(char **cmdline_p)
 #endif
 	"-bit Kernel has started...\n");
 
+#ifdef CONFIG_PDC_NARROW
+	printk("Kernel is using PDC in 32-bit mode.\n");
+#endif
 	setup_pdc();
 	setup_cmdline(cmdline_p);
 	collect_boot_cpu_data();
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/22 06:30:18
@@ -207,13 +207,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 +378,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 +396,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 +598,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 +607,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 +626,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);
@@ -657,16 +648,22 @@ int pdc_mem_mem_table(void *r_addr, void
  *
  * Note that some PAT boxes may have 64-bit IODC I/O...
  */
-#ifdef __LP64__
-#   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, ...);
+
+#if defined(__LP64__) && ! defined(CONFIG_PDC_NARROW)
+#define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc
+#   define mem_pdc_call(args...) real64_call(MEM_PDC, args)
+#else
+#define MEM_PDC (unsigned long)PAGE0->mem_pdc
+#   define mem_pdc_call(args...) real32_call(MEM_PDC, args)
+#endif
+
 extern void pdc_init(void);
 
 #endif /* __ASSEMBLY__ */
 
 #endif /* _PARISC_PDC_H */
+

--T4sUOijqQbZv57TR--