All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
@ 2003-07-16  2:14 Christopher Wedgwood
  2003-07-16 15:22 ` Luck, Tony
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Christopher Wedgwood @ 2003-07-16  2:14 UTC (permalink / raw)
  To: linux-ia64

Hi,

This patch is against the linux-ia64-2.4 bk tree (as of a few minutes
ago).  It should apply cleanly to almost any recent 2.4.x tree though.

This patch is more for discussion than inclusion (although I'm happy
for it to be merged as-is even if further changes are required).

Altix/SN2 presently has the PAL located in a granule that has mixed
cachability --- for this reason we need to map the PAL using the
smallest mapping possible.

In an attempt to make the diff and my intentions clear here, I've
taken the rather inelegant approach of replicating the logic for SN2
in another function and hooking this from a higher-level (it's mostly
all __init code so even like this it's mostly harmless).

I'm more that happy to change this as necessary so flames are most
welcome!


  --cw


# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1147  -> 1.1148 
#	arch/ia64/kernel/efi.c	1.12    -> 1.13   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/07/15	cw@tomahawk.engr.sgi.com	1.1148
# Allow alternate (minimalist) PAL mapping for SN2.
# --------------------------------------------
#
diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
--- a/arch/ia64/kernel/efi.c	Tue Jul 15 18:53:12 2003
+++ b/arch/ia64/kernel/efi.c	Tue Jul 15 18:53:12 2003
@@ -33,11 +33,20 @@
 
 #define EFI_DEBUG	0
 
+#ifdef EFI_DEBUG
+/* make debugging visible */
+#undef KERN_DEBUG
+#define KERN_DEBUG KERN_ERR
+#endif
+
 extern efi_status_t efi_call_phys (void *, ...);
 
 struct efi efi;
 static efi_runtime_services_t *runtime;
 
+/* For some architectures (presently only SN2) we may want to map the PAL differently */
+static void (*alternate_pal_map)(void);
+
 /*
  * efi_dir is allocated here, but the directory isn't created
  * here, as proc_mkdir() doesn't work this early in the bootup
@@ -392,8 +401,12 @@
  * Look for the PAL_CODE region reported by EFI and maps it using an
  * ITR to enable safe PAL calls in virtual mode.  See IA-64 Processor
  * Abstraction Layer chapter 11 in ADAG
+ *
+ * This is called for every CPU in the system (ie. from efi_init for
+ * the boot CPU and from start_secondary() in smpboot.c for all other
+ * CPUs)
  */
-void
+void __init
 efi_map_pal_code (void)
 {
 	void *efi_map_start, *efi_map_end, *p;
@@ -403,6 +416,11 @@
 	u64 mask, psr;
 	u64 vaddr;
 
+	if (alternate_pal_map) {
+		alternate_pal_map();
+		return;
+	}
+
 	efi_map_start = __va(ia64_boot_param->efi_memmap);
 	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
 	efi_desc_size = ia64_boot_param->efi_memdesc_size;
@@ -462,6 +480,93 @@
 	}
 }
 
+/*
+ * This is more-or-less a copy of the original PAL mapping with replicated functionality.
+ * It all repeated here (out of line on the above) for clarity.  Since this is marked __init
+ * code it doesn't hurt that much.  Arguably we should either generalize these two functions
+ * or allow for a platform specific mapping function (a little tricky this early in the boot
+ * but not impossible).
+ *
+ * Please see the genric code for comments if any of this is unclear.
+ *
+ */
+static void __init
+sgisn_efi_map_pal_code(void)
+{
+	static u64 pal_start = 0ul, pal_end = 0ul;
+	void *efi_map_start, *efi_map_end, *p;
+	int pg_shift;
+	u64 efi_desc_size;
+	u64 vaddr, mask, psr;
+
+#if EFI_DEBUG
+	printk("SGI: Mapping PAL.\n");
+#endif
+
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+	/* The first time this runs (on the boot processor) we copy the PAL's start and end
+	   addresses because the trim code destroy's the EFI MD */
+	if (!pal_start) {
+		efi_memory_desc_t *md = NULL;
+
+		/* scan the efi memory map to find the PAL_CODE descriptor */
+		for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+			md = (efi_memory_desc_t*)p;
+
+			if (md->type != EFI_PAL_CODE)
+				continue;
+
+			break; /* there's only enough room in this town for one PAL */
+		}
+
+		if (!md)
+			panic(KERN_ERR "SN2: Unable to performace minimalist PAL mapping\n");
+
+		pal_start = md->phys_addr;
+		pal_end = pal_start + (md->num_pages << EFI_PAGE_SHIFT);
+
+		if (pal_end <= pal_start)
+			panic(KERN_ERR "SGI: PAL_CODE MD already hosed\n");
+	}
+
+	/* Find out the smallest page with which we can map the PAL */
+	for (pg_shift = _PAGE_SIZE_64K; pg_shift <= IA64_GRANULE_SHIFT; pg_shift += 2) {
+		/* round the start address down to our test page size */
+		u64 chk_start = pal_start & (~((1ul << pg_shift) - 1));
+
+		/* does the test page size cover the newly aligned size? */
+		if ((1ul << pg_shift) >= (pal_end - chk_start))
+			break;
+	}
+
+	if (pg_shift > IA64_GRANULE_SHIFT)
+		panic(KERN_ERR "SGI: Woah!  PAL code size bigger than a granule!");
+
+	vaddr = (u64)__va(pal_start);
+	mask  = ~((1ul<<pg_shift) - 1);
+
+#if EFI_DEBUG
+	printk("SGI: CPU(%d) pg_shift %d\n", smp_processor_id(), pg_shift);
+	printk("SGI: CPU(%d) actual PAL range phys: 0x%lx-0x%lx\n", smp_processor_id(), pal_start, pal_end);
+	printk("SGI: CPU(%d) PAL mapping from phys:0x%lx-0x%lx to virt:0x%lx-0x%lx\n",
+	       smp_processor_id(),
+	       pal_start & mask, (pal_start & mask) + (1ul<<pg_shift) - 1,
+	       vaddr & mask, (vaddr & mask) + (1ul<<pg_shift) - 1);
+#endif
+
+	psr = ia64_clear_ic();
+	ia64_itr(0x1, IA64_TR_PALCODE, vaddr & mask, pte_val(mk_pte_phys((pal_start & mask), PAGE_KERNEL)), pg_shift);
+	ia64_set_psr(psr);
+	ia64_srlz_i();
+
+	printk(KERN_DEBUG "SGI: Mapped PAL for CPU %d\n", smp_processor_id());
+}
+
+/* This is called early for the boot-CPU only...  we are therefore somewhat restricted in
+ * what we can blindly do. */
 void __init
 efi_init (void)
 {
@@ -572,6 +677,14 @@
 		}
 	}
 #endif
+
+	/* SGI's SN2 (Altix) requires slightly different PAL mapping semantics.  For now we
+	   check if this is the case and do it all out-of-line for clarity (once the code is
+	   merged we can clean this up).  We use a function pointer here because we want
+	   this decision to follow for all other non-boot CPUs where we don't easily have
+	   access to the vendor string (unless we want to be more invasive). */
+	if (!strncmp(vendor, "SGI", 3))
+		alternate_pal_map = sgisn_efi_map_pal_code;
 
 	efi_map_pal_code();
 	efi_enter_virtual_mode();

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
  2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
@ 2003-07-16 15:22 ` Luck, Tony
  2003-07-16 18:23 ` Christopher Wedgwood
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Luck, Tony @ 2003-07-16 15:22 UTC (permalink / raw)
  To: linux-ia64


> Altix/SN2 presently has the PAL located in a granule that has mixed
> cachability --- for this reason we need to map the PAL using the
> smallest mapping possible.

I tried some similar code for Tiger a while ago, but ran into a problem
as there is other code in the same granule, that isn't covered by the
address range for PAL routines (I think that the other code was the
EFI loaded FPSWA code, but I didn't look too closely at the time this
happened).  As soon as the processor tried to execute this other code,
the Alt-ITLB handler tried to insert a mapping for the whole granule,
which overlaps with the ITR[1] that was set to map the PAL, and boom,
the system died with a machine check.

If SN2 guarantees that the PAL code is the only executable code in the
whole of your mixed cacheability granule, then this code is safe.

-Tony

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
  2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
  2003-07-16 15:22 ` Luck, Tony
