-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'x86-olpc-for-linus' of git://git.kernel.org/pub/scm/lin…
…ux/kernel/git/tip/linux-2.6-tip * 'x86-olpc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, olpc: Constify an olpc_ofw() arg x86, olpc: Use pr_debug() for EC commands x86, olpc: Add comment about implicit optimization barrier x86, olpc: Add support for calling into OpenFirmware
- Loading branch information
Showing
9 changed files
with
178 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#ifndef _ASM_X86_OLPC_OFW_H | ||
#define _ASM_X86_OLPC_OFW_H | ||
|
||
/* index into the page table containing the entry OFW occupies */ | ||
#define OLPC_OFW_PDE_NR 1022 | ||
|
||
#define OLPC_OFW_SIG 0x2057464F /* aka "OFW " */ | ||
|
||
#ifdef CONFIG_OLPC_OPENFIRMWARE | ||
|
||
/* run an OFW command by calling into the firmware */ | ||
#define olpc_ofw(name, args, res) \ | ||
__olpc_ofw((name), ARRAY_SIZE(args), args, ARRAY_SIZE(res), res) | ||
|
||
extern int __olpc_ofw(const char *name, int nr_args, const void **args, int nr_res, | ||
void **res); | ||
|
||
/* determine whether OFW is available and lives in the proper memory */ | ||
extern void olpc_ofw_detect(void); | ||
|
||
/* install OFW's pde permanently into the kernel's pgtable */ | ||
extern void setup_olpc_ofw_pgd(void); | ||
|
||
#else /* !CONFIG_OLPC_OPENFIRMWARE */ | ||
|
||
static inline void olpc_ofw_detect(void) { } | ||
static inline void setup_olpc_ofw_pgd(void) { } | ||
|
||
#endif /* !CONFIG_OLPC_OPENFIRMWARE */ | ||
|
||
#endif /* _ASM_X86_OLPC_OFW_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
#include <linux/init.h> | ||
#include <asm/page.h> | ||
#include <asm/setup.h> | ||
#include <asm/io.h> | ||
#include <asm/pgtable.h> | ||
#include <asm/olpc_ofw.h> | ||
|
||
/* address of OFW callback interface; will be NULL if OFW isn't found */ | ||
static int (*olpc_ofw_cif)(int *); | ||
|
||
/* page dir entry containing OFW's pgdir table; filled in by head_32.S */ | ||
u32 olpc_ofw_pgd __initdata; | ||
|
||
static DEFINE_SPINLOCK(ofw_lock); | ||
|
||
#define MAXARGS 10 | ||
|
||
void __init setup_olpc_ofw_pgd(void) | ||
{ | ||
pgd_t *base, *ofw_pde; | ||
|
||
if (!olpc_ofw_cif) | ||
return; | ||
|
||
/* fetch OFW's PDE */ | ||
base = early_ioremap(olpc_ofw_pgd, sizeof(olpc_ofw_pgd) * PTRS_PER_PGD); | ||
if (!base) { | ||
printk(KERN_ERR "failed to remap OFW's pgd - disabling OFW!\n"); | ||
olpc_ofw_cif = NULL; | ||
return; | ||
} | ||
ofw_pde = &base[OLPC_OFW_PDE_NR]; | ||
|
||
/* install OFW's PDE permanently into the kernel's pgtable */ | ||
set_pgd(&swapper_pg_dir[OLPC_OFW_PDE_NR], *ofw_pde); | ||
/* implicit optimization barrier here due to uninline function return */ | ||
|
||
early_iounmap(base, sizeof(olpc_ofw_pgd) * PTRS_PER_PGD); | ||
} | ||
|
||
int __olpc_ofw(const char *name, int nr_args, const void **args, int nr_res, | ||
void **res) | ||
{ | ||
int ofw_args[MAXARGS + 3]; | ||
unsigned long flags; | ||
int ret, i, *p; | ||
|
||
BUG_ON(nr_args + nr_res > MAXARGS); | ||
|
||
if (!olpc_ofw_cif) | ||
return -EIO; | ||
|
||
ofw_args[0] = (int)name; | ||
ofw_args[1] = nr_args; | ||
ofw_args[2] = nr_res; | ||
|
||
p = &ofw_args[3]; | ||
for (i = 0; i < nr_args; i++, p++) | ||
*p = (int)args[i]; | ||
|
||
/* call into ofw */ | ||
spin_lock_irqsave(&ofw_lock, flags); | ||
ret = olpc_ofw_cif(ofw_args); | ||
spin_unlock_irqrestore(&ofw_lock, flags); | ||
|
||
if (!ret) { | ||
for (i = 0; i < nr_res; i++, p++) | ||
*((int *)res[i]) = *p; | ||
} | ||
|
||
return ret; | ||
} | ||
EXPORT_SYMBOL_GPL(__olpc_ofw); | ||
|
||
/* OFW cif _should_ be above this address */ | ||
#define OFW_MIN 0xff000000 | ||
|
||
/* OFW starts on a 1MB boundary */ | ||
#define OFW_BOUND (1<<20) | ||
|
||
void __init olpc_ofw_detect(void) | ||
{ | ||
struct olpc_ofw_header *hdr = &boot_params.olpc_ofw_header; | ||
unsigned long start; | ||
|
||
/* ensure OFW booted us by checking for "OFW " string */ | ||
if (hdr->ofw_magic != OLPC_OFW_SIG) | ||
return; | ||
|
||
olpc_ofw_cif = (int (*)(int *))hdr->cif_handler; | ||
|
||
if ((unsigned long)olpc_ofw_cif < OFW_MIN) { | ||
printk(KERN_ERR "OFW detected, but cif has invalid address 0x%lx - disabling.\n", | ||
(unsigned long)olpc_ofw_cif); | ||
olpc_ofw_cif = NULL; | ||
return; | ||
} | ||
|
||
/* determine where OFW starts in memory */ | ||
start = round_down((unsigned long)olpc_ofw_cif, OFW_BOUND); | ||
printk(KERN_INFO "OFW detected in memory, cif @ 0x%lx (reserving top %ldMB)\n", | ||
(unsigned long)olpc_ofw_cif, (-start) >> 20); | ||
reserve_top_address(-start); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters