patch-2.4.23 linux-2.4.23/arch/ia64/sn/fakeprom/fpmem.c

Next file: linux-2.4.23/arch/ia64/sn/fakeprom/fpmem.h
Previous file: linux-2.4.23/arch/ia64/scripts/make_gas_hint_test.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.22/arch/ia64/sn/fakeprom/fpmem.c linux-2.4.23/arch/ia64/sn/fakeprom/fpmem.c
@@ -17,8 +17,58 @@
  * 	  klconfig to efi_memmap
  */
 
+
+/*
+ * Sometimes it is useful to build a fake prom with a memmap that matches another
+ * platform. There are restrictions on how successful you will be, but here
+ * are the instructions for what I have used in the past & had good luck:
+ *
+ * 	- compile a kernel for the target platform (like zx1) with the following
+ * 	  set: 
+ * 	  	#define EFI_DEBUG 1		# in arch/ia64/kernel/efi.c
+ * 	  	#define SRAT_DEBUG		# in drivers/acpi/numa.c
+ *
+ *	- this causes the kernel to dump the memmap & SRAT during boot.
+ *
+ *	- copy the console output to a file.
+ *
+ *	- run the following script with the file as input:
+ *		
+ *			#!/bin/sh
+ *			
+ *			awk '
+ *			/^mem/ {
+ *			        printf "\t{%s, %sUL, %sUL, %sUL},\n", $4, $7, $11, $12
+ *			} 
+ *			/SRAT Memory/ {
+ *			        if (srat != 1) print "SRAT"
+ *			        srat = 1
+ *			        for (i=1; i<=0;i++)
+ *			                printf "%4d |%s|\n", i, $i
+ *			        printf "\t{%s, %sUL, %sUL, %sUL},\n", $4, $6, $8, $13
+ *			}
+ *			BEGIN {
+ *			        FS="[ \[\)\(\t:=,-]"
+ *			} '
+ *			
+ * 	- this converts the memmap & SRAT info into C code array initilization statements.
+ *
+ * 	- copy & paste the initialization statements into the arrays below. Look for
+ * 	  comments "PASTE xxx HERE". In general, on the MEMMAP is present on most other
+ * 	  systems. If you have an SRAT, you may need to hack the number of nodes in fw-emu.
+ * 	  Good luck...
+ *
+ * 	- set "#define FAKE_MEMMAP 1
+ *
+ * 	- When running medusa, make sure you set the node1_memory_config to cover the
+ * 	  amount of memory that you are going to use. Also note that you can run the
+ * 	  kernel in "alias" space (starts at phy adr 0). This is kinda tricky, though
+ */
+
+
 #include <linux/config.h>
 #include <linux/efi.h>
+#include <linux/acpi.h>
 #include "fpmem.h"
 
 /*
@@ -77,9 +127,9 @@
 /* For SN, get the index th nasid */
 
 int
-GetNasid(int index)
+GetNasid(int cnode)
 {
-	return sn_memmap[index].nasid ;
+	return sn_memmap[cnode].nasid ;
 }
 
 node_memmap_t
@@ -94,6 +144,21 @@
 	return  sn_memmap[cnode].cpuconfig & (1UL<<cpu);
 }
 
+void
+GetLogicalCpu(int bsp, int *nasidp, int *cpup)
+{
+	int cnode, cpu;
+
+	for (cnode=0; cnode<GetNumNodes(); cnode++) {
+		for (cpu=0; cpu<MAX_CPUS_NODE; cpu++)
+			if (IsCpuPresent(cnode,cpu)) {
+				*nasidp = GetNasid(cnode);
+				*cpup = cpu;
+				if (bsp-- == 0)
+					return;
+			}
+	}
+}
 
 /*
  * Made this into an explicit case statement so that
@@ -102,31 +167,41 @@
  */
 
 #ifdef SGI_SN2
-int
-IsBankPresent(int index, node_memmap_t nmemmap)
-{
-	switch (index) {
-		case 0:return BankPresent(nmemmap.b0size);
-		case 1:return BankPresent(nmemmap.b1size);
-		case 2:return BankPresent(nmemmap.b2size);
-		case 3:return BankPresent(nmemmap.b3size);
-		default:return -1 ;
-	}
-}
-
-int
+long
 GetBankSize(int index, node_memmap_t nmemmap)
 {
+	int bsize, bdou, hack;
 	/*
 	 * Add 2 because there are 4 dimms per bank.
 	 */
         switch (index) {
-                case 0:return 2 + ((long)nmemmap.b0size + nmemmap.b0dou);
-                case 1:return 2 + ((long)nmemmap.b1size + nmemmap.b1dou);
-                case 2:return 2 + ((long)nmemmap.b2size + nmemmap.b2dou);
-                case 3:return 2 + ((long)nmemmap.b3size + nmemmap.b3dou);
+                case 0:
+			bsize = nmemmap.b0size;
+			bdou = nmemmap.b0dou;
+			hack = nmemmap.hack0;
+			break;
+                case 1:
+			bsize = nmemmap.b1size;
+			bdou = nmemmap.b1dou;
+			hack = nmemmap.hack1;
+			break;
+                case 2:
+			bsize = nmemmap.b2size;
+			bdou = nmemmap.b2dou;
+			hack = nmemmap.hack2;
+			break;
+                case 3:
+			bsize = nmemmap.b3size;
+			bdou = nmemmap.b3dou;
+			hack = nmemmap.hack3;
+			break;
                 default:return -1 ;
         }
+
+	if (bsize < 6 && hack == 0)
+		return (1UL<<((2+bsize+bdou)+SN2_BANK_SIZE_SHIFT))*31/32;
+	else 
+		return (16*MB)*hack;
 }
 
 #endif