@ 2003-07-16 18:23 ` Christopher Wedgwood
  2003-07-17 17:42 ` Bjorn Helgaas
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Christopher Wedgwood @ 2003-07-16 18:23 UTC (permalink / raw)
  To: linux-ia64

On Wed, Jul 16, 2003 at 08:22:37AM -0700, Luck, Tony wrote:

> If SN2 guarantees that the PAL code is the only executable code in
> the whole of your mixed cacheability granule, then this code is
> safe.

Yes, for SN2 this works and is what I presently use here.

Somewhere I have/had an instrumented version of the ivt code which
allows to to profile fault patterns across regions and such-like, by
sucking data our of /proc and making pretty graphs --- I wrote this
mostly to ensure what I thought was going on really was and also to
get some idea of the distribution of things.

Since it doesn't affect non-SN2 users I'm hoping to get something like
this merged if nobody objects...


  --cw

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
  2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
  2003-07-16 15:22 ` Luck, Tony
  2003-07-16 18:23 ` Christopher Wedgwood
@ 2003-07-17 17:42 ` Bjorn Helgaas
  2003-07-17 17:57 ` Christopher Wedgwood
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Bjorn Helgaas @ 2003-07-17 17:42 UTC (permalink / raw)
  To: linux-ia64

On Tuesday 15 July 2003 8:14 pm, Christopher Wedgwood wrote:
> Altix/SN2 presently has the PAL located in a granule that has mixed
> cachability --- for this reason we need to map the PAL using the
> smallest mapping possible.

