cregit-Linux how code gets into the kernel

Release 4.14 arch/ia64/kernel/sal.c

Directory: arch/ia64/kernel
/*
 * System Abstraction Layer (SAL) interface routines.
 *
 * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co
 *      David Mosberger-Tang <davidm@hpl.hp.com>
 * Copyright (C) 1999 VA Linux Systems
 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/string.h>

#include <asm/delay.h>
#include <asm/page.h>
#include <asm/sal.h>
#include <asm/pal.h>

 __cacheline_aligned DEFINE_SPINLOCK(sal_lock);

unsigned long sal_platform_features;


unsigned short sal_revision;

unsigned short sal_version;


#define SAL_MAJOR(x) ((x) >> 8)

#define SAL_MINOR(x) ((x) & 0xff)

static struct {
	
void *addr;	/* function entry point */
	
void *gpval;	/* gp value to use */

} pdesc;


static long default_handler (void) { return -1; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)12100.00%1100.00%
Total12100.00%1100.00%

ia64_sal_handler ia64_sal = (ia64_sal_handler) default_handler; ia64_sal_desc_ptc_t *ia64_ptc_domain_info;
const char * ia64_sal_strerror (long status) { const char *str; switch (status) { case 0: str = "Call completed without error"; break; case 1: str = "Effect a warm boot of the system to complete " "the update"; break; case -1: str = "Not implemented"; break; case -2: str = "Invalid argument"; break; case -3: str = "Call completed with error"; break; case -4: str = "Virtual address not registered"; break; case -5: str = "No information available"; break; case -6: str = "Insufficient space to add the entry"; break; case -7: str = "Invalid entry_addr value"; break; case -8: str = "Invalid interrupt vector"; break; case -9: str = "Requested memory not available"; break; case -10: str = "Unable to write to the NVM device"; break; case -11: str = "Invalid partition type specified"; break; case -12: str = "Invalid NVM_Object id specified"; break; case -13: str = "NVM_Object already has the maximum number " "of partitions"; break; case -14: str = "Insufficient space in partition for the " "requested write sub-function"; break; case -15: str = "Insufficient data buffer space for the " "requested read record sub-function"; break; case -16: str = "Scratch buffer required for the write/delete " "sub-function"; break; case -17: str = "Insufficient space in the NVM_Object for the " "requested create sub-function"; break; case -18: str = "Invalid value specified in the partition_rec " "argument"; break; case -19: str = "Record oriented I/O not supported for this " "partition"; break; case -20: str = "Bad format of record to be written or " "required keyword variable not " "specified"; break; default: str = "Unknown SAL status code"; break; } return str; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)236100.00%1100.00%
Total236100.00%1100.00%


void __init ia64_sal_handler_init (void *entry_point, void *gpval) { /* fill in the SAL procedure descriptor and point ia64_sal to it: */ pdesc.addr = entry_point; pdesc.gpval = gpval; ia64_sal = (ia64_sal_handler) &pdesc; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)35100.00%1100.00%
Total35100.00%1100.00%


static void __init check_versions (struct ia64_sal_systab *systab) { sal_revision = (systab->sal_rev_major << 8) | systab->sal_rev_minor; sal_version = (systab->sal_b_rev_major << 8) | systab->sal_b_rev_minor; /* Check for broken firmware */ if ((sal_revision == SAL_VERSION_CODE(49, 29)) && (sal_version == SAL_VERSION_CODE(49, 29))) { /* * Old firmware for zx2000 prototypes have this weird version number, * reset it to something sane. */ sal_revision = SAL_VERSION_CODE(2, 8); sal_version = SAL_VERSION_CODE(0, 0); } if (ia64_platform_is("sn2") && (sal_revision == SAL_VERSION_CODE(2, 9))) /* * SGI Altix has hard-coded version 2.9 in their prom * but they actually implement 3.2, so let's fix it here. */ sal_revision = SAL_VERSION_CODE(3, 2); }

Contributors

PersonTokensPropCommitsCommitProp
David Mosberger-Tang8372.81%125.00%
Alexander Chiang2824.56%125.00%
Linus Torvalds (pre-git)21.75%125.00%
Matthew Wilcox10.88%125.00%
Total114100.00%4100.00%


static void __init sal_desc_entry_point (void *p) { struct ia64_sal_desc_entry_point *ep = p; ia64_pal_handler_init(__va(ep->pal_proc)); ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp)); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3680.00%133.33%
Matthew Wilcox613.33%133.33%
David Mosberger-Tang36.67%133.33%
Total45100.00%3100.00%