@@ -141,6 +216,99 @@
         md->attribute = attr;
 }
 
+
+//#define FAKE_MEMMAP 1
+#ifdef FAKE_MEMMAP
+
+#define OFF 0x3000000000UL
+struct {
+	unsigned long	type;
+	unsigned long	attr;
+	unsigned long	start;
+	unsigned long	end;
+} mdx[] = {
+	/* PASTE SRAT HERE */
+};
+
+struct srat {
+	unsigned long	start;
+	unsigned long	len;
+	unsigned long	type;
+	unsigned long	pxm;
+} srat[] = {
+
+	/* PASTE SRAT HERE */
+
+};
+
+
+
+void *
+build_memory_srat(struct acpi_table_memory_affinity *ptr)
+{
+	int i;
+	int n = sizeof(srat)/sizeof(struct srat);
+
+        for (i=0; i<n; i++)
+		srat[i].start += OFF;
+        for (i=0; i<n; i++) {
+                ptr->header.type = ACPI_SRAT_MEMORY_AFFINITY;
+                ptr->header.length = sizeof(struct acpi_table_memory_affinity);
+                ptr->proximity_domain = srat[i].pxm;
+                ptr->base_addr_lo = srat[i].start & 0xffffffff;
+                ptr->length_lo = srat[i].len & 0xffffffff;
+                ptr->base_addr_hi = srat[i].start >> 32;
+                ptr->length_hi = srat[i].len >> 32;
+                ptr->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
+                ptr->flags.enabled = 1;
+		ptr++;
+        }
+	return ptr;
+}
+
+int
+build_efi_memmap(void *md, int mdsize)
+{
+	int		i;
+
+	for (i=0; i<sizeof(mdx)/32; i++) {
+		mdx[i].start += OFF;
+		mdx[i].end += OFF;
+	}
+	for (i=0; i<sizeof(mdx)/32; i++) {
+			build_mem_desc(md, mdx[i].type, mdx[i].start, mdx[i].end-mdx[i].start, mdx[i].attr);
+			md += mdsize;
+	}
+	return i;
+
+}
+
+#else /* ! FAKE_MEMMAP */
+
+void *
+build_memory_srat(struct acpi_table_memory_affinity *ptr)
+{
+	int	cnode, nasid;
+
+	for (cnode=0; cnode<GetNumNodes(); cnode++) {
+		nasid = GetNasid(cnode);
+		ptr->header.type = ACPI_SRAT_MEMORY_AFFINITY;
+		ptr->header.length = sizeof(struct acpi_table_memory_affinity);
+		ptr->proximity_domain = PROXIMITY_DOMAIN(nasid);
+		ptr->base_addr_lo = 0;
+		ptr->length_lo = 0;
+#if defined(SGI_SN2)
+		ptr->base_addr_hi = (nasid<<6) | (3<<4);
+		ptr->length_hi = (MD_BANKSIZE*MD_BANKS_PER_NODE)>>32;
+#endif
+		ptr->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
+		ptr->flags.enabled = 1;
+		ptr++;
+	}
+	return ptr;
+}
+
+
 int
 build_efi_memmap(void *md, int mdsize)
 {
@@ -148,7 +316,6 @@
 	int		cnode,bank ;
 	int		nasid ;
 	node_memmap_t	membank_info ;
-	int		bsize;
 	int		count = 0 ;
 	long		paddr, hole, numbytes;
 
@@ -157,18 +324,9 @@
 		nasid = GetNasid(cnode) ;
 		membank_info = GetMemBankInfo(cnode) ;
 		for (bank=0;bank<MD_BANKS_PER_NODE;bank++) {
-			if (IsBankPresent(bank, membank_info)) {
-				bsize = GetBankSize(bank, membank_info) ;
+			numbytes = GetBankSize(bank, membank_info);
+			if (numbytes) {
                                 paddr = PHYS_ADDRESS(nasid, (long)bank<<MD_BANK_SHFT);
-                                numbytes = BankSizeBytes(bsize);
-#ifdef SGI_SN2
-				/* 
-				 * Ignore directory.
-				 * Shorten memory chunk by 1 page - makes a better
-				 * testcase & is more like the real PROM.
-				 */
-				numbytes = numbytes * 31 / 32;
-#endif
 				/*
 				 * Only emulate the memory prom grabs
 				 * if we have lots of memory, to allow
@@ -242,6 +400,7 @@
 	}
 	return count ;
 }
+#endif /* FAKE_MEMMAP */
 
 void
 build_init(unsigned long args)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)