We had a big discussion inside HP a while back about a similar
issue (firmware reported a region that required run-time mapping
inside a granule that also contained a hole).  We pushed hard to
make everything inside a granule have the same attributes.

Given that you're stuck with this situation:

- I hate to clutter the generic efi.c with so much platform-
  specific stuff.  What are the implications of making this
  a platform vector?  I don't see any obvious dependencies that
  prevent us from doing machvec_init() earlier.

- As Tony mentioned, you might want to verify that there's nothing
  else in the granule that requires run-time mapping.

- If there are different cacheability attributes within a granule,
  efi_memmap_walk should remove the granule from efi_memmap.  Do
  you see that happening?  I guess since PAL is mapped with a TR,
  we probably can live without it being in the EFI memmap, but since
  we use the memmap to validate accesses to /dev/mem, the wrong
  thing will probably happen if you try to read the PAL space.

Bjorn


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
  2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
                   ` (2 preceding siblings ...)
  2003-07-17 17:42 ` Bjorn Helgaas
@ 2003-07-17 17:57 ` Christopher Wedgwood
  2003-07-17 22:52 ` Bjorn Helgaas
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Christopher Wedgwood @ 2003-07-17 17:57 UTC (permalink / raw)
  To: linux-ia64

On Thu, Jul 17, 2003 at 11:42:23AM -0600, Bjorn Helgaas wrote:

> - I hate to clutter the generic efi.c with so much platform-
> specific stuff.

Me too.  I tried hard to make this simply in the generic code at the
cost of code-duplication and ugliness.  I figured simple-less-elegant
wins this time since it's __init code and we throw it away.

That said, at some point this should become non __init code for
hot-swap CPUs but I'd like to ignore that for now.

>   What are the implications of making this a platform vector?  I
>   don't see any obvious dependencies that prevent us from doing
>   machvec_init() earlier.

It's too early on to have the machvec stuff setup otherwise I would so
this.  I did consider doing phyiscal calls to abstract this but it
makes the code larger and more complex --- the current code means the
only issue is a strncmp in the generic path and then we drop out to
core where I assume non-SN2 people don't care much about.

What about the above check or something more generic and I'll move the
offending code to arch/ia64/sn/kernel/* then?

> As Tony mentioned, you might want to verify that there's nothing
> else in the granule that requires run-time mapping.

I had code to do this previously for a generic implementation so there
was no SN2 specific hack.  DavidM had a look at this and said he would
prefer an approach less invasive.

The patch submitted was mostly to make it obvious what generic code
was affect so that people can mentaly verify that only SN2 was
affected by this.

> If there are different cacheability attributes within a granule,
> efi_memmap_walk should remove the granule from efi_memmap.  Do you
> see that happening?

Yes.

>   I guess since PAL is mapped with a TR, we probably can live
>   without it being in the EFI memmap, but since we use the memmap to
>   validate accesses to /dev/mem, the wrong thing will probably
>   happen if you try to read the PAL space.

This does happen which is why I cache the PAL bounds.  The trim code
runs after the boot-CPUs PAL mapping.

As some point I'd like to restructure the efi code and various things
that use it but I'm far to short on cycles to even contemplate this so
its definately a 2.7.x project I would guess.  Part of the reason for
this desire is probably idealistic and unimportant and thus merits a
different discussion altogether.

So how about the strncmp as above and I'll hide the code elsewhere as
a compromise?


  --cw

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
  2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
                   ` (3 preceding siblings ...)
  2003-07-17 17:57 ` Christopher Wedgwood
@ 2003-07-17 22:52 ` Bjorn Helgaas
  2003-07-18  2:22 ` Christopher Wedgwood
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Bjorn Helgaas @ 2003-07-17 22:52 UTC (permalink / raw)
  To: linux-ia64

On Thursday 17 July 2003 11:57 am, Christopher Wedgwood wrote:
> It's too early on to have the machvec stuff setup otherwise I would so
> this.  I did consider doing phyiscal calls to abstract this but it
> makes the code larger and more complex --- the current code means the
> only issue is a strncmp in the generic path and then we drop out to
> core where I assume non-SN2 people don't care much about.

I'm not sure what physical calls you're referring to.

Have you tripped over something in particular that prevents
machvec_init() from working earlier?  It needs only the system
name from acpi_get_sysname().  And acpi_get_sysname() only
requires the efi.acpi20 pointer, which is set up in efi_init().

It seems a little ugly to call machvec_init() from the middle of
efi_init(), but it looks to me like we'd have all the info we
need at that point.

> > If there are different cacheability attributes within a granule,
> > efi_memmap_walk should remove the granule from efi_memmap.  Do you
> > see that happening?
> 
> Yes.
> 
> >   I guess since PAL is mapped with a TR, we probably can live
> >   without it being in the EFI memmap, but since we use the memmap to
> >   validate accesses to /dev/mem, the wrong thing will probably
> >   happen if you try to read the PAL space.
> 
> This does happen which is why I cache the PAL bounds.  The trim code
> runs after the boot-CPUs PAL mapping.

I'm suspecting a different problem: what happens if you try to read
the PAL area through /dev/mem?  In 2.5, we check the EFI memmap to
determine whether to use cached or non-cached access.  For PAL, we
won't find it in the memmap (because we discarded the whole granule),
so we'll try to do uncached accesses to the PAL area.

Bjorn



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
  2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
                   ` (4 preceding siblings ...)
  2003-07-17 22:52 ` Bjorn Helgaas
@ 2003-07-18  2:22 ` Christopher Wedgwood
  2003-07-18 16:13 ` Bjorn Helgaas
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Christopher Wedgwood @ 2003-07-18  2:22 UTC (permalink / raw)
  To: linux-ia64

On Thu, Jul 17, 2003 at 04:52:53PM -0600, Bjorn Helgaas wrote:

> Have you tripped over something in particular that prevents
> machvec_init() from working earlier?

I tried something similar earlier using ia64_platform_is("sn2") which
uses the ACPI data and it didn't work that early on.  Let me check
this again and also see if the machine vector approach works and
resend a patch.

> It seems a little ugly to call machvec_init() from the middle of
> efi_init(), but it looks to me like we'd have all the info we need
> at that point.

This code is only used only during boot.  Give that would prefer a
machine vector over the current suggested code though I take it?

It seems a little unnecessary and complex.  What about an explicitly
ia64_platform_is check instead?

> I'm suspecting a different problem: what happens if you try to read
> the PAL area through /dev/mem?

Checking the code it looks like and write should work.  I'm pretty
sure mmap will too but I've not checked it.  I'll probably make sure
it does work though.

That said, I'm not 100% certain that mmap semantics over the PAL
region even make sense --- for SN2 the PAL is mapped into local-node
memory and as such in theory could differ across nodes, so what
user-space sees might changes depending on what CPU you run on.

Looking at the way PAL is defined it looks like someone at Intel
allowed for the possibility of different CPUs having different PAL-code
so presumably this isn't unique to SN2.

> In 2.5, we check the EFI memmap to determine whether to use cached
> or non-cached access.

Yes, I recall this being mentioned now.  To be honest I have a really
bad case of 2.4-myopia and had to check just now though.

> For PAL, we won't find it in the memmap (because we discarded the
> whole granule), so we'll try to do uncached accesses to the PAL
> area.

Well, I'm not sure I really like the trim code (or anything else)
messing with the EFI memory map as it does --- I'd much rather see the
upper layers be smarter but that's fairly invasive changes for now.

It seems it *should* be safe to not trim PAL code and then the
efi_mem_attributes check will work correctly in 2.5.  I couldn't see
anything using the granule-sized-assumptions that would break if I did
this (in fact, I didn't trim the PAL code in an internal tree for some
time and never saw any problems on zx1, tiger or sn2 --- but I wasn't
looking hard for it).



  --cw

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
  2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
                   ` (5 preceding siblings ...)
  2003-07-18  2:22 ` Christopher Wedgwood
@ 2003-07-18 16:13 ` Bjorn Helgaas
  2003-07-19  1:05 ` Christopher Wedgwood
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Bjorn Helgaas @ 2003-07-18 16:13 UTC (permalink / raw)
  To: linux-ia64

On Thursday 17 July 2003 8:22 pm, Christopher Wedgwood wrote:
> On Thu, Jul 17, 2003 at 04:52:53PM -0600, Bjorn Helgaas wrote:
> 
> > Have you tripped over something in particular that prevents
> > machvec_init() from working earlier?
> 
> I tried something similar earlier using ia64_platform_is("sn2") which
> uses the ACPI data and it didn't work that early on.  Let me check
> this again and also see if the machine vector approach works and
> resend a patch.

ia64_platform_is() only works after calling machvec_init().  If you
move the machvec_init() call into the middle of efi_init(), I think
it should work.  But I do prefer the machine vector approach,
and there are several other machine vectors used only at boot-time,
so I don't think that's an issue.

> It seems it *should* be safe to not trim PAL code and then the
> efi_mem_attributes check will work correctly in 2.5.  I couldn't see
> anything using the granule-sized-assumptions that would break if I did
> this (in fact, I didn't trim the PAL code in an internal tree for some
> time and never saw any problems on zx1, tiger or sn2 --- but I wasn't
> looking hard for it).

You said the granule containing PAL contained regions with different
cacheability attributes.  That means the kernel can't use any memory
in that granule (we would insert kernel mapping that covers the entire
granule).  So the kernel does have to ignore the granule, and modifying
the EFI memmap, while maybe not ideal, is the current approach.

Bjorn


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
  2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
                   ` (6 preceding siblings ...)
  2003-07-18 16:13 ` Bjorn Helgaas
@ 2003-07-19  1:05 ` Christopher Wedgwood
  2003-07-22  1:38 ` Bjorn Helgaas
  2003-07-22 21:26 ` Christopher Wedgwood
  9 siblings, 0 replies; 11+ messages in thread
From: Christopher Wedgwood @ 2003-07-19  1:05 UTC (permalink / raw)
  To: linux-ia64

On Fri, Jul 18, 2003 at 10:13:02AM -0600, Bjorn Helgaas wrote:

> But I do prefer the machine vector approach, and there are several
> other machine vectors used only at boot-time, so I don't think
> that's an issue.

I've done this but must say it feels like excessive abstraction and an
overkill approach.

The previous suggestion of mine was smaller and clearer.  Machine
vectors are at some level vague.  The preprocessor kung-foo involved
obscures things considerably (I think anyhow) so I still prefer the
smaller more-obvious approach I originally sent :)


 arch/ia64/kernel/efi.c          |  111 +++++++++++++++++++++++++++++-
 arch/ia64/kernel/setup.c        |    9 --
 arch/ia64/kernel/smpboot.c      |    2
 include/asm-ia64/machvec.h      |    9 ++
 include/asm-ia64/machvec_init.h |    1
 include/asm-ia64/machvec_sn2.h  |    1
 include/linux/efi.h             |    2
 7 files changed, 123 insertions(+), 12 deletions(-)


=== arch/ia64/kernel/efi.c 1.12 vs edited ==--- 1.12/arch/ia64/kernel/efi.c	Fri Mar 14 16:08:01 2003
+++ edited/arch/ia64/kernel/efi.c	Fri Jul 18 14:17:53 2003
@@ -392,9 +398,13 @@
  * Look for the PAL_CODE region reported by EFI and maps it using an
  * ITR to enable safe PAL calls in virtual mode.  See IA-64 Processor
  * Abstraction Layer chapter 11 in ADAG
+ *
+ * This is called for every CPU in the system (ie. from efi_init for
+ * the boot CPU and from start_secondary() in smpboot.c for all other
+ * CPUs).  This is called using the machine vector mechanics.
  */
-void
-efi_map_pal_code (void)
+void __init
+ia64_generic_PAL_map (void)
 {
 	void *efi_map_start, *efi_map_end, *p;
 	efi_memory_desc_t *md;
@@ -462,6 +472,95 @@
 	}
 }
 
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+/*
+ * This is more-or-less a copy of the original PAL mapping with replicated functionality.
+ * It all repeated here (out of line on the above) for clarity.  Since this is marked __init
+ * code it doesn't hurt that much.  Arguably we should either generalize these two functions
+ * or allow for a platform specific mapping function (a little tricky this early in the boot
+ * but not impossible).
+ *
+ * Please see the genric code for comments if any of this is unclear.
+ *
+ */
+void __init
+sn_PAL_map(void)
+{
+	static u64 pal_start = 0ul, pal_end = 0ul;
+	void *efi_map_start, *efi_map_end, *p;
+	int pg_shift;
+	u64 efi_desc_size;
+	u64 vaddr, mask, psr;
+
+#if EFI_DEBUG
+	printk("SGI: Mapping PAL.\n");
+#endif
+
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+	/* The first time this runs (on the boot processor) we copy the PAL's start and end
+	   addresses because the trim code destroy's the EFI MD */
+	if (!pal_start) {
+		efi_memory_desc_t *md = NULL;
+
+		/* scan the efi memory map to find the PAL_CODE descriptor */
+		for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+			md = (efi_memory_desc_t*)p;
+
+			if (md->type != EFI_PAL_CODE)
+				continue;
+
+			break; /* there's only enough room in this town for one PAL */
+		}
+
+		if (!md)
+			panic(KERN_ERR "SN2: Unable to performace minimalist PAL mapping\n");
+
+		pal_start = md->phys_addr;
+		pal_end = pal_start + (md->num_pages << EFI_PAGE_SHIFT);
+
+		if (pal_end <= pal_start)
+			panic(KERN_ERR "SGI: PAL_CODE MD already hosed\n");
+	}
+
+	/* Find out the smallest page with which we can map the PAL */
+	for (pg_shift = _PAGE_SIZE_64K; pg_shift <= IA64_GRANULE_SHIFT; pg_shift += 2) {
+		/* round the start address down to our test page size */
+		u64 chk_start = pal_start & (~((1ul << pg_shift) - 1));
+
+		/* does the test page size cover the newly aligned size? */
+		if ((1ul << pg_shift) >= (pal_end - chk_start))
+			break;
+	}
+
+	if (pg_shift > IA64_GRANULE_SHIFT)
+		panic(KERN_ERR "SGI: Woah!  PAL code size bigger than a granule!");
+
+	vaddr = (u64)__va(pal_start);
+	mask  = ~((1ul<<pg_shift) - 1);
+
+#if EFI_DEBUG
+	printk("SGI: CPU(%d) pg_shift %d\n", smp_processor_id(), pg_shift);
+	printk("SGI: CPU(%d) actual PAL range phys: 0x%lx-0x%lx\n", smp_processor_id(), pal_start, pal_end);
+	printk("SGI: CPU(%d) PAL mapping from phys:0x%lx-0x%lx to virt:0x%lx-0x%lx\n",
+	       smp_processor_id(),
+	       pal_start & mask, (pal_start & mask) + (1ul<<pg_shift) - 1,
+	       vaddr & mask, (vaddr & mask) + (1ul<<pg_shift) - 1);
+#endif
+
+	psr = ia64_clear_ic();
+	ia64_itr(0x1, IA64_TR_PALCODE, vaddr & mask, pte_val(mk_pte_phys((pal_start & mask), PAGE_KERNEL)), pg_shift);
+	ia64_set_psr(psr);
+	ia64_srlz_i();
+
+	printk(KERN_DEBUG "SGI: Mapped PAL for CPU %d\n", smp_processor_id());
+}
+#endif /* CONFIG_IA64_GENERIC or CONFIG_IA64_SGI_SN2 */
+
+/* This is called early for the boot-CPU only...  we are therefore somewhat restricted in
+ * what we can blindly do. */
 void __init
 efi_init (void)
 {
@@ -542,6 +641,11 @@
 	}
 	printk("\n");
 
+#ifdef CONFIG_IA64_GENERIC
+	/* we have efi.acpi20 so we can do this now */
+	machvec_init(acpi_get_sysname());
+#endif
+
 	runtime = __va(efi.systab->runtime);
 	efi.get_time = phys_get_time;
 	efi.set_time = phys_set_time;
@@ -573,7 +677,8 @@
 	}
 #endif
 
-	efi_map_pal_code();
+	platform_PAL_map();
+
 	efi_enter_virtual_mode();
 }
 
=== arch/ia64/kernel/setup.c 1.13 vs edited ==--- 1.13/arch/ia64/kernel/setup.c	Thu May 29 16:19:59 2003
+++ edited/arch/ia64/kernel/setup.c	Fri Jul 18 14:17:53 2003
@@ -300,6 +300,9 @@
 
 	efi_init();
 
+	/* process SAL system table: */
+	ia64_sal_init(efi.sal_systab);
+
 	iomem_resource.end = ~0UL;	/* FIXME probably belongs elsewhere */
 	find_memory();
 
@@ -316,12 +319,6 @@
 	data_resource.end = virt_to_bus(&_edata) - 1;
 #endif
 
-	/* process SAL system table: */
-	ia64_sal_init(efi.sal_systab);
-
-#ifdef CONFIG_IA64_GENERIC
-	machvec_init(acpi_get_sysname());
-#endif
 
 	/*
 	 *  Set `iobase' to the appropriate address in region 6 (uncached access range).
=== arch/ia64/kernel/smpboot.c 1.14 vs edited ==--- 1.14/arch/ia64/kernel/smpboot.c	Fri May  9 07:42:04 2003
+++ edited/arch/ia64/kernel/smpboot.c	Fri Jul 18 12:07:07 2003
@@ -396,7 +396,7 @@
 	extern int cpu_idle (void);
 
 	Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id());
-	efi_map_pal_code();
+	platform_PAL_map();
 	cpu_init();
 	smp_callin();
 	Dprintk("CPU %d is set to go.\n", smp_processor_id());
=== include/asm-ia64/machvec.h 1.8 vs edited ==--- 1.8/include/asm-ia64/machvec.h	Thu Oct 31 15:39:07 2002
+++ edited/include/asm-ia64/machvec.h	Fri Jul 18 14:23:48 2003
@@ -63,6 +63,7 @@
 typedef void ia64_mv_outb_t (unsigned char, unsigned long);
 typedef void ia64_mv_outw_t (unsigned short, unsigned long);
 typedef void ia64_mv_outl_t (unsigned int, unsigned long);
+typedef void ia64_mv_PAL_map_t (void);
 
 extern void machvec_noop (void);
 
@@ -113,6 +114,7 @@
 #  define platform_outb		ia64_mv.outb
 #  define platform_outw		ia64_mv.outw
 #  define platform_outl		ia64_mv.outl
+#  define platform_PAL_map	ia64_mv.PAL_map
 # endif
 
 struct ia64_machine_vector {
@@ -148,6 +150,7 @@
 	ia64_mv_outb_t *outb;
 	ia64_mv_outw_t *outw;
 	ia64_mv_outl_t *outl;
+	ia64_mv_PAL_map_t *PAL_map;
 };
 
 #define MACHVEC_INIT(name)			\
@@ -183,7 +186,8 @@
 	platform_inl,				\
 	platform_outb,				\
 	platform_outw,				\
-	platform_outl				\
+	platform_outl,				\
+	platform_PAL_map				\
 }
 
 extern struct ia64_machine_vector ia64_mv;
@@ -300,6 +304,9 @@
 #endif
 #ifndef platform_outl
 # define platform_outl		__ia64_outl
+#endif
+#ifndef platform_PAL_map
+# define platform_PAL_map		ia64_generic_PAL_map
 #endif
 
 #endif /* _ASM_IA64_MACHVEC_H */
