Commit 01b635de authored by Brian J. Johnson's avatar Brian J. Johnson Committed by Tony Luck

[IA64-SGI] Add full PROM version banner to /proc/sgi_prominfo/nodeXX/version.

Signed-off-by: default avatarBrian J. Johnson <bjohnson@sgi.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 65fd90f1
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All Rights Reserved. * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All Rights Reserved.
* *
* Module to export the system's Firmware Interface Tables, including * Module to export the system's Firmware Interface Tables, including
* PROM revision numbers, in /proc * PROM revision numbers and banners, in /proc
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -45,9 +45,18 @@ MODULE_LICENSE("GPL"); ...@@ -45,9 +45,18 @@ MODULE_LICENSE("GPL");
# define TRACE() # define TRACE()
#endif #endif
/* Architected IA64 firmware space */
#define FW_BASE 0x00000000FF000000
#define FW_TOP 0x0000000100000000
/* Sub-regions determined by bits in Node Offset */ /* Sub-regions determined by bits in Node Offset */
#define LB_PROM_SPACE 0x0000000700000000ul /* Local LB PROM */ #define LB_PROM_SPACE 0x0000000700000000ul /* Local LB PROM */
/* Offset of PROM banner pointers in SAL A and SAL B */
#define SAL_A_BANNER_OFFSET (1 * 16)
#define SAL_B_BANNER_OFFSET (3 * 16)
#define FIT_SIGNATURE 0x2020205f5449465ful #define FIT_SIGNATURE 0x2020205f5449465ful
/* Standard Intel FIT entry types */ /* Standard Intel FIT entry types */
#define FIT_ENTRY_FIT_HEADER 0x00 /* FIT header entry */ #define FIT_ENTRY_FIT_HEADER 0x00 /* FIT header entry */
...@@ -125,6 +134,26 @@ fit_type_name(unsigned char type) ...@@ -125,6 +134,26 @@ fit_type_name(unsigned char type)
return "Unknown type"; return "Unknown type";
} }
static unsigned long
convert_fw_addr(nasid_t nasid, unsigned long addr)
{
/* snag just the node-relative offset */
addr &= ~0ul >> (63-35);
/* the pointer to SAL A is relative to IA-64 compatibility
* space. However, the PROM is mapped at a different offset
* in MMR space (both local and global)
*/
addr += 0x700000000;
return GLOBAL_MMR_ADDR(nasid, addr);
}
static int
valid_fw_addr(unsigned long addr)
{
addr &= ~(1ul << 63); /* Clear cached/uncached bit */
return (addr >= FW_BASE && addr < FW_TOP);
}
/* These two routines read the FIT table directly from the FLASH PROM /* These two routines read the FIT table directly from the FLASH PROM
* on a specific node. The PROM can only be accessed using aligned 64 * on a specific node. The PROM can only be accessed using aligned 64
* bit reads, so we do that and then shift and mask the result to get * bit reads, so we do that and then shift and mask the result to get
...@@ -194,6 +223,8 @@ dump_version(char *page, unsigned long *fit) ...@@ -194,6 +223,8 @@ dump_version(char *page, unsigned long *fit)
int nentries; int nentries;
int fentry; int fentry;
unsigned long qw; unsigned long qw;
int len;
nasid_t nasid = NASID_GET(fit);
TRACE(); TRACE();
...@@ -203,10 +234,31 @@ dump_version(char *page, unsigned long *fit) ...@@ -203,10 +234,31 @@ dump_version(char *page, unsigned long *fit)
for (fentry = 0; fentry < nentries; fentry++) { for (fentry = 0; fentry < nentries; fentry++) {
qw = readq(fit + 2 * fentry + 1); qw = readq(fit + 2 * fentry + 1);
if (FIT_TYPE(qw) == FIT_ENTRY_SAL_A) if (FIT_TYPE(qw) == FIT_ENTRY_SAL_A)
return sprintf(page, "%x.%02x\n", break;
FIT_MAJOR(qw), FIT_MINOR(qw));
} }
return 0; if (fentry >= nentries)
return 0;
len = sprintf(page, "%x.%02x\n", FIT_MAJOR(qw), FIT_MINOR(qw));
page += len;
qw = readq(fit + 2 * fentry); /* Address of SAL A */
DPRINTK("SAL A at %p\n", (void *)qw);
if (!valid_fw_addr(qw))
return len;
qw += SAL_A_BANNER_OFFSET;
qw = convert_fw_addr(nasid, qw);
DPRINTK("Banner ptr at %p\n", (void *)qw);
qw = readq(qw); /* Address of banner */
if (!valid_fw_addr(qw))
return len;
qw = convert_fw_addr(nasid, qw);
DPRINTK("Banner at %p\n", (void *)qw);
len += snprintf(page, PAGE_SIZE-len, "%s\n", (char *)qw);
return len;
} }
/* same as in proc_misc.c */ /* same as in proc_misc.c */
...@@ -278,14 +330,10 @@ lookup_fit(int nasid) ...@@ -278,14 +330,10 @@ lookup_fit(int nasid)
DPRINTK("pointer to fit at %p\n", (void *)fitp); DPRINTK("pointer to fit at %p\n", (void *)fitp);
fit_paddr = readq(fitp); fit_paddr = readq(fitp);
DPRINTK("fit pointer contains %lx\n", fit_paddr); DPRINTK("fit pointer contains %lx\n", fit_paddr);
/* snag just the node-relative offset */
fit_paddr &= ~0ul >> (63-35); BUG_ON(!valid_fw_addr(fit_paddr));
/* the pointer to the FIT is relative to IA-64 compatibility fit_vaddr = (void *)convert_fw_addr(nasid, fit_paddr);
* space. However, the PROM is mapped at a different offset
* in MMR space (both local and global)
*/
fit_paddr += 0x700000000;
fit_vaddr = (void *)GLOBAL_MMR_ADDR(nasid, fit_paddr);
DPRINTK("fit at %p\n", (void *)fit_vaddr); DPRINTK("fit at %p\n", (void *)fit_vaddr);
return fit_vaddr; return fit_vaddr;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment