mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 09:08:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
10
arch/mips/fw/arc/Makefile
Normal file
10
arch/mips/fw/arc/Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# Makefile for the ARC prom monitor library routines under Linux.
|
||||
#
|
||||
|
||||
lib-y += cmdline.o env.o file.o identify.o init.o \
|
||||
misc.o salone.o time.o tree.o
|
||||
|
||||
lib-$(CONFIG_ARC_MEMORY) += memory.o
|
||||
lib-$(CONFIG_ARC_CONSOLE) += arc_con.o
|
||||
lib-$(CONFIG_ARC_PROMLIB) += promlib.o
|
50
arch/mips/fw/arc/arc_con.c
Normal file
50
arch/mips/fw/arc/arc_con.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Wrap-around code for a console using the
|
||||
* ARC io-routines.
|
||||
*
|
||||
* Copyright (c) 1998 Harald Koerfgen
|
||||
* Copyright (c) 2001 Ralf Baechle
|
||||
* Copyright (c) 2002 Thiemo Seufer
|
||||
*/
|
||||
#include <linux/tty.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/sgialib.h>
|
||||
|
||||
static void prom_console_write(struct console *co, const char *s,
|
||||
unsigned count)
|
||||
{
|
||||
/* Do each character */
|
||||
while (count--) {
|
||||
if (*s == '\n')
|
||||
prom_putchar('\r');
|
||||
prom_putchar(*s++);
|
||||
}
|
||||
}
|
||||
|
||||
static int prom_console_setup(struct console *co, char *options)
|
||||
{
|
||||
return !(prom_flags & PROM_FLAG_USE_AS_CONSOLE);
|
||||
}
|
||||
|
||||
static struct console arc_cons = {
|
||||
.name = "arc",
|
||||
.write = prom_console_write,
|
||||
.setup = prom_console_setup,
|
||||
.flags = CON_PRINTBUFFER,
|
||||
.index = -1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Register console.
|
||||
*/
|
||||
|
||||
static int __init arc_console_init(void)
|
||||
{
|
||||
register_console(&arc_cons);
|
||||
|
||||
return 0;
|
||||
}
|
||||
console_initcall(arc_console_init);
|
104
arch/mips/fw/arc/cmdline.c
Normal file
104
arch/mips/fw/arc/cmdline.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* cmdline.c: Kernel command line creation using ARCS argc/argv.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
#include <linux/bug.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/sgialib.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
||||
#undef DEBUG_CMDLINE
|
||||
|
||||
static char *ignored[] = {
|
||||
"ConsoleIn=",
|
||||
"ConsoleOut=",
|
||||
"SystemPartition=",
|
||||
"OSLoader=",
|
||||
"OSLoadPartition=",
|
||||
"OSLoadFilename=",
|
||||
"OSLoadOptions="
|
||||
};
|
||||
|
||||
static char *used_arc[][2] = {
|
||||
{ "OSLoadPartition=", "root=" },
|
||||
{ "OSLoadOptions=", "" }
|
||||
};
|
||||
|
||||
static char * __init move_firmware_args(char* cp)
|
||||
{
|
||||
char *s;
|
||||
int actr, i;
|
||||
|
||||
actr = 1; /* Always ignore argv[0] */
|
||||
|
||||
while (actr < prom_argc) {
|
||||
for(i = 0; i < ARRAY_SIZE(used_arc); i++) {
|
||||
int len = strlen(used_arc[i][0]);
|
||||
|
||||
if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
|
||||
/* Ok, we want it. First append the replacement... */
|
||||
strcat(cp, used_arc[i][1]);
|
||||
cp += strlen(used_arc[i][1]);
|
||||
/* ... and now the argument */
|
||||
s = strchr(prom_argv(actr), '=');
|
||||
if (s) {
|
||||
s++;
|
||||
strcpy(cp, s);
|
||||
cp += strlen(s);
|
||||
}
|
||||
*cp++ = ' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
actr++;
|
||||
}
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
void __init prom_init_cmdline(void)
|
||||
{
|
||||
char *cp;
|
||||
int actr, i;
|
||||
|
||||
actr = 1; /* Always ignore argv[0] */
|
||||
|
||||
cp = arcs_cmdline;
|
||||
/*
|
||||
* Move ARC variables to the beginning to make sure they can be
|
||||
* overridden by later arguments.
|
||||
*/
|
||||
cp = move_firmware_args(cp);
|
||||
|
||||
while (actr < prom_argc) {
|
||||
for (i = 0; i < ARRAY_SIZE(ignored); i++) {
|
||||
int len = strlen(ignored[i]);
|
||||
|
||||
if (!strncmp(prom_argv(actr), ignored[i], len))
|
||||
goto pic_cont;
|
||||
}
|
||||
/* Ok, we want it. */
|
||||
strcpy(cp, prom_argv(actr));
|
||||
cp += strlen(prom_argv(actr));
|
||||
*cp++ = ' ';
|
||||
|
||||
pic_cont:
|
||||
actr++;
|
||||
}
|
||||
|
||||
if (cp != arcs_cmdline) /* get rid of trailing space */
|
||||
--cp;
|
||||
*cp = '\0';
|
||||
|
||||
#ifdef DEBUG_CMDLINE
|
||||
printk(KERN_DEBUG "prom cmdline: %s\n", arcs_cmdline);
|
||||
#endif
|
||||
}
|
27
arch/mips/fw/arc/env.c
Normal file
27
arch/mips/fw/arc/env.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* env.c: ARCS environment variable routines.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/fw/arc/types.h>
|
||||
#include <asm/sgialib.h>
|
||||
|
||||
PCHAR __init
|
||||
ArcGetEnvironmentVariable(CHAR *name)
|
||||
{
|
||||
return (CHAR *) ARC_CALL1(get_evar, name);
|
||||
}
|
||||
|
||||
LONG __init
|
||||
ArcSetEnvironmentVariable(PCHAR name, PCHAR value)
|
||||
{
|
||||
return ARC_CALL2(set_evar, name, value);
|
||||
}
|
74
arch/mips/fw/arc/file.c
Normal file
74
arch/mips/fw/arc/file.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* ARC firmware interface.
|
||||
*
|
||||
* Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle
|
||||
* Copyright (C) 1999 Silicon Graphics, Inc.
|
||||
*/
|
||||
|
||||
#include <asm/fw/arc/types.h>
|
||||
#include <asm/sgialib.h>
|
||||
|
||||
LONG
|
||||
ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer,
|
||||
ULONG N, ULONG *Count)
|
||||
{
|
||||
return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count);
|
||||
}
|
||||
|
||||
LONG
|
||||
ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID)
|
||||
{
|
||||
return ARC_CALL3(open, Path, OpenMode, FileID);
|
||||
}
|
||||
|
||||
LONG
|
||||
ArcClose(ULONG FileID)
|
||||
{
|
||||
return ARC_CALL1(close, FileID);
|
||||
}
|
||||
|
||||
LONG
|
||||
ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count)
|
||||
{
|
||||
return ARC_CALL4(read, FileID, Buffer, N, Count);
|
||||
}
|
||||
|
||||
LONG
|
||||
ArcGetReadStatus(ULONG FileID)
|
||||
{
|
||||
return ARC_CALL1(get_rstatus, FileID);
|
||||
}
|
||||
|
||||
LONG
|
||||
ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count)
|
||||
{
|
||||
return ARC_CALL4(write, FileID, Buffer, N, Count);
|
||||
}
|
||||
|
||||
LONG
|
||||
ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode)
|
||||
{
|
||||
return ARC_CALL3(seek, FileID, Position, SeekMode);
|
||||
}
|
||||
|
||||
LONG
|
||||
ArcMount(char *name, enum linux_mountops op)
|
||||
{
|
||||
return ARC_CALL2(mount, name, op);
|
||||
}
|
||||
|
||||
LONG
|
||||
ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information)
|
||||
{
|
||||
return ARC_CALL2(get_finfo, FileID, Information);
|
||||
}
|
||||
|
||||
LONG ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags,
|
||||
ULONG AttributeMask)
|
||||
{
|
||||
return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask);
|
||||
}
|
116
arch/mips/fw/arc/identify.c
Normal file
116
arch/mips/fw/arc/identify.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* identify.c: identify machine by looking up system identifier
|
||||
*
|
||||
* Copyright (C) 1998 Thomas Bogendoerfer
|
||||
*
|
||||
* This code is based on arch/mips/sgi/kernel/system.c, which is
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
#include <linux/bug.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/sgialib.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
||||
struct smatch {
|
||||
char *arcname;
|
||||
char *liname;
|
||||
int flags;
|
||||
};
|
||||
|
||||
static struct smatch mach_table[] = {
|
||||
{
|
||||
.arcname = "SGI-IP22",
|
||||
.liname = "SGI Indy",
|
||||
.flags = PROM_FLAG_ARCS,
|
||||
}, {
|
||||
.arcname = "SGI-IP27",
|
||||
.liname = "SGI Origin",
|
||||
.flags = PROM_FLAG_ARCS,
|
||||
}, {
|
||||
.arcname = "SGI-IP28",
|
||||
.liname = "SGI IP28",
|
||||
.flags = PROM_FLAG_ARCS,
|
||||
}, {
|
||||
.arcname = "SGI-IP30",
|
||||
.liname = "SGI Octane",
|
||||
.flags = PROM_FLAG_ARCS,
|
||||
}, {
|
||||
.arcname = "SGI-IP32",
|
||||
.liname = "SGI O2",
|
||||
.flags = PROM_FLAG_ARCS,
|
||||
}, {
|
||||
.arcname = "Microsoft-Jazz",
|
||||
.liname = "Jazz MIPS_Magnum_4000",
|
||||
.flags = 0,
|
||||
}, {
|
||||
.arcname = "PICA-61",
|
||||
.liname = "Jazz Acer_PICA_61",
|
||||
.flags = 0,
|
||||
}, {
|
||||
.arcname = "RM200PCI",
|
||||
.liname = "SNI RM200_PCI",
|
||||
.flags = PROM_FLAG_DONT_FREE_TEMP,
|
||||
}, {
|
||||
.arcname = "RM200PCI-R5K",
|
||||
.liname = "SNI RM200_PCI-R5K",
|
||||
.flags = PROM_FLAG_DONT_FREE_TEMP,
|
||||
}
|
||||
};
|
||||
|
||||
int prom_flags;
|
||||
|
||||
static struct smatch * __init string_to_mach(const char *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mach_table); i++) {
|
||||
if (!strcmp(s, mach_table[i].arcname))
|
||||
return &mach_table[i];
|
||||
}
|
||||
|
||||
panic("Yeee, could not determine architecture type <%s>", s);
|
||||
}
|
||||
|
||||
char *system_type;
|
||||
|
||||
const char *get_system_type(void)
|
||||
{
|
||||
return system_type;
|
||||
}
|
||||
|
||||
void __init prom_identify_arch(void)
|
||||
{
|
||||
pcomponent *p;
|
||||
struct smatch *mach;
|
||||
const char *iname;
|
||||
|
||||
/*
|
||||
* The root component tells us what machine architecture we have here.
|
||||
*/
|
||||
p = ArcGetChild(PROM_NULL_COMPONENT);
|
||||
if (p == NULL) {
|
||||
#ifdef CONFIG_SGI_IP27
|
||||
/* IP27 PROM misbehaves, seems to not implement ARC
|
||||
GetChild(). So we just assume it's an IP27. */
|
||||
iname = "SGI-IP27";
|
||||
#else
|
||||
iname = "Unknown";
|
||||
#endif
|
||||
} else
|
||||
iname = (char *) (long) p->iname;
|
||||
|
||||
printk("ARCH: %s\n", iname);
|
||||
mach = string_to_mach(iname);
|
||||
system_type = mach->liname;
|
||||
|
||||
prom_flags = mach->flags;
|
||||
}
|
59
arch/mips/fw/arc/init.c
Normal file
59
arch/mips/fw/arc/init.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* PROM library initialisation code.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/sgialib.h>
|
||||
#include <asm/smp-ops.h>
|
||||
|
||||
#undef DEBUG_PROM_INIT
|
||||
|
||||
/* Master romvec interface. */
|
||||
struct linux_romvec *romvec;
|
||||
int prom_argc;
|
||||
LONG *_prom_argv, *_prom_envp;
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
|
||||
|
||||
romvec = ROMVECTOR;
|
||||
|
||||
prom_argc = fw_arg0;
|
||||
_prom_argv = (LONG *) fw_arg1;
|
||||
_prom_envp = (LONG *) fw_arg2;
|
||||
|
||||
if (pb->magic != 0x53435241) {
|
||||
printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n",
|
||||
(unsigned long) pb->magic);
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
|
||||
prom_init_cmdline();
|
||||
prom_identify_arch();
|
||||
printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n",
|
||||
pb->ver, pb->rev);
|
||||
prom_meminit();
|
||||
|
||||
#ifdef DEBUG_PROM_INIT
|
||||
pr_info("Press a key to reboot\n");
|
||||
ArcRead(0, &c, 1, &cnt);
|
||||
ArcEnterInteractiveMode();
|
||||
#endif
|
||||
#ifdef CONFIG_SGI_IP27
|
||||
{
|
||||
extern struct plat_smp_ops ip27_smp_ops;
|
||||
|
||||
register_smp_ops(&ip27_smp_ops);
|
||||
}
|
||||
#endif
|
||||
}
|
160
arch/mips/fw/arc/memory.c
Normal file
160
arch/mips/fw/arc/memory.c
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* memory.c: PROM library functions for acquiring/using memory descriptors
|
||||
* given to us from the ARCS firmware.
|
||||
*
|
||||
* Copyright (C) 1996 by David S. Miller
|
||||
* Copyright (C) 1999, 2000, 2001 by Ralf Baechle
|
||||
* Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
|
||||
*
|
||||
* PROM library functions for acquiring/using memory descriptors given to us
|
||||
* from the ARCS firmware. This is only used when CONFIG_ARC_MEMORY is set
|
||||
* because on some machines like SGI IP27 the ARC memory configuration data
|
||||
* completly bogus and alternate easier to use mechanisms are available.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/swap.h>
|
||||
|
||||
#include <asm/sgialib.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
/*
|
||||
* For ARC firmware memory functions the unit of meassuring memory is always
|
||||
* a 4k page of memory
|
||||
*/
|
||||
#define ARC_PAGE_SHIFT 12
|
||||
|
||||
struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
|
||||
{
|
||||
return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
|
||||
}
|
||||
|
||||
#ifdef DEBUG /* convenient for debugging */
|
||||
static char *arcs_mtypes[8] = {
|
||||
"Exception Block",
|
||||
"ARCS Romvec Page",
|
||||
"Free/Contig RAM",
|
||||
"Generic Free RAM",
|
||||
"Bad Memory",
|
||||
"Standalone Program Pages",
|
||||
"ARCS Temp Storage Area",
|
||||
"ARCS Permanent Storage Area"
|
||||
};
|
||||
|
||||
static char *arc_mtypes[8] = {
|
||||
"Exception Block",
|
||||
"SystemParameterBlock",
|
||||
"FreeMemory",
|
||||
"Bad Memory",
|
||||
"LoadedProgram",
|
||||
"FirmwareTemporary",
|
||||
"FirmwarePermanent",
|
||||
"FreeContiguous"
|
||||
};
|
||||
#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
|
||||
: arc_mtypes[a.arc]
|
||||
#endif
|
||||
|
||||
static inline int memtype_classify_arcs(union linux_memtypes type)
|
||||
{
|
||||
switch (type.arcs) {
|
||||
case arcs_fcontig:
|
||||
case arcs_free:
|
||||
return BOOT_MEM_RAM;
|
||||
case arcs_atmp:
|
||||
return BOOT_MEM_ROM_DATA;
|
||||
case arcs_eblock:
|
||||
case arcs_rvpage:
|
||||
case arcs_bmem:
|
||||
case arcs_prog:
|
||||
case arcs_aperm:
|
||||
return BOOT_MEM_RESERVED;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
while(1); /* Nuke warning. */
|
||||
}
|
||||
|
||||
static inline int memtype_classify_arc(union linux_memtypes type)
|
||||
{
|
||||
switch (type.arc) {
|
||||
case arc_free:
|
||||
case arc_fcontig:
|
||||
return BOOT_MEM_RAM;
|
||||
case arc_atmp:
|
||||
return BOOT_MEM_ROM_DATA;
|
||||
case arc_eblock:
|
||||
case arc_rvpage:
|
||||
case arc_bmem:
|
||||
case arc_prog:
|
||||
case arc_aperm:
|
||||
return BOOT_MEM_RESERVED;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
while(1); /* Nuke warning. */
|
||||
}
|
||||
|
||||
static int __init prom_memtype_classify(union linux_memtypes type)
|
||||
{
|
||||
if (prom_flags & PROM_FLAG_ARCS) /* SGI is ``different'' ... */
|
||||
return memtype_classify_arcs(type);
|
||||
|
||||
return memtype_classify_arc(type);
|
||||
}
|
||||
|
||||
void __init prom_meminit(void)
|
||||
{
|
||||
struct linux_mdesc *p;
|
||||
|
||||
#ifdef DEBUG
|
||||
int i = 0;
|
||||
|
||||
printk("ARCS MEMORY DESCRIPTOR dump:\n");
|
||||
p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
|
||||
while(p) {
|
||||
printk("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
|
||||
i, p, p->base, p->pages, mtypes(p->type));
|
||||
p = ArcGetMemoryDescriptor(p);
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
|
||||
p = PROM_NULL_MDESC;
|
||||
while ((p = ArcGetMemoryDescriptor(p))) {
|
||||
unsigned long base, size;
|
||||
long type;
|
||||
|
||||
base = p->base << ARC_PAGE_SHIFT;
|
||||
size = p->pages << ARC_PAGE_SHIFT;
|
||||
type = prom_memtype_classify(p->type);
|
||||
|
||||
add_memory_region(base, size, type);
|
||||
}
|
||||
}
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
{
|
||||
unsigned long addr;
|
||||
int i;
|
||||
|
||||
if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
|
||||
return;
|
||||
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
|
||||
continue;
|
||||
|
||||
addr = boot_mem_map.map[i].addr;
|
||||
free_init_pages("prom memory",
|
||||
addr, addr + boot_mem_map.map[i].size);
|
||||
}
|
||||
}
|
89
arch/mips/fw/arc/misc.c
Normal file
89
arch/mips/fw/arc/misc.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Miscellaneous ARCS PROM routines.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
|
||||
* Copyright (C) 1999 Silicon Graphics, Inc.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
#include <asm/bcache.h>
|
||||
|
||||
#include <asm/fw/arc/types.h>
|
||||
#include <asm/sgialib.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
||||
VOID
|
||||
ArcHalt(VOID)
|
||||
{
|
||||
bc_disable();
|
||||
local_irq_disable();
|
||||
ARC_CALL0(halt);
|
||||
never: goto never;
|
||||
}
|
||||
|
||||
VOID
|
||||
ArcPowerDown(VOID)
|
||||
{
|
||||
bc_disable();
|
||||
local_irq_disable();
|
||||
ARC_CALL0(pdown);
|
||||
never: goto never;
|
||||
}
|
||||
|
||||
/* XXX is this a soft reset basically? XXX */
|
||||
VOID
|
||||
ArcRestart(VOID)
|
||||
{
|
||||
bc_disable();
|
||||
local_irq_disable();
|
||||
ARC_CALL0(restart);
|
||||
never: goto never;
|
||||
}
|
||||
|
||||
VOID
|
||||
ArcReboot(VOID)
|
||||
{
|
||||
bc_disable();
|
||||
local_irq_disable();
|
||||
ARC_CALL0(reboot);
|
||||
never: goto never;
|
||||
}
|
||||
|
||||
VOID
|
||||
ArcEnterInteractiveMode(VOID)
|
||||
{
|
||||
bc_disable();
|
||||
local_irq_disable();
|
||||
ARC_CALL0(imode);
|
||||
never: goto never;
|
||||
}
|
||||
|
||||
LONG
|
||||
ArcSaveConfiguration(VOID)
|
||||
{
|
||||
return ARC_CALL0(cfg_save);
|
||||
}
|
||||
|
||||
struct linux_sysid *
|
||||
ArcGetSystemId(VOID)
|
||||
{
|
||||
return (struct linux_sysid *) ARC_CALL0(get_sysid);
|
||||
}
|
||||
|
||||
VOID __init
|
||||
ArcFlushAllCaches(VOID)
|
||||
{
|
||||
ARC_CALL0(cache_flush);
|
||||
}
|
||||
|
||||
DISPLAY_STATUS * __init ArcGetDisplayStatus(ULONG FileID)
|
||||
{
|
||||
return (DISPLAY_STATUS *) ARC_CALL1(GetDisplayStatus, FileID);
|
||||
}
|
43
arch/mips/fw/arc/promlib.c
Normal file
43
arch/mips/fw/arc/promlib.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (dm@sgi.com)
|
||||
* Compatibility with board caches, Ulf Carlsson
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/sgialib.h>
|
||||
#include <asm/bcache.h>
|
||||
|
||||
/*
|
||||
* IP22 boardcache is not compatible with board caches. Thus we disable it
|
||||
* during romvec action. Since r4xx0.c is always compiled and linked with your
|
||||
* kernel, this shouldn't cause any harm regardless what MIPS processor you
|
||||
* have.
|
||||
*
|
||||
* The ARC write and read functions seem to interfere with the serial lines
|
||||
* in some way. You should be careful with them.
|
||||
*/
|
||||
|
||||
void prom_putchar(char c)
|
||||
{
|
||||
ULONG cnt;
|
||||
CHAR it = c;
|
||||
|
||||
bc_disable();
|
||||
ArcWrite(1, &it, 1, &cnt);
|
||||
bc_enable();
|
||||
}
|
||||
|
||||
char prom_getchar(void)
|
||||
{
|
||||
ULONG cnt;
|
||||
CHAR c;
|
||||
|
||||
bc_disable();
|
||||
ArcRead(0, &c, 1, &cnt);
|
||||
bc_enable();
|
||||
|
||||
return c;
|
||||
}
|
24
arch/mips/fw/arc/salone.c
Normal file
24
arch/mips/fw/arc/salone.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Routines to load into memory and execute stand-along program images using
|
||||
* ARCS PROM firmware.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <asm/sgialib.h>
|
||||
|
||||
LONG __init ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr)
|
||||
{
|
||||
return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr);
|
||||
}
|
||||
|
||||
LONG __init ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[],
|
||||
CHAR *Envp[])
|
||||
{
|
||||
return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp);
|
||||
}
|
||||
|
||||
LONG __init ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[])
|
||||
{
|
||||
return ARC_CALL4(exec, Path, Argc, Argv, Envp);
|
||||
}
|
25
arch/mips/fw/arc/time.c
Normal file
25
arch/mips/fw/arc/time.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Extracting time information from ARCS prom.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/fw/arc/types.h>
|
||||
#include <asm/sgialib.h>
|
||||
|
||||
struct linux_tinfo * __init
|
||||
ArcGetTime(VOID)
|
||||
{
|
||||
return (struct linux_tinfo *) ARC_CALL0(get_tinfo);
|
||||
}
|
||||
|
||||
ULONG __init
|
||||
ArcGetRelativeTime(VOID)
|
||||
{
|
||||
return ARC_CALL0(get_rtime);
|
||||
}
|
127
arch/mips/fw/arc/tree.c
Normal file
127
arch/mips/fw/arc/tree.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* PROM component device tree code.
|
||||
*
|
||||
* Copyright (C) 1996 David S. Miller (davem@davemloft.net)
|
||||
* Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
|
||||
* Copyright (C) 1999 Silicon Graphics, Inc.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <asm/fw/arc/types.h>
|
||||
#include <asm/sgialib.h>
|
||||
|
||||
#undef DEBUG_PROM_TREE
|
||||
|
||||
pcomponent * __init
|
||||
ArcGetPeer(pcomponent *Current)
|
||||
{
|
||||
if (Current == PROM_NULL_COMPONENT)
|
||||
return PROM_NULL_COMPONENT;
|
||||
|
||||
return (pcomponent *) ARC_CALL1(next_component, Current);
|
||||
}
|
||||
|
||||
pcomponent * __init
|
||||
ArcGetChild(pcomponent *Current)
|
||||
{
|
||||
return (pcomponent *) ARC_CALL1(child_component, Current);
|
||||
}
|
||||
|
||||
pcomponent * __init
|
||||
ArcGetParent(pcomponent *Current)
|
||||
{
|
||||
if (Current == PROM_NULL_COMPONENT)
|
||||
return PROM_NULL_COMPONENT;
|
||||
|
||||
return (pcomponent *) ARC_CALL1(parent_component, Current);
|
||||
}
|
||||
|
||||
LONG __init
|
||||
ArcGetConfigurationData(VOID *Buffer, pcomponent *Current)
|
||||
{
|
||||
return ARC_CALL2(component_data, Buffer, Current);
|
||||
}
|
||||
|
||||
pcomponent * __init
|
||||
ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData)
|
||||
{
|
||||
return (pcomponent *)
|
||||
ARC_CALL3(child_add, Current, Template, ConfigurationData);
|
||||
}
|
||||
|
||||
LONG __init
|
||||
ArcDeleteComponent(pcomponent *ComponentToDelete)
|
||||
{
|
||||
return ARC_CALL1(comp_del, ComponentToDelete);
|
||||
}
|
||||
|
||||
pcomponent * __init
|
||||
ArcGetComponent(CHAR *Path)
|
||||
{
|
||||
return (pcomponent *)ARC_CALL1(component_by_path, Path);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PROM_TREE
|
||||
|
||||
static char *classes[] = {
|
||||
"system", "processor", "cache", "adapter", "controller", "peripheral",
|
||||
"memory"
|
||||
};
|
||||
|
||||
static char *types[] = {
|
||||
"arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache",
|
||||
"sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter",
|
||||
"dti adapter", "multi-func adapter", "disk controller",
|
||||
"tp controller", "cdrom controller", "worm controller",
|
||||
"serial controller", "net controller", "display controller",
|
||||
"parallel controller", "pointer controller", "keyboard controller",
|
||||
"audio controller", "misc controller", "disk peripheral",
|
||||
"floppy peripheral", "tp peripheral", "modem peripheral",
|
||||
"monitor peripheral", "printer peripheral", "pointer peripheral",
|
||||
"keyboard peripheral", "terminal peripheral", "line peripheral",
|
||||
"net peripheral", "misc peripheral", "anonymous"
|
||||
};
|
||||
|
||||
static char *iflags[] = {
|
||||
"bogus", "read only", "removable", "console in", "console out",
|
||||
"input", "output"
|
||||
};
|
||||
|
||||
static void __init
|
||||
dump_component(pcomponent *p)
|
||||
{
|
||||
printk("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>",
|
||||
p, classes[p->class], types[p->type],
|
||||
iflags[p->iflags], p->vers, p->rev);
|
||||
printk("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n",
|
||||
p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
|
||||
}
|
||||
|
||||
static void __init
|
||||
traverse(pcomponent *p, int op)
|
||||
{
|
||||
dump_component(p);
|
||||
if(ArcGetChild(p))
|
||||
traverse(ArcGetChild(p), 1);
|
||||
if(ArcGetPeer(p) && op)
|
||||
traverse(ArcGetPeer(p), 1);
|
||||
}
|
||||
|
||||
void __init
|
||||
prom_testtree(void)
|
||||
{
|
||||
pcomponent *p;
|
||||
|
||||
p = ArcGetChild(PROM_NULL_COMPONENT);
|
||||
dump_component(p);
|
||||
p = ArcGetChild(p);
|
||||
while(p) {
|
||||
dump_component(p);
|
||||
p = ArcGetPeer(p);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DEBUG_PROM_TREE */
|
5
arch/mips/fw/cfe/Makefile
Normal file
5
arch/mips/fw/cfe/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# Makefile for the Broadcom Common Firmware Environment support
|
||||
#
|
||||
|
||||
lib-y += cfe_api.o
|
432
arch/mips/fw/cfe/cfe_api.c
Normal file
432
arch/mips/fw/cfe/cfe_api.c
Normal file
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* Copyright (C) 2000, 2001, 2002 Broadcom Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Broadcom Common Firmware Environment (CFE)
|
||||
*
|
||||
* This module contains device function stubs (small routines to
|
||||
* call the standard "iocb" interface entry point to CFE).
|
||||
* There should be one routine here per iocb function call.
|
||||
*
|
||||
* Authors: Mitch Lichtenberg, Chris Demetriou
|
||||
*/
|
||||
|
||||
#include <asm/fw/cfe/cfe_api.h>
|
||||
#include "cfe_api_int.h"
|
||||
|
||||
/* Cast from a native pointer to a cfe_xptr_t and back. */
|
||||
#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n))
|
||||
#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x))
|
||||
|
||||
int cfe_iocb_dispatch(struct cfe_xiocb *xiocb);
|
||||
|
||||
/*
|
||||
* Declare the dispatch function with args of "intptr_t".
|
||||
* This makes sure whatever model we're compiling in
|
||||
* puts the pointers in a single register. For example,
|
||||
* combining -mlong64 and -mips1 or -mips2 would lead to
|
||||
* trouble, since the handle and IOCB pointer will be
|
||||
* passed in two registers each, and CFE expects one.
|
||||
*/
|
||||
|
||||
static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb);
|
||||
static u64 cfe_handle;
|
||||
|
||||
int cfe_init(u64 handle, u64 ept)
|
||||
{
|
||||
cfe_dispfunc = NATIVE_FROM_XPTR(ept);
|
||||
cfe_handle = handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cfe_iocb_dispatch(struct cfe_xiocb * xiocb)
|
||||
{
|
||||
if (!cfe_dispfunc)
|
||||
return -1;
|
||||
return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb);
|
||||
}
|
||||
|
||||
int cfe_close(int handle)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = handle;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = 0;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
return xiocb.xiocb_status;
|
||||
|
||||
}
|
||||
|
||||
int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
|
||||
xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
|
||||
xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
|
||||
xiocb.plist.xiocb_cpuctl.gp_val = gp;
|
||||
xiocb.plist.xiocb_cpuctl.sp_val = sp;
|
||||
xiocb.plist.xiocb_cpuctl.a1_val = a1;
|
||||
xiocb.plist.xiocb_cpuctl.start_addr = (long) fn;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
return xiocb.xiocb_status;
|
||||
}
|
||||
|
||||
int cfe_cpu_stop(int cpu)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
|
||||
xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
|
||||
xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
return xiocb.xiocb_status;
|
||||
}
|
||||
|
||||
int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
|
||||
xiocb.plist.xiocb_envbuf.enum_idx = idx;
|
||||
xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
|
||||
xiocb.plist.xiocb_envbuf.name_length = namelen;
|
||||
xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
|
||||
xiocb.plist.xiocb_envbuf.val_length = vallen;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
return xiocb.xiocb_status;
|
||||
}
|
||||
|
||||
int
|
||||
cfe_enummem(int idx, int flags, u64 *start, u64 *length, u64 *type)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = flags;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_meminfo);
|
||||
xiocb.plist.xiocb_meminfo.mi_idx = idx;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
if (xiocb.xiocb_status < 0)
|
||||
return xiocb.xiocb_status;
|
||||
|
||||
*start = xiocb.plist.xiocb_meminfo.mi_addr;
|
||||
*length = xiocb.plist.xiocb_meminfo.mi_size;
|
||||
*type = xiocb.plist.xiocb_meminfo.mi_type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cfe_exit(int warm, int status)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_exitstat);
|
||||
xiocb.plist.xiocb_exitstat.status = status;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
return xiocb.xiocb_status;
|
||||
}
|
||||
|
||||
int cfe_flushcache(int flg)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = flg;
|
||||
xiocb.xiocb_psize = 0;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
return xiocb.xiocb_status;
|
||||
}
|
||||
|
||||
int cfe_getdevinfo(char *name)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
|
||||
xiocb.plist.xiocb_buffer.buf_offset = 0;
|
||||
xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
|
||||
xiocb.plist.xiocb_buffer.buf_length = strlen(name);
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
if (xiocb.xiocb_status < 0)
|
||||
return xiocb.xiocb_status;
|
||||
return xiocb.plist.xiocb_buffer.buf_ioctlcmd;
|
||||
}
|
||||
|
||||
int cfe_getenv(char *name, char *dest, int destlen)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
*dest = 0;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_ENV_GET;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
|
||||
xiocb.plist.xiocb_envbuf.enum_idx = 0;
|
||||
xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
|
||||
xiocb.plist.xiocb_envbuf.name_length = strlen(name);
|
||||
xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest);
|
||||
xiocb.plist.xiocb_envbuf.val_length = destlen;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
return xiocb.xiocb_status;
|
||||
}
|
||||
|
||||
int cfe_getfwinfo(cfe_fwinfo_t * info)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_fwinfo);
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
if (xiocb.xiocb_status < 0)
|
||||
return xiocb.xiocb_status;
|
||||
|
||||
info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version;
|
||||
info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem;
|
||||
info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags;
|
||||
info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid;
|
||||
info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va;
|
||||
info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa;
|
||||
info->fwi_bootarea_size =
|
||||
xiocb.plist.xiocb_fwinfo.fwi_bootarea_size;
|
||||
#if 0
|
||||
info->fwi_reserved1 = xiocb.plist.xiocb_fwinfo.fwi_reserved1;
|
||||
info->fwi_reserved2 = xiocb.plist.xiocb_fwinfo.fwi_reserved2;
|
||||
info->fwi_reserved3 = xiocb.plist.xiocb_fwinfo.fwi_reserved3;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cfe_getstdhandle(int flg)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = flg;
|
||||
xiocb.xiocb_psize = 0;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
if (xiocb.xiocb_status < 0)
|
||||
return xiocb.xiocb_status;
|
||||
return xiocb.xiocb_handle;
|
||||
}
|
||||
|
||||
int64_t
|
||||
cfe_getticks(void)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_time);
|
||||
xiocb.plist.xiocb_time.ticks = 0;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
return xiocb.plist.xiocb_time.ticks;
|
||||
|
||||
}
|
||||
|
||||
int cfe_inpstat(int handle)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = handle;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_inpstat);
|
||||
xiocb.plist.xiocb_inpstat.inp_status = 0;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
if (xiocb.xiocb_status < 0)
|
||||
return xiocb.xiocb_status;
|
||||
return xiocb.plist.xiocb_inpstat.inp_status;
|
||||
}
|
||||
|
||||
int
|
||||
cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
|
||||
int length, int *retlen, u64 offset)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = handle;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
|
||||
xiocb.plist.xiocb_buffer.buf_offset = offset;
|
||||
xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum;
|
||||
xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
|
||||
xiocb.plist.xiocb_buffer.buf_length = length;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
if (retlen)
|
||||
*retlen = xiocb.plist.xiocb_buffer.buf_retlen;
|
||||
return xiocb.xiocb_status;
|
||||
}
|
||||
|
||||
int cfe_open(char *name)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
|
||||
xiocb.plist.xiocb_buffer.buf_offset = 0;
|
||||
xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
|
||||
xiocb.plist.xiocb_buffer.buf_length = strlen(name);
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
if (xiocb.xiocb_status < 0)
|
||||
return xiocb.xiocb_status;
|
||||
return xiocb.xiocb_handle;
|
||||
}
|
||||
|
||||
int cfe_read(int handle, unsigned char *buffer, int length)
|
||||
{
|
||||
return cfe_readblk(handle, 0, buffer, length);
|
||||
}
|
||||
|
||||
int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = handle;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
|
||||
xiocb.plist.xiocb_buffer.buf_offset = offset;
|
||||
xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
|
||||
xiocb.plist.xiocb_buffer.buf_length = length;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
if (xiocb.xiocb_status < 0)
|
||||
return xiocb.xiocb_status;
|
||||
return xiocb.plist.xiocb_buffer.buf_retlen;
|
||||
}
|
||||
|
||||
int cfe_setenv(char *name, char *val)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = 0;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
|
||||
xiocb.plist.xiocb_envbuf.enum_idx = 0;
|
||||
xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
|
||||
xiocb.plist.xiocb_envbuf.name_length = strlen(name);
|
||||
xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
|
||||
xiocb.plist.xiocb_envbuf.val_length = strlen(val);
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
return xiocb.xiocb_status;
|
||||
}
|
||||
|
||||
int cfe_write(int handle, const char *buffer, int length)
|
||||
{
|
||||
return cfe_writeblk(handle, 0, buffer, length);
|
||||
}
|
||||
|
||||
int cfe_writeblk(int handle, s64 offset, const char *buffer, int length)
|
||||
{
|
||||
struct cfe_xiocb xiocb;
|
||||
|
||||
xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
|
||||
xiocb.xiocb_status = 0;
|
||||
xiocb.xiocb_handle = handle;
|
||||
xiocb.xiocb_flags = 0;
|
||||
xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
|
||||
xiocb.plist.xiocb_buffer.buf_offset = offset;
|
||||
xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
|
||||
xiocb.plist.xiocb_buffer.buf_length = length;
|
||||
|
||||
cfe_iocb_dispatch(&xiocb);
|
||||
|
||||
if (xiocb.xiocb_status < 0)
|
||||
return xiocb.xiocb_status;
|
||||
return xiocb.plist.xiocb_buffer.buf_retlen;
|
||||
}
|
148
arch/mips/fw/cfe/cfe_api_int.h
Normal file
148
arch/mips/fw/cfe/cfe_api_int.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (C) 2000, 2001, 2002 Broadcom Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef CFE_API_INT_H
|
||||
#define CFE_API_INT_H
|
||||
|
||||
/*
|
||||
* Constants.
|
||||
*/
|
||||
#define CFE_CMD_FW_GETINFO 0
|
||||
#define CFE_CMD_FW_RESTART 1
|
||||
#define CFE_CMD_FW_BOOT 2
|
||||
#define CFE_CMD_FW_CPUCTL 3
|
||||
#define CFE_CMD_FW_GETTIME 4
|
||||
#define CFE_CMD_FW_MEMENUM 5
|
||||
#define CFE_CMD_FW_FLUSHCACHE 6
|
||||
|
||||
#define CFE_CMD_DEV_GETHANDLE 9
|
||||
#define CFE_CMD_DEV_ENUM 10
|
||||
#define CFE_CMD_DEV_OPEN 11
|
||||
#define CFE_CMD_DEV_INPSTAT 12
|
||||
#define CFE_CMD_DEV_READ 13
|
||||
#define CFE_CMD_DEV_WRITE 14
|
||||
#define CFE_CMD_DEV_IOCTL 15
|
||||
#define CFE_CMD_DEV_CLOSE 16
|
||||
#define CFE_CMD_DEV_GETINFO 17
|
||||
|
||||
#define CFE_CMD_ENV_ENUM 20
|
||||
#define CFE_CMD_ENV_GET 22
|
||||
#define CFE_CMD_ENV_SET 23
|
||||
#define CFE_CMD_ENV_DEL 24
|
||||
|
||||
#define CFE_CMD_MAX 32
|
||||
|
||||
#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */
|
||||
|
||||
/*
|
||||
* Structures.
|
||||
*/
|
||||
|
||||
/* eeek, signed "pointers" */
|
||||
typedef s64 cfe_xptr_t;
|
||||
|
||||
struct xiocb_buffer {
|
||||
u64 buf_offset; /* offset on device (bytes) */
|
||||
cfe_xptr_t buf_ptr; /* pointer to a buffer */
|
||||
u64 buf_length; /* length of this buffer */
|
||||
u64 buf_retlen; /* returned length (for read ops) */
|
||||
u64 buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */
|
||||
};
|
||||
|
||||
struct xiocb_inpstat {
|
||||
u64 inp_status; /* 1 means input available */
|
||||
};
|
||||
|
||||
struct xiocb_envbuf {
|
||||
s64 enum_idx; /* 0-based enumeration index */
|
||||
cfe_xptr_t name_ptr; /* name string buffer */
|
||||
s64 name_length; /* size of name buffer */
|
||||
cfe_xptr_t val_ptr; /* value string buffer */
|
||||
s64 val_length; /* size of value string buffer */
|
||||
};
|
||||
|
||||
struct xiocb_cpuctl {
|
||||
u64 cpu_number; /* cpu number to control */
|
||||
u64 cpu_command; /* command to issue to CPU */
|
||||
u64 start_addr; /* CPU start address */
|
||||
u64 gp_val; /* starting GP value */
|
||||
u64 sp_val; /* starting SP value */
|
||||
u64 a1_val; /* starting A1 value */
|
||||
};
|
||||
|
||||
struct xiocb_time {
|
||||
s64 ticks; /* current time in ticks */
|
||||
};
|
||||
|
||||
struct xiocb_exitstat{
|
||||
s64 status;
|
||||
};
|
||||
|
||||
struct xiocb_meminfo {
|
||||
s64 mi_idx; /* 0-based enumeration index */
|
||||
s64 mi_type; /* type of memory block */
|
||||
u64 mi_addr; /* physical start address */
|
||||
u64 mi_size; /* block size */
|
||||
};
|
||||
|
||||
struct xiocb_fwinfo {
|
||||
s64 fwi_version; /* major, minor, eco version */
|
||||
s64 fwi_totalmem; /* total installed mem */
|
||||
s64 fwi_flags; /* various flags */
|
||||
s64 fwi_boardid; /* board ID */
|
||||
s64 fwi_bootarea_va; /* VA of boot area */
|
||||
s64 fwi_bootarea_pa; /* PA of boot area */
|
||||
s64 fwi_bootarea_size; /* size of boot area */
|
||||
s64 fwi_reserved1;
|
||||
s64 fwi_reserved2;
|
||||
s64 fwi_reserved3;
|
||||
};
|
||||
|
||||
struct cfe_xiocb {
|
||||
u64 xiocb_fcode; /* IOCB function code */
|
||||
s64 xiocb_status; /* return status */
|
||||
s64 xiocb_handle; /* file/device handle */
|
||||
u64 xiocb_flags; /* flags for this IOCB */
|
||||
u64 xiocb_psize; /* size of parameter list */
|
||||
union {
|
||||
/* buffer parameters */
|
||||
struct xiocb_buffer xiocb_buffer;
|
||||
|
||||
/* input status parameters */
|
||||
struct xiocb_inpstat xiocb_inpstat;
|
||||
|
||||
/* environment function parameters */
|
||||
struct xiocb_envbuf xiocb_envbuf;
|
||||
|
||||
/* CPU control parameters */
|
||||
struct xiocb_cpuctl xiocb_cpuctl;
|
||||
|
||||
/* timer parameters */
|
||||
struct xiocb_time xiocb_time;
|
||||
|
||||
/* memory arena info parameters */
|
||||
struct xiocb_meminfo xiocb_meminfo;
|
||||
|
||||
/* firmware information */
|
||||
struct xiocb_fwinfo xiocb_fwinfo;
|
||||
|
||||
/* Exit Status */
|
||||
struct xiocb_exitstat xiocb_exitstat;
|
||||
} plist;
|
||||
};
|
||||
|
||||
#endif /* CFE_API_INT_H */
|
7
arch/mips/fw/lib/Makefile
Normal file
7
arch/mips/fw/lib/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Makefile for generic prom monitor library routines under Linux.
|
||||
#
|
||||
|
||||
lib-y += cmdline.o
|
||||
|
||||
lib-$(CONFIG_64BIT) += call_o32.o
|
108
arch/mips/fw/lib/call_o32.S
Normal file
108
arch/mips/fw/lib/call_o32.S
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* O32 interface for the 64 (or N32) ABI.
|
||||
*
|
||||
* Copyright (C) 2002, 2014 Maciej W. Rozycki
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
|
||||
/* O32 register size. */
|
||||
#define O32_SZREG 4
|
||||
/* Maximum number of arguments supported. Must be even! */
|
||||
#define O32_ARGC 32
|
||||
/* Number of static registers we save. */
|
||||
#define O32_STATC 11
|
||||
/* Argument area frame size. */
|
||||
#define O32_ARGSZ (O32_SZREG * O32_ARGC)
|
||||
/* Static register save area frame size. */
|
||||
#define O32_STATSZ (SZREG * O32_STATC)
|
||||
/* Stack pointer register save area frame size. */
|
||||
#define O32_SPSZ SZREG
|
||||
/* Combined area frame size. */
|
||||
#define O32_FRAMESZ (O32_ARGSZ + O32_SPSZ + O32_STATSZ)
|
||||
/* Switched stack frame size. */
|
||||
#define O32_NFRAMESZ (O32_ARGSZ + O32_SPSZ)
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* O32 function call dispatcher, for interfacing 32-bit ROM routines.
|
||||
*
|
||||
* The standard 64 (N32) calling sequence is supported, with a0 holding
|
||||
* a function pointer, a1 a pointer to the new stack to call the
|
||||
* function with or 0 if no stack switching is requested, a2-a7 -- the
|
||||
* function call's first six arguments, and the stack -- the remaining
|
||||
* arguments (up to O32_ARGC, including a2-a7). Static registers, gp
|
||||
* and fp are preserved, v0 holds the result. This code relies on the
|
||||
* called o32 function for sp and ra restoration and this dispatcher has
|
||||
* to be placed in a KSEGx (or KUSEG) address space. Any pointers
|
||||
* passed have to point to addresses within one of these spaces as well.
|
||||
*/
|
||||
NESTED(call_o32, O32_FRAMESZ, ra)
|
||||
REG_SUBU sp,O32_FRAMESZ
|
||||
|
||||
REG_S ra,O32_FRAMESZ-1*SZREG(sp)
|
||||
REG_S fp,O32_FRAMESZ-2*SZREG(sp)
|
||||
REG_S gp,O32_FRAMESZ-3*SZREG(sp)
|
||||
REG_S s7,O32_FRAMESZ-4*SZREG(sp)
|
||||
REG_S s6,O32_FRAMESZ-5*SZREG(sp)
|
||||
REG_S s5,O32_FRAMESZ-6*SZREG(sp)
|
||||
REG_S s4,O32_FRAMESZ-7*SZREG(sp)
|
||||
REG_S s3,O32_FRAMESZ-8*SZREG(sp)
|
||||
REG_S s2,O32_FRAMESZ-9*SZREG(sp)
|
||||
REG_S s1,O32_FRAMESZ-10*SZREG(sp)
|
||||
REG_S s0,O32_FRAMESZ-11*SZREG(sp)
|
||||
|
||||
move jp,a0
|
||||
|
||||
move fp,sp
|
||||
beqz a1,0f
|
||||
REG_SUBU fp,a1,O32_NFRAMESZ
|
||||
0:
|
||||
REG_S sp,O32_NFRAMESZ-1*SZREG(fp)
|
||||
|
||||
sll a0,a2,zero
|
||||
sll a1,a3,zero
|
||||
sll a2,a4,zero
|
||||
sll a3,a5,zero
|
||||
sw a6,4*O32_SZREG(fp)
|
||||
sw a7,5*O32_SZREG(fp)
|
||||
|
||||
PTR_LA t0,O32_FRAMESZ(sp)
|
||||
PTR_LA t1,6*O32_SZREG(fp)
|
||||
li t2,O32_ARGC-6
|
||||
1:
|
||||
lw t3,(t0)
|
||||
REG_ADDU t0,SZREG
|
||||
sw t3,(t1)
|
||||
REG_SUBU t2,1
|
||||
REG_ADDU t1,O32_SZREG
|
||||
bnez t2,1b
|
||||
|
||||
move sp,fp
|
||||
|
||||
jalr jp
|
||||
|
||||
REG_L sp,O32_NFRAMESZ-1*SZREG(sp)
|
||||
|
||||
REG_L s0,O32_FRAMESZ-11*SZREG(sp)
|
||||
REG_L s1,O32_FRAMESZ-10*SZREG(sp)
|
||||
REG_L s2,O32_FRAMESZ-9*SZREG(sp)
|
||||
REG_L s3,O32_FRAMESZ-8*SZREG(sp)
|
||||
REG_L s4,O32_FRAMESZ-7*SZREG(sp)
|
||||
REG_L s5,O32_FRAMESZ-6*SZREG(sp)
|
||||
REG_L s6,O32_FRAMESZ-5*SZREG(sp)
|
||||
REG_L s7,O32_FRAMESZ-4*SZREG(sp)
|
||||
REG_L gp,O32_FRAMESZ-3*SZREG(sp)
|
||||
REG_L fp,O32_FRAMESZ-2*SZREG(sp)
|
||||
REG_L ra,O32_FRAMESZ-1*SZREG(sp)
|
||||
|
||||
REG_ADDU sp,O32_FRAMESZ
|
||||
jr ra
|
||||
END(call_o32)
|
101
arch/mips/fw/lib/cmdline.c
Normal file
101
arch/mips/fw/lib/cmdline.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/fw/fw.h>
|
||||
|
||||
int fw_argc;
|
||||
int *_fw_argv;
|
||||
int *_fw_envp;
|
||||
|
||||
void __init fw_init_cmdline(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Validate command line parameters. */
|
||||
if ((fw_arg0 >= CKSEG0) || (fw_arg1 < CKSEG0)) {
|
||||
fw_argc = 0;
|
||||
_fw_argv = NULL;
|
||||
} else {
|
||||
fw_argc = (fw_arg0 & 0x0000ffff);
|
||||
_fw_argv = (int *)fw_arg1;
|
||||
}
|
||||
|
||||
/* Validate environment pointer. */
|
||||
if (fw_arg2 < CKSEG0)
|
||||
_fw_envp = NULL;
|
||||
else
|
||||
_fw_envp = (int *)fw_arg2;
|
||||
|
||||
for (i = 1; i < fw_argc; i++) {
|
||||
strlcat(arcs_cmdline, fw_argv(i), COMMAND_LINE_SIZE);
|
||||
if (i < (fw_argc - 1))
|
||||
strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
char * __init fw_getcmdline(void)
|
||||
{
|
||||
return &(arcs_cmdline[0]);
|
||||
}
|
||||
|
||||
char *fw_getenv(char *envname)
|
||||
{
|
||||
char *result = NULL;
|
||||
|
||||
if (_fw_envp != NULL) {
|
||||
/*
|
||||
* Return a pointer to the given environment variable.
|
||||
* YAMON uses "name", "value" pairs, while U-Boot uses
|
||||
* "name=value".
|
||||
*/
|
||||
int i, yamon, index = 0;
|
||||
|
||||
yamon = (strchr(fw_envp(index), '=') == NULL);
|
||||
i = strlen(envname);
|
||||
|
||||
while (fw_envp(index)) {
|
||||
if (strncmp(envname, fw_envp(index), i) == 0) {
|
||||
if (yamon) {
|
||||
result = fw_envp(index + 1);
|
||||
break;
|
||||
} else if (fw_envp(index)[i] == '=') {
|
||||
result = (fw_envp(index + 1) + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Increment array index. */
|
||||
if (yamon)
|
||||
index += 2;
|
||||
else
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long fw_getenvl(char *envname)
|
||||
{
|
||||
unsigned long envl = 0UL;
|
||||
char *str;
|
||||
long val;
|
||||
int tmp;
|
||||
|
||||
str = fw_getenv(envname);
|
||||
if (str) {
|
||||
tmp = kstrtol(str, 0, &val);
|
||||
envl = (unsigned long)val;
|
||||
}
|
||||
|
||||
return envl;
|
||||
}
|
5
arch/mips/fw/sni/Makefile
Normal file
5
arch/mips/fw/sni/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# Makefile for the SNI prom monitor routines under Linux.
|
||||
#
|
||||
|
||||
lib-$(CONFIG_FW_SNIPROM) += sniprom.o
|
152
arch/mips/fw/sni/sniprom.c
Normal file
152
arch/mips/fw/sni/sniprom.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Big Endian PROM code for SNI RM machines
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
|
||||
* Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/console.h>
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/sni.h>
|
||||
#include <asm/mipsprom.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/bootinfo.h>
|
||||
|
||||
/* special SNI prom calls */
|
||||
/*
|
||||
* This does not exist in all proms - SINIX compares
|
||||
* the prom env variable "version" against "2.0008"
|
||||
* or greater. If lesser it tries to probe interesting
|
||||
* registers
|
||||
*/
|
||||
#define PROM_GET_MEMCONF 58
|
||||
#define PROM_GET_HWCONF 61
|
||||
|
||||
#define PROM_VEC (u64 *)CKSEG1ADDR(0x1fc00000)
|
||||
#define PROM_ENTRY(x) (PROM_VEC + (x))
|
||||
|
||||
#define ___prom_putchar ((int *(*)(int))PROM_ENTRY(PROM_PUTCHAR))
|
||||
#define ___prom_getenv ((char *(*)(char *))PROM_ENTRY(PROM_GETENV))
|
||||
#define ___prom_get_memconf ((void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF))
|
||||
#define ___prom_get_hwconf ((u32 (*)(void))PROM_ENTRY(PROM_GET_HWCONF))
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
||||
/* O32 stack has to be 8-byte aligned. */
|
||||
static u64 o32_stk[4096];
|
||||
#define O32_STK &o32_stk[sizeof(o32_stk)]
|
||||
|
||||
#define __PROM_O32(fun, arg) fun arg __asm__(#fun); \
|
||||
__asm__(#fun " = call_o32")
|
||||
|
||||
int __PROM_O32(__prom_putchar, (int *(*)(int), void *, int));
|
||||
char *__PROM_O32(__prom_getenv, (char *(*)(char *), void *, char *));
|
||||
void __PROM_O32(__prom_get_memconf, (void (*)(void *), void *, void *));
|
||||
u32 __PROM_O32(__prom_get_hwconf, (u32 (*)(void), void *));
|
||||
|
||||
#define _prom_putchar(x) __prom_putchar(___prom_putchar, O32_STK, x)
|
||||
#define _prom_getenv(x) __prom_getenv(___prom_getenv, O32_STK, x)
|
||||
#define _prom_get_memconf(x) __prom_get_memconf(___prom_get_memconf, O32_STK, x)
|
||||
#define _prom_get_hwconf() __prom_get_hwconf(___prom_get_hwconf, O32_STK)
|
||||
|
||||
#else
|
||||
#define _prom_putchar(x) ___prom_putchar(x)
|
||||
#define _prom_getenv(x) ___prom_getenv(x)
|
||||
#define _prom_get_memconf(x) ___prom_get_memconf(x)
|
||||
#define _prom_get_hwconf(x) ___prom_get_hwconf(x)
|
||||
#endif
|
||||
|
||||
void prom_putchar(char c)
|
||||
{
|
||||
_prom_putchar(c);
|
||||
}
|
||||
|
||||
|
||||
char *prom_getenv(char *s)
|
||||
{
|
||||
return _prom_getenv(s);
|
||||
}
|
||||
|
||||
void *prom_get_hwconf(void)
|
||||
{
|
||||
u32 hwconf = _prom_get_hwconf();
|
||||
|
||||
if (hwconf == 0xffffffff)
|
||||
return NULL;
|
||||
|
||||
return (void *)CKSEG1ADDR(hwconf);
|
||||
}
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* /proc/cpuinfo system type
|
||||
*
|
||||
*/
|
||||
char *system_type = "Unknown";
|
||||
const char *get_system_type(void)
|
||||
{
|
||||
return system_type;
|
||||
}
|
||||
|
||||
static void __init sni_mem_init(void)
|
||||
{
|
||||
int i, memsize;
|
||||
struct membank {
|
||||
u32 size;
|
||||
u32 base;
|
||||
u32 size2;
|
||||
u32 pad1;
|
||||
u32 pad2;
|
||||
} memconf[8];
|
||||
int brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
|
||||
|
||||
|
||||
/* MemSIZE from prom in 16MByte chunks */
|
||||
memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
|
||||
|
||||
pr_debug("IDProm memsize: %u MByte\n", memsize);
|
||||
|
||||
/* get memory bank layout from prom */
|
||||
_prom_get_memconf(&memconf);
|
||||
|
||||
pr_debug("prom_get_mem_conf memory configuration:\n");
|
||||
for (i = 0; i < 8 && memconf[i].size; i++) {
|
||||
if (brd_type == SNI_BRD_PCI_TOWER ||
|
||||
brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
|
||||
if (memconf[i].base >= 0x20000000 &&
|
||||
memconf[i].base < 0x30000000)
|
||||
memconf[i].base -= 0x20000000;
|
||||
}
|
||||
pr_debug("Bank%d: %08x @ %08x\n", i,
|
||||
memconf[i].size, memconf[i].base);
|
||||
add_memory_region(memconf[i].base, memconf[i].size,
|
||||
BOOT_MEM_RAM);
|
||||
}
|
||||
}
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
int argc = fw_arg0;
|
||||
u32 *argv = (u32 *)CKSEG0ADDR(fw_arg1);
|
||||
int i;
|
||||
|
||||
sni_mem_init();
|
||||
|
||||
/* copy prom cmdline parameters to kernel cmdline */
|
||||
for (i = 1; i < argc; i++) {
|
||||
strcat(arcs_cmdline, (char *)CKSEG0ADDR(argv[i]));
|
||||
if (i < (argc - 1))
|
||||
strcat(arcs_cmdline, " ");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue