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 @@
* License. See the file "COPYING" in the main directory of this archive
* 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
* PROM revision numbers, in /proc
* PROM revision numbers and banners, in /proc
*/
#include <linux/config.h>
#include <linux/module.h>
......@@ -45,9 +45,18 @@ MODULE_LICENSE("GPL");
# define TRACE()
#endif
/* Architected IA64 firmware space */
#define FW_BASE 0x00000000FF000000
#define FW_TOP 0x0000000100000000
/* Sub-regions determined by bits in Node Offset */
#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
/* Standard Intel FIT entry types */
#define FIT_ENTRY_FIT_HEADER 0x00 /* FIT header entry */
......@@ -125,6 +134,26 @@ fit_type_name(unsigned char 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
* 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
......@@ -194,6 +223,8 @@ dump_version(char *page, unsigned long *fit)
int nentries;
int fentry;
unsigned long qw;
int len;
nasid_t nasid = NASID_GET(fit);
TRACE();
......@@ -203,10 +234,31 @@ dump_version(char *page, unsigned long *fit)
for (fentry = 0; fentry < nentries; fentry++) {
qw = readq(fit + 2 * fentry + 1);
if (FIT_TYPE(qw) == FIT_ENTRY_SAL_A)
return sprintf(page, "%x.%02x\n",
FIT_MAJOR(qw), FIT_MINOR(qw));
break;
}
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 */
......@@ -278,14 +330,10 @@ lookup_fit(int nasid)
DPRINTK("pointer to fit at %p\n", (void *)fitp);
fit_paddr = readq(fitp);
DPRINTK("fit pointer contains %lx\n", fit_paddr);
/* snag just the node-relative offset */
fit_paddr &= ~0ul >> (63-35);
/* the pointer to the FIT is relative to IA-64 compatibility
* 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);
BUG_ON(!valid_fw_addr(fit_paddr));
fit_vaddr = (void *)convert_fw_addr(nasid, fit_paddr);
DPRINTK("fit at %p\n", (void *)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