=== include/asm-ia64/machvec_init.h 1.3 vs edited ==--- 1.3/include/asm-ia64/machvec_init.h	Mon Jun 23 09:46:56 2003
+++ edited/include/asm-ia64/machvec_init.h	Fri Jul 18 14:23:48 2003
@@ -12,6 +12,7 @@
 extern ia64_mv_outb_t __ia64_outb;
 extern ia64_mv_outw_t __ia64_outw;
 extern ia64_mv_outl_t __ia64_outl;
+extern ia64_mv_PAL_map_t ia64_generic_PAL_map;
 
 #define MACHVEC_HELPER(name)									\
  struct ia64_machine_vector machvec_##name __attribute__ ((unused, __section__ (".machvec")))	\
=== include/asm-ia64/machvec_sn2.h 1.6 vs edited ==--- 1.6/include/asm-ia64/machvec_sn2.h	Thu May 29 02:22:05 2003
+++ edited/include/asm-ia64/machvec_sn2.h	Fri Jul 18 12:00:23 2003
@@ -91,5 +91,6 @@
 #define platform_pci_dma_sync_single	sn_pci_dma_sync_single
 #define platform_pci_dma_sync_sg	sn_pci_dma_sync_sg
 #define platform_pci_dma_supported	sn_pci_dma_supported