#ifdef CONFIG_SMP
static void __init set_smp_redirect (int flag) { #ifndef CONFIG_HOTPLUG_CPU if (no_int_routing) smp_int_redirect &= ~flag; else smp_int_redirect |= flag; #else /* * For CPU Hotplug we dont want to do any chipset supported * interrupt redirection. The reason is this would require that * All interrupts be stopped and hard bind the irq to a cpu. * Later when the interrupt is fired we need to set the redir hint * on again in the vector. This is cumbersome for something that the * user mode irq balancer will solve anyways. */ no_int_routing=1; smp_int_redirect &= ~flag; #endif }

Contributors

PersonTokensPropCommitsCommitProp
Matthew Wilcox2458.54%133.33%
Andrew Morton1639.02%133.33%
Simon Arlott12.44%133.33%
Total41100.00%3100.00%

#else #define set_smp_redirect(flag) do { } while (0) #endif
static void __init sal_desc_platform_feature (void *p) { struct ia64_sal_desc_platform_feature *pf = p; sal_platform_features = pf->feature_mask; printk(KERN_INFO "SAL Platform features:"); if (!sal_platform_features) { printk(" None\n"); return; } if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK) printk(" BusLock"); if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT) { printk(" IRQ_Redirection"); set_smp_redirect(SMP_IRQ_REDIRECTION); } if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT) { printk(" IPI_Redirection"); set_smp_redirect(SMP_IPI_REDIRECTION); } if (sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT) printk(" ITC_Drift"); printk("\n"); }

Contributors

PersonTokensPropCommitsCommitProp
Matthew Wilcox5450.94%120.00%
Linus Torvalds (pre-git)4845.28%240.00%
David Mosberger-Tang43.77%240.00%
Total106100.00%5100.00%

#ifdef CONFIG_SMP
static void __init sal_desc_ap_wakeup (void *p) { struct ia64_sal_desc_ap_wakeup *ap = p; switch (ap->mechanism) { case IA64_SAL_AP_EXTERNAL_INT: ap_wakeup_vector = ap->vector; printk(KERN_INFO "SAL: AP wakeup using external interrupt " "vector 0x%lx\n", ap_wakeup_vector); break; default: printk(KERN_ERR "SAL: AP wakeup mechanism unsupported!\n"); break; } }

Contributors

PersonTokensPropCommitsCommitProp
Matthew Wilcox4992.45%150.00%
Linus Torvalds (pre-git)47.55%150.00%
Total53100.00%2100.00%


static void __init chk_nointroute_opt(void) { char *cp; for (cp = boot_command_line; *cp; ) { if (memcmp(cp, "nointroute", 10) == 0) { no_int_routing = 1; printk ("no_int_routing on\n"); break; } else { while (*cp != ' ' && *cp) ++cp; while (*cp == ' ') ++cp; } } }

Contributors

PersonTokensPropCommitsCommitProp
Rohit Seth7598.68%150.00%
Alon Bar-Lev11.32%150.00%
Total76100.00%2100.00%

#else
static void __init sal_desc_ap_wakeup(void *p) { }

Contributors

PersonTokensPropCommitsCommitProp
Matthew Wilcox10100.00%1100.00%
Total10100.00%1100.00%

#endif /* * HP rx5670 firmware polls for interrupts during SAL_CACHE_FLUSH by reading * cr.ivr, but it never writes cr.eoi. This leaves any interrupt marked as * "in-service" and masks other interrupts of equal or lower priority. * * HP internal defect reports: F1859, F2775, F3031. */ static int sal_cache_flush_drops_interrupts;
static int __init force_pal_cache_flush(char *str) { sal_cache_flush_drops_interrupts = 1; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Alexander Chiang18100.00%1100.00%
Total18100.00%1100.00%

early_param("force_pal_cache_flush", force_pal_cache_flush);
void __init check_sal_cache_flush (void) { unsigned long flags; int cpu; u64 vector, cache_type = 3; struct ia64_sal_retval isrv; if (sal_cache_flush_drops_interrupts) return; cpu = get_cpu(); local_irq_save(flags); /* * Send ourselves a timer interrupt, wait until it's reported, and see * if SAL_CACHE_FLUSH drops it. */ platform_send_ipi(cpu, IA64_TIMER_VECTOR, IA64_IPI_DM_INT, 0); while (!ia64_get_irr(IA64_TIMER_VECTOR)) cpu_relax(); SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0); if (isrv.status) printk(KERN_ERR "SAL_CAL_FLUSH failed with %ld\n", isrv.status); if (ia64_get_irr(IA64_TIMER_VECTOR)) { vector = ia64_get_ivr(); ia64_eoi(); WARN_ON(vector != IA64_TIMER_VECTOR); } else { sal_cache_flush_drops_interrupts = 1; printk(KERN_ERR "SAL: SAL_CACHE_FLUSH drops interrupts; " "PAL_CACHE_FLUSH will be used instead\n"); ia64_eoi(); } local_irq_restore(flags); put_cpu(); }

Contributors

PersonTokensPropCommitsCommitProp
Björn Helgaas9563.33%125.00%
Troy Heber4228.00%125.00%
Alexander Chiang138.67%250.00%
Total150100.00%4100.00%


s64 ia64_sal_cache_flush (u64 cache_type) { struct ia64_sal_retval isrv; if (sal_cache_flush_drops_interrupts) { unsigned long flags; u64 progress; s64 rc; progress = 0; local_irq_save(flags); rc = ia64_pal_cache_flush(cache_type, PAL_CACHE_FLUSH_INVALIDATE, &progress, NULL); local_irq_restore(flags); return rc; } SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0); return isrv.status; }

Contributors

PersonTokensPropCommitsCommitProp
Björn Helgaas85100.00%1100.00%
Total85100.00%1100.00%

EXPORT_SYMBOL_GPL(ia64_sal_cache_flush);
void __init ia64_sal_init (struct ia64_sal_systab *systab) { char *p; int i; if (!systab) { printk(KERN_WARNING "Hmm, no SAL System Table.\n"); return; } if (strncmp(systab->signature, "SST_", 4) != 0) printk(KERN_ERR "bad signature in system table!"); check_versions(systab); #ifdef CONFIG_SMP chk_nointroute_opt(); #endif /* revisions are coded in BCD, so %x does the job for us */ printk(KERN_INFO "SAL %x.%x: %.32s %.32s%sversion %x.%x\n", SAL_MAJOR(sal_revision), SAL_MINOR(sal_revision), systab->oem_id, systab->product_id, systab->product_id[0] ? " " : "", SAL_MAJOR(sal_version), SAL_MINOR(sal_version)); p = (char *) (systab + 1); for (i = 0; i < systab->entry_count; i++) { /* * The first byte of each entry type contains the type * descriptor. */ switch (*p) { case SAL_DESC_ENTRY_POINT: sal_desc_entry_point(p); break; case SAL_DESC_PLATFORM_FEATURE: sal_desc_platform_feature(p); break; case SAL_DESC_PTC: ia64_ptc_domain_info = (ia64_sal_desc_ptc_t *)p; break; case SAL_DESC_AP_WAKEUP: sal_desc_ap_wakeup(p); break; } p += SAL_DESC_SIZE(*p); } }

Contributors

PersonTokensPropCommitsCommitProp
Matthew Wilcox16081.63%116.67%
Linus Torvalds (pre-git)178.67%233.33%
David Mosberger-Tang115.61%233.33%
Rohit Seth84.08%116.67%
Total196100.00%6100.00%


int ia64_sal_oemcall(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7) { if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX) return -1; SAL_CALL(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6, arg7); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Dean Nelson73100.00%1100.00%
Total73100.00%1100.00%

EXPORT_SYMBOL(ia64_sal_oemcall);
int ia64_sal_oemcall_nolock(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7) { if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX) return -1; SAL_CALL_NOLOCK(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6, arg7); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Dean Nelson73100.00%1100.00%
Total73100.00%1100.00%

EXPORT_SYMBOL(ia64_sal_oemcall_nolock);
int ia64_sal_oemcall_reentrant(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7) { if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX) return -1; SAL_CALL_REENTRANT(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6, arg7); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Dean Nelson73100.00%1100.00%
Total73100.00%1100.00%

EXPORT_SYMBOL(ia64_sal_oemcall_reentrant);
long ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second, unsigned long *drift_info) { struct ia64_sal_retval isrv; SAL_CALL(isrv, SAL_FREQ_BASE, which, 0, 0, 0, 0, 0, 0); *ticks_per_second = isrv.v0; *drift_info = isrv.v1; return isrv.status; }

Contributors

PersonTokensPropCommitsCommitProp
Xiantao Zhang63100.00%1100.00%
Total63100.00%1100.00%

EXPORT_SYMBOL_GPL(ia64_sal_freq_base);

Overall Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)44727.85%315.79%
Matthew Wilcox33620.93%15.26%
Dean Nelson23714.77%15.26%
Björn Helgaas18811.71%15.26%
David Mosberger-Tang1106.85%315.79%
Rohit Seth835.17%15.26%
Xiantao Zhang734.55%15.26%
Alexander Chiang664.11%315.79%
Troy Heber422.62%15.26%
Andrew Morton161.00%15.26%
Thomas Gleixner50.31%15.26%
Alon Bar-Lev10.06%15.26%
Simon Arlott10.06%15.26%
Total1605100.00%19100.00%
Directory: arch/ia64/kernel
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.