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
- Lines: 289
- Date:
2003-11-28 10:26:19.000000000 -0800
- Orig file:
linux-2.4.22/arch/ia64/sn/fakeprom/fpmem.c
- Orig date:
2003-08-25 04:44:39.000000000 -0700
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)