+#define platform_PAL_map		sn_PAL_map
 
 #endif /* _ASM_IA64_MACHVEC_SN2_H */
=== include/linux/efi.h 1.3 vs edited ==--- 1.3/include/linux/efi.h	Thu Sep 12 11:57:59 2002
+++ edited/include/linux/efi.h	Fri Jul 18 14:23:57 2003
@@ -258,13 +258,13 @@
 }
 
 extern void efi_init (void);
-extern void efi_map_pal_code (void);
 extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
 extern void efi_gettimeofday (struct timeval *tv);
 extern void efi_enter_virtual_mode (void);	/* switch EFI to virtual mode, if possible */
 extern u64 efi_get_iobase (void);
 extern u32 efi_mem_type (unsigned long phys_addr);
 extern u64 efi_mem_attributes (unsigned long phys_addr);
+extern void ia64_generic_PAL_map (void);
 
 /*
  * Variable Attributes

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
  2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
                   ` (7 preceding siblings ...)
  2003-07-19  1:05 ` Christopher Wedgwood
@ 2003-07-22  1:38 ` Bjorn Helgaas
  2003-07-22 21:26 ` Christopher Wedgwood
  9 siblings, 0 replies; 11+ messages in thread
From: Bjorn Helgaas @ 2003-07-22  1:38 UTC (permalink / raw)
  To: linux-ia64

On Friday 18 July 2003 7:05 pm, Christopher Wedgwood wrote:
> On Fri, Jul 18, 2003 at 10:13:02AM -0600, Bjorn Helgaas wrote:
> 
> > But I do prefer the machine vector approach, and there are several
> > other machine vectors used only at boot-time, so I don't think
> > that's an issue.
> 
> I've done this but must say it feels like excessive abstraction and an
> overkill approach.

Take a look at some existing machine vector implemetations
(platform_setup, platform_cpu_init, etc).  You should be
able to place the code to eliminate the #ifdefs, i.e., by
putting the SGI pal_map stuff in a file that's already
SGI-specific.

Bjorn


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2
  2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
                   ` (8 preceding siblings ...)
  2003-07-22  1:38 ` Bjorn Helgaas
@ 2003-07-22 21:26 ` Christopher Wedgwood
  9 siblings, 0 replies; 11+ messages in thread
From: Christopher Wedgwood @ 2003-07-22 21:26 UTC (permalink / raw)
  To: linux-ia64

On Wed, Jul 16, 2003 at 08:22:37AM -0700, Luck, Tony wrote:

> I tried some similar code for Tiger a while ago, but ran into a
> problem as there is other code in the same granule, that isn't
> covered by the address range for PAL routines (I think that the
> other code was the EFI loaded FPSWA code, but I didn't look too
> closely at the time this happened).

Can you send me the memmap for this situation if possible please?

I have an algorithmic approach that should work everywhere but
obviously this requires that *ANY* code executed WB in the same
granule be visible in the EFI memory map so I can be sure to include
those when trying to find the minimum suitable TR to use.

The kicker here of course is that if some code is omitted (not
delcared) in the EFI memory map but actively used...  does anyone do
this?



  --cw

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2003-07-22 21:26 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-16  2:14 [PATCH] (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2 Christopher Wedgwood
2003-07-16 15:22 ` Luck, Tony
2003-07-16 18:23 ` Christopher Wedgwood
2003-07-17 17:42 ` Bjorn Helgaas
2003-07-17 17:57 ` Christopher Wedgwood
2003-07-17 22:52 ` Bjorn Helgaas
2003-07-18  2:22 ` Christopher Wedgwood
2003-07-18 16:13 ` Bjorn Helgaas
2003-07-19  1:05 ` Christopher Wedgwood
2003-07-22  1:38 ` Bjorn Helgaas
2003-07-22 21:26 ` Christopher Wedgwood

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.