Skip to contentSkip to conversation

(2.4.21-bjorn-bk) Minimalist PAL mapping for SN2

PATCH In review Christopher Wedgwood 3 participants 11 messages Jul 16, 2003 – Jul 22, 2003 EFI

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 (2.4.21-bjorn-bk) Minimalist PAL mapping for SN2

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 [email protected] 1.1148
# Allow alternate (minimalist) PAL mapping for SN2.
# --------------------------------------------
#

arch/ia64/kernel/efi.c +114 -1
diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
@@ -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();
#1 lore raw
Quoted 4 lines

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

#2 lore raw
In reply to Christopher Wedgwood
Quoted 3 lines · Tony

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

#3 lore raw
In reply to Christopher Wedgwood
Quoted 3 lines · Christopher Wedgwood

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

#4 lore raw
In reply to Christopher Wedgwood
Quoted 2 lines · Bjorn Helgaas

- 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.

Quoted 3 lines

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?

Quoted 2 lines

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.

Quoted 3 lines

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.

Quoted 4 lines

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

#5 lore raw
In reply to Christopher Wedgwood
Quoted 5 lines · Christopher Wedgwood

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.

Quoted 6 lines
Quoted 3 lines

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.

Quoted 7 lines
Quoted 4 lines

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

#6 lore raw
In reply to Christopher Wedgwood
Quoted 2 lines · Bjorn Helgaas

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.

Quoted 3 lines

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?

Quoted 2 lines

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.

Quoted 2 lines

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.

Quoted 3 lines

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

#7 lore raw
In reply to Christopher Wedgwood
Quoted 9 lines · Christopher Wedgwood
Quoted 2 lines · Bjorn Helgaas

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.

Quoted 6 lines

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

#8 lore raw
In reply to Christopher Wedgwood
Quoted 3 lines · Bjorn Helgaas

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

#9 lore raw
In reply to Christopher Wedgwood
Quoted 8 lines · Christopher Wedgwood
Quoted 3 lines · Bjorn Helgaas

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

#10 lore raw
In reply to Christopher Wedgwood
Quoted 5 lines · Tony

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