* [parisc-linux] [RFC] Reorder compat structure placement and casting (firmware.c)?
@ 2004-08-01 4:50 Carlos O'Donell
[not found] ` <20040802052751.GD20904@colo.lackof.org>
0 siblings, 1 reply; 6+ messages in thread
From: Carlos O'Donell @ 2004-08-01 4:50 UTC (permalink / raw)
To: parisc-linux
pa,
Stop defining variables after code, and make sure that two externs don't
reference the same variable with different types. Comments?
Index: arch/parisc/kernel/firmware.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/firmware.c,v
retrieving revision 1.10
diff -u -p -r1.10 firmware.c
--- arch/parisc/kernel/firmware.c 10 Jul 2004 21:20:47 -0000 1.10
+++ arch/parisc/kernel/firmware.c 1 Aug 2004 04:24:15 -0000
@@ -237,11 +237,11 @@ int __init pdc_chassis_info(struct pdc_c
#ifdef __LP64__
int pdc_pat_chassis_send_log(unsigned long state, unsigned long data)
{
+ int retval = 0;
+
if (!is_pdc_pat())
return -1;
- int retval = 0;
-
spin_lock_irq(&pdc_lock);
retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data));
spin_unlock_irq(&pdc_lock);
@@ -1195,7 +1195,32 @@ int pdc_pat_io_pci_cfg_write(unsigned lo
#endif /* __LP64__ */
-/***************** 32-bit real-mode calls ***********/
+/***************** 32-bit and 64-bit real-mode calls ***********/
+
+#ifdef __LP64__
+/* The structure below is the wide 64-bit stack view */
+
+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 */
+};
+#endif /* __LP64__ */
+
/* 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
@@ -1225,53 +1250,42 @@ struct narrow_stack {
long real32_call(unsigned long fn, ...)
{
va_list args;
+#ifdef __LP64__
+ /* If we have a 64-bit kernel reference the stack as
+ such, but cast down to a 32-bit structure if
+ required. */
+ extern struct wide_stack real_stack;
+#else
extern struct narrow_stack real_stack;
+#endif
+
+ struct narrow_stack * real32_stack;
extern unsigned long real32_call_asm(unsigned int *,
unsigned int *,
unsigned int);
+ real32_stack = (struct narrow_stack *)&real_stack;
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);
+ real32_stack->arg0 = va_arg(args, unsigned int);
+ real32_stack->arg1 = va_arg(args, unsigned int);
+ real32_stack->arg2 = va_arg(args, unsigned int);
+ real32_stack->arg3 = va_arg(args, unsigned int);
+ real32_stack->arg4 = va_arg(args, unsigned int);
+ real32_stack->arg5 = va_arg(args, unsigned int);
+ real32_stack->arg6 = va_arg(args, unsigned int);
+ real32_stack->arg7 = va_arg(args, unsigned int);
+ real32_stack->arg8 = va_arg(args, unsigned int);
+ real32_stack->arg9 = va_arg(args, unsigned int);
+ real32_stack->arg10 = va_arg(args, unsigned int);
+ real32_stack->arg11 = va_arg(args, unsigned int);
+ real32_stack->arg12 = va_arg(args, unsigned int);
+ real32_stack->arg13 = va_arg(args, unsigned int);
va_end(args);
- return real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
+ return real32_call_asm(&real32_stack->sp, &real32_stack->arg0, fn);
}
#ifdef __LP64__
-/***************** 64-bit real-mode calls ***********/
^ permalink raw reply [flat|nested] 6+ messages in thread[parent not found: <20040802052751.GD20904@colo.lackof.org>]
* Re: [parisc-linux] [RFC] Reorder compat structure placement and casting (firmware.c)? [not found] ` <20040802052751.GD20904@colo.lackof.org> @ 2004-08-05 4:06 ` Carlos O'Donell [not found] ` <20040805205937.GB20367@colo.lackof.org> 0 siblings, 1 reply; 6+ messages in thread From: Carlos O'Donell @ 2004-08-05 4:06 UTC (permalink / raw) To: Grant Grundler; +Cc: parisc-linux On Sun, Aug 01, 2004 at 11:27:51PM -0600, Grant Grundler wrote: > On Sun, Aug 01, 2004 at 12:50:32AM -0400, Carlos O'Donell wrote: > > +#ifdef __LP64__ > > + /* If we have a 64-bit kernel reference the stack as > > + such, but cast down to a 32-bit structure if > > + required. */ > > + extern struct wide_stack real_stack; > > +#else > > extern struct narrow_stack real_stack; > > +#endif > > This is the bit I don't think will work. Why not? In a wide kernel we only ever declare "extern struct wide_stack real_stack" and then if we need a narrow stack we cast the pointer. It's just a label to 8192 bytes declared in real2.S. > > + real32_stack = (struct narrow_stack *)&real_stack; > > Apologies - this is probbaly the right way to alias/union > the same address. I just overlooked it before. The problem is that we can't have two externs declare the same variable with different storage types. So in wide kernels we make gcc think it's pointing to a wide_stack, and cast about as neccessary. I coded it such that the fallback case should optimize away. c. _______________________________________________ parisc-linux mailing list parisc-linux@lists.parisc-linux.org http://lists.parisc-linux.org/mailman/listinfo/parisc-linux ^ permalink raw reply [flat|nested] 6+ messages in thread
[parent not found: <20040805205937.GB20367@colo.lackof.org>]
* Re: [parisc-linux] [RFC] Reorder compat structure placement and casting (firmware.c)? [not found] ` <20040805205937.GB20367@colo.lackof.org> @ 2004-08-06 2:28 ` Carlos O'Donell 2004-08-06 3:51 ` Carlos O'Donell 1 sibling, 0 replies; 6+ messages in thread From: Carlos O'Donell @ 2004-08-06 2:28 UTC (permalink / raw) To: Grant Grundler; +Cc: parisc-linux On Thu, Aug 05, 2004 at 02:59:37PM -0600, Grant Grundler wrote: > We don't need the same variable name. The two code paths could use different > labels which point at the same storage. And both could co-exist in > the wide kernel. So you just want: label32: label64: block 8192 In the assembly and then let the C code do whatever it pleases? :) c. _______________________________________________ parisc-linux mailing list parisc-linux@lists.parisc-linux.org http://lists.parisc-linux.org/mailman/listinfo/parisc-linux ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [parisc-linux] [RFC] Reorder compat structure placement and casting (firmware.c)? [not found] ` <20040805205937.GB20367@colo.lackof.org> 2004-08-06 2:28 ` Carlos O'Donell @ 2004-08-06 3:51 ` Carlos O'Donell 2004-08-06 4:33 ` Grant Grundler 1 sibling, 1 reply; 6+ messages in thread From: Carlos O'Donell @ 2004-08-06 3:51 UTC (permalink / raw) To: Grant Grundler; +Cc: parisc-linux > Because a wide kernel can make narrow PDC calls. (eg C360). > narrow_stack has to be available regardless which > way we compile the kernel. I don't exclude making narrow calls from a wide kernel. How about something like this? It's actually cleaner to add more assembly labels. Index: firmware.c =================================================================== RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/firmware.c,v retrieving revision 1.10 diff -u -p -r1.10 firmware.c --- firmware.c 10 Jul 2004 21:20:47 -0000 1.10 +++ firmware.c 6 Aug 2004 03:49:32 -0000 @@ -237,11 +237,11 @@ int __init pdc_chassis_info(struct pdc_c #ifdef __LP64__ int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) { + int retval = 0; + if (!is_pdc_pat()) return -1; - int retval = 0; - spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data)); spin_unlock_irq(&pdc_lock); @@ -1225,29 +1225,30 @@ struct narrow_stack { long real32_call(unsigned long fn, ...) { va_list args; - extern struct narrow_stack real_stack; + extern struct narrow_stack real32_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); + real32_stack.arg0 = va_arg(args, unsigned int); + real32_stack.arg1 = va_arg(args, unsigned int); + real32_stack.arg2 = va_arg(args, unsigned int); + real32_stack.arg3 = va_arg(args, unsigned int); + real32_stack.arg4 = va_arg(args, unsigned int); + real32_stack.arg5 = va_arg(args, unsigned int); + real32_stack.arg6 = va_arg(args, unsigned int); + real32_stack.arg7 = va_arg(args, unsigned int); + real32_stack.arg8 = va_arg(args, unsigned int); + real32_stack.arg9 = va_arg(args, unsigned int); + real32_stack.arg10 = va_arg(args, unsigned int); + real32_stack.arg11 = va_arg(args, unsigned int); + real32_stack.arg12 = va_arg(args, unsigned int); + real32_stack.arg13 = va_arg(args, unsigned int); va_end(args); - return real32_call_asm(&real_stack.sp, &real_stack.arg0, fn); + return real32_call_asm(&real32_stack.sp, &real32_stack.arg0, fn); } #ifdef __LP64__ Index: real2.S =================================================================== RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/real2.S,v retrieving revision 1.13 diff -u -p -r1.13 real2.S --- real2.S 15 Mar 2004 20:08:51 -0000 1.13 +++ real2.S 6 Aug 2004 03:49:32 -0000 @@ -14,6 +14,8 @@ .export real_stack .align 64 real_stack: +real32_stack: +real64_stack: .block 8192 #ifdef __LP64__ _______________________________________________ parisc-linux mailing list parisc-linux@lists.parisc-linux.org http://lists.parisc-linux.org/mailman/listinfo/parisc-linux ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [parisc-linux] [RFC] Reorder compat structure placement and casting (firmware.c)? 2004-08-06 3:51 ` Carlos O'Donell @ 2004-08-06 4:33 ` Grant Grundler 2004-08-06 18:20 ` [parisc-linux] [RFC] Reorder compat structure placement and John David Anglin 0 siblings, 1 reply; 6+ messages in thread From: Grant Grundler @ 2004-08-06 4:33 UTC (permalink / raw) To: Carlos O'Donell; +Cc: parisc-linux On Thu, Aug 05, 2004 at 11:51:28PM -0400, Carlos O'Donell wrote: > I don't exclude making narrow calls from a wide kernel. ok > How about something like this? It's actually cleaner to add more > assembly labels. Yes - that's basically what I initially had hacked up but didn't test since I saw you had an alternative posted already. The only possible problem with multiple labels is gcc won't know the two labels are aliases. See my previous posting on this thread. But I don't know if it's really a problem at all or just an overly active imagination. grant _______________________________________________ parisc-linux mailing list parisc-linux@lists.parisc-linux.org http://lists.parisc-linux.org/mailman/listinfo/parisc-linux ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [parisc-linux] [RFC] Reorder compat structure placement and 2004-08-06 4:33 ` Grant Grundler @ 2004-08-06 18:20 ` John David Anglin 0 siblings, 0 replies; 6+ messages in thread From: John David Anglin @ 2004-08-06 18:20 UTC (permalink / raw) To: Grant Grundler; +Cc: parisc-linux > The only possible problem with multiple labels is gcc won't know > the two labels are aliases. See my previous posting > on this thread. But I don't know if it's really a problem at all > or just an overly active imagination. You might look at using gcc alias attribute. Dave -- J. David Anglin dave.anglin@nrc-cnrc.gc.ca National Research Council of Canada (613) 990-0752 (FAX: 952-6602) _______________________________________________ parisc-linux mailing list parisc-linux@lists.parisc-linux.org http://lists.parisc-linux.org/mailman/listinfo/parisc-linux ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2004-08-06 18:20 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-01 4:50 [parisc-linux] [RFC] Reorder compat structure placement and casting (firmware.c)? Carlos O'Donell
[not found] ` <20040802052751.GD20904@colo.lackof.org>
2004-08-05 4:06 ` Carlos O'Donell
[not found] ` <20040805205937.GB20367@colo.lackof.org>
2004-08-06 2:28 ` Carlos O'Donell
2004-08-06 3:51 ` Carlos O'Donell
2004-08-06 4:33 ` Grant Grundler
2004-08-06 18:20 ` [parisc-linux] [RFC] Reorder compat structure placement and John David Anglin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox