Commit 3e6c5335 authored by Ralf Bächle's avatar Ralf Bächle Committed by Linus Torvalds

[PATCH] ARC update

This updates the ARC firmware support code.  Also removes the 64-bit
variant of the code; the 64-bit kernel now uses the 32-bit code also.
parent 726978f5
# #
# Makefile for the SGI arcs prom monitor library routines # Makefile for the ARC prom monitor library routines under Linux.
# under Linux.
# #
lib-y += console.o init.o memory.o tree.o env.o cmdline.o misc.o \ lib-y += cmdline.o env.o file.o identify.o init.o \
time.o file.o identify.o misc.o time.o tree.o
lib-$(CONFIG_ARC_MEMORY) += memory.o
lib-$(CONFIG_ARC_CONSOLE) += arc_con.o lib-$(CONFIG_ARC_CONSOLE) += arc_con.o
lib-$(CONFIG_ARC_PROMLIB) += promlib.o
...@@ -3,68 +3,48 @@ ...@@ -3,68 +3,48 @@
* ARC io-routines. * ARC io-routines.
* *
* Copyright (c) 1998 Harald Koerfgen * Copyright (c) 1998 Harald Koerfgen
* Copyright (c) 2001 Ralf Baechle
* Copyright (c) 2002 Thiemo Seufer
*/ */
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/ptrace.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/console.h> #include <linux/console.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <asm/sgialib.h>
extern char prom_getchar (void);
extern void prom_printf (char *, ...);
static void prom_console_write(struct console *co, const char *s, static void prom_console_write(struct console *co, const char *s,
unsigned count) unsigned count)
{ {
unsigned i; /* Do each character */
while (count--) {
/* if (*s == '\n')
* Now, do each character prom_putchar('\r');
*/ prom_putchar(*s++);
for (i = 0; i < count; i++) {
if (*s == 10)
prom_printf("%c", 13);
prom_printf("%c", *s++);
} }
} }
static int prom_console_wait_key(struct console *co)
{
return prom_getchar();
}
static int __init prom_console_setup(struct console *co, char *options) static int __init prom_console_setup(struct console *co, char *options)
{ {
return 0; return !(prom_flags & PROM_FLAG_USE_AS_CONSOLE);
}
static kdev_t prom_console_device(struct console *c)
{
return MKDEV(TTY_MAJOR, 64 + c->index);
} }
static struct console arc_cons = { static struct console arc_cons = {
"ttyS", .name = "arc",
prom_console_write, .write = prom_console_write,
NULL, .setup = prom_console_setup,
prom_console_device, .flags = CON_PRINTBUFFER,
prom_console_wait_key, .index = -1,
NULL,
prom_console_setup,
CON_PRINTBUFFER,
-1,
0,
NULL
}; };
/* /*
* Register console. * Register console.
*/ */
static void __init arc_console_init(void) static int __init arc_console_init(void)
{ {
register_console(&arc_cons); register_console(&arc_cons);
return 0;
} }
console_initcall(arc_console_init); console_initcall(arc_console_init);
/* /*
* 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. * cmdline.c: Kernel command line creation using ARCS argc/argv.
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
...@@ -12,11 +16,11 @@ ...@@ -12,11 +16,11 @@
#undef DEBUG_CMDLINE #undef DEBUG_CMDLINE
char arcs_cmdline[COMMAND_LINE_SIZE]; char arcs_cmdline[CL_SIZE];
char * __init prom_getcmdline(void) char * __init prom_getcmdline(void)
{ {
return &(arcs_cmdline[0]); return arcs_cmdline;
} }
static char *ignored[] = { static char *ignored[] = {
...@@ -28,7 +32,6 @@ static char *ignored[] = { ...@@ -28,7 +32,6 @@ static char *ignored[] = {
"OSLoadFilename=", "OSLoadFilename=",
"OSLoadOptions=" "OSLoadOptions="
}; };
#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0])))))
static char *used_arc[][2] = { static char *used_arc[][2] = {
{ "OSLoadPartition=", "root=" }, { "OSLoadPartition=", "root=" },
...@@ -43,16 +46,16 @@ static char * __init move_firmware_args(char* cp) ...@@ -43,16 +46,16 @@ static char * __init move_firmware_args(char* cp)
actr = 1; /* Always ignore argv[0] */ actr = 1; /* Always ignore argv[0] */
while (actr < prom_argc) { while (actr < prom_argc) {
for(i = 0; i < NENTS(used_arc); i++) { for(i = 0; i < ARRAY_SIZE(used_arc); i++) {
int len = strlen(used_arc[i][0]); int len = strlen(used_arc[i][0]);
if(!strncmp(prom_argv[actr], used_arc[i][0], len)) { if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
/* Ok, we want it. First append the replacement... */ /* Ok, we want it. First append the replacement... */
strcat(cp, used_arc[i][1]); strcat(cp, used_arc[i][1]);
cp += strlen(used_arc[i][1]); cp += strlen(used_arc[i][1]);
/* ... and now the argument */ /* ... and now the argument */
s = strstr(prom_argv[actr], "="); s = strstr(prom_argv(actr), "=");
if(s) { if (s) {
s++; s++;
strcpy(cp, s); strcpy(cp, s);
cp += strlen(s); cp += strlen(s);
...@@ -67,7 +70,6 @@ static char * __init move_firmware_args(char* cp) ...@@ -67,7 +70,6 @@ static char * __init move_firmware_args(char* cp)
return cp; return cp;
} }
void __init prom_init_cmdline(void) void __init prom_init_cmdline(void)
{ {
char *cp; char *cp;
...@@ -75,7 +77,7 @@ void __init prom_init_cmdline(void) ...@@ -75,7 +77,7 @@ void __init prom_init_cmdline(void)
actr = 1; /* Always ignore argv[0] */ actr = 1; /* Always ignore argv[0] */
cp = &(arcs_cmdline[0]); cp = arcs_cmdline;
/* /*
* Move ARC variables to the beginning to make sure they can be * Move ARC variables to the beginning to make sure they can be
* overridden by later arguments. * overridden by later arguments.
...@@ -83,25 +85,26 @@ void __init prom_init_cmdline(void) ...@@ -83,25 +85,26 @@ void __init prom_init_cmdline(void)
cp = move_firmware_args(cp); cp = move_firmware_args(cp);
while (actr < prom_argc) { while (actr < prom_argc) {
for (i = 0; i < NENTS(ignored); i++) { for (i = 0; i < ARRAY_SIZE(ignored); i++) {
int len = strlen(ignored[i]); int len = strlen(ignored[i]);
if(!strncmp(prom_argv[actr], ignored[i], len)) if (!strncmp(prom_argv(actr), ignored[i], len))
goto pic_cont; goto pic_cont;
} }
/* Ok, we want it. */ /* Ok, we want it. */
strcpy(cp, prom_argv[actr]); strcpy(cp, prom_argv(actr));
cp += strlen(prom_argv[actr]); cp += strlen(prom_argv(actr));
*cp++ = ' '; *cp++ = ' ';
pic_cont: pic_cont:
actr++; actr++;
} }
if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
if (cp != arcs_cmdline) /* get rid of trailing space */
--cp; --cp;
*cp = '\0'; *cp = '\0';
#ifdef DEBUG_CMDLINE #ifdef DEBUG_CMDLINE
prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0])); printk(KERN_DEBUG "prom cmdline: %s\n", arcs_cmdline);
#endif #endif
} }
...@@ -6,14 +6,9 @@ ...@@ -6,14 +6,9 @@
* Copyright (C) 1996 David S. Miller (dm@sgi.com) * Copyright (C) 1996 David S. Miller (dm@sgi.com)
* Compability with board caches, Ulf Carlsson * Compability with board caches, Ulf Carlsson
*/ */
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
#include <asm/bcache.h> #include <asm/bcache.h>
#include <linux/console.h>
#include <linux/kdev_t.h>
#include <linux/major.h>
/* /*
* IP22 boardcache is not compatible with board caches. Thus we disable it * IP22 boardcache is not compatible with board caches. Thus we disable it
...@@ -27,44 +22,42 @@ ...@@ -27,44 +22,42 @@
void prom_putchar(char c) void prom_putchar(char c)
{ {
long cnt; ULONG cnt;
char it = c; CHAR it = c;
bc_disable(); bc_disable();
romvec->write(1, &it, 1, &cnt); ArcWrite(1, &it, 1, &cnt);
bc_enable(); bc_enable();
} }
char __init prom_getchar(void) char prom_getchar(void)
{ {
long cnt; ULONG cnt;
char c; CHAR c;
bc_disable(); bc_disable();
romvec->read(0, &c, 1, &cnt); ArcRead(0, &c, 1, &cnt);
bc_enable(); bc_enable();
return c; return c;
} }
static char ppbuf[1024];
void prom_printf(char *fmt, ...) void prom_printf(char *fmt, ...)
{ {
va_list args; va_list args;
char ch, *bptr; char ppbuf[1024];
int i; char *bptr;
va_start(args, fmt); va_start(args, fmt);
i = vsprintf(ppbuf, fmt, args); vsprintf(ppbuf, fmt, args);
bptr = ppbuf; bptr = ppbuf;
while ((ch = *(bptr++)) != 0) { while (*bptr != 0) {
if (ch == '\n') if (*bptr == '\n')
prom_putchar('\r'); prom_putchar('\r');
prom_putchar(ch); prom_putchar(*bptr++);
} }
va_end(args); va_end(args);
} }
/* /*
* 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. * env.c: ARCS environment variable routines.
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
* $Id: env.c,v 1.2 1999/10/09 00:00:57 ralf Exp $
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
#include <asm/arc/types.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
PCHAR __init PCHAR __init
ArcGetEnvironmentVariable(CHAR *name) ArcGetEnvironmentVariable(CHAR *name)
{ {
return romvec->get_evar(name); return (CHAR *) ARC_CALL1(get_evar, name);
} }
LONG __init LONG __init
ArcSetEnvironmentVariable(PCHAR name, PCHAR value) ArcSetEnvironmentVariable(PCHAR name, PCHAR value)
{ {
return romvec->set_evar(name, value); return ARC_CALL2(set_evar, name, value);
} }
/* /*
* file.c: ARCS firmware interface to files. * 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@engr.sgi.com) * ARC firmware interface.
* *
* $Id: file.c,v 1.1 1998/10/18 13:32:08 tsbogend Exp $ * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle
* Copyright (C) 1999 Silicon Graphics, Inc.
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <asm/arc/types.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
long __init prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt) LONG __init
ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer,
ULONG N, ULONG *Count)
{ {
return romvec->get_vdirent(fd, ent, num, cnt); return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count);
} }
long __init prom_open(char *name, enum linux_omode md, unsigned long *fd) LONG __init
ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID)
{ {
return romvec->open(name, md, fd); return ARC_CALL3(open, Path, OpenMode, FileID);
} }
long __init prom_close(unsigned long fd) LONG __init
ArcClose(ULONG FileID)
{ {
return romvec->close(fd); return ARC_CALL1(close, FileID);
} }
long __init prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt) LONG __init
ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count)
{ {
return romvec->read(fd, buf, num, cnt); return ARC_CALL4(read, FileID, Buffer, N, Count);
} }
long __init prom_getrstatus(unsigned long fd) LONG __init
ArcGetReadStatus(ULONG FileID)
{ {
return romvec->get_rstatus(fd); return ARC_CALL1(get_rstatus, FileID);
} }
long __init prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt) LONG __init
ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count)
{ {
return romvec->write(fd, buf, num, cnt); return ARC_CALL4(write, FileID, Buffer, N, Count);
} }
long __init prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm) LONG __init
ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode)
{ {
return romvec->seek(fd, off, sm); return ARC_CALL3(seek, FileID, Position, SeekMode);
} }
long __init prom_mount(char *name, enum linux_mountops op) LONG __init
ArcMount(char *name, enum linux_mountops op)
{ {
return romvec->mount(name, op); return ARC_CALL2(mount, name, op);
} }
long __init prom_getfinfo(unsigned long fd, struct linux_finfo *buf) LONG __init
ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information)
{ {
return romvec->get_finfo(fd, buf); return ARC_CALL2(get_finfo, FileID, Information);
} }
long __init prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk) LONG __init ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags,
ULONG AttributeMask)
{ {
return romvec->set_finfo(fd, flags, msk); return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask);
} }
/* /*
* 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 * identify.c: identify machine by looking up system identifier
* *
* Copyright (C) 1998 Thomas Bogendoerfer * Copyright (C) 1998 Thomas Bogendoerfer
...@@ -7,59 +11,107 @@ ...@@ -7,59 +11,107 @@
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*/ */
#include <linux/config.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/string.h> #include <linux/string.h>
#include <asm/sgi/sgi.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
struct smatch { struct smatch {
char *name; char *arcname;
char *liname;
int group; int group;
int type; int type;
int flags; int flags;
}; };
static struct smatch mach_table[] = { static struct smatch mach_table[] = {
{"SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, PROM_FLAG_ARCS}, { "SGI-IP22",
{"Microsoft-Jazz", MACH_GROUP_JAZZ, MACH_MIPS_MAGNUM_4000, 0}, "SGI Indy",
{"PICA-61", MACH_GROUP_JAZZ, MACH_ACER_PICA_61, 0}, MACH_GROUP_SGI,
{"RM200PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, 0} MACH_SGI_IP22,
PROM_FLAG_ARCS
}, { "SGI-IP27",
"SGI Origin",
MACH_GROUP_SGI,
MACH_SGI_IP27,
PROM_FLAG_ARCS
}, { "SGI-IP28",
"SGI IP28",
MACH_GROUP_SGI,
MACH_SGI_IP28,
PROM_FLAG_ARCS
}, { "SGI-IP32",
"SGI IP32",
MACH_GROUP_SGI,
MACH_SGI_IP32,
PROM_FLAG_ARCS
}, { "Microsoft-Jazz",
"Jazz MIPS_Magnum_4000",
MACH_GROUP_JAZZ,
MACH_MIPS_MAGNUM_4000,
0
}, { "PICA-61",
"Jazz Acer_PICA_61",
MACH_GROUP_JAZZ,
MACH_ACER_PICA_61,
0
}, { "RM200PCI",
"SNI RM200_PCI",
MACH_GROUP_SNI_RM,
MACH_SNI_RM200_PCI,
0
}
}; };
int prom_flags; int prom_flags;
static struct smatch *__init string_to_mach(char *s) static struct smatch * __init string_to_mach(const char *s)
{ {
int i; int i;
for (i = 0; i < (sizeof(mach_table) / sizeof (mach_table[0])); i++) { for (i = 0; i < (sizeof(mach_table) / sizeof (mach_table[0])); i++) {
if (!strcmp(s, mach_table[i].name)) if (!strcmp(s, mach_table[i].arcname))
return &mach_table[i]; return &mach_table[i];
} }
prom_printf("\nYeee, could not determine architecture type <%s>\n",
s); panic("Yeee, could not determine architecture type <%s>", s);
prom_printf("press a key to reboot\n"); }
prom_getchar();
romvec->imode(); char *system_type;
return NULL;
const char *get_system_type(void)
{
return system_type;
} }
void __init prom_identify_arch(void) void __init prom_identify_arch(void)
{ {
pcomponent *p; pcomponent *p;
struct smatch *mach; struct smatch *mach;
const char *iname;
/* /*
* The root component tells us what machine architecture we * The root component tells us what machine architecture we have here.
* have here.
*/ */
p = prom_getchild(PROM_NULL_COMPONENT); p = ArcGetChild(PROM_NULL_COMPONENT);
printk("ARCH: %s\n", p->iname); if (p == NULL) {
mach = string_to_mach(p->iname); #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;
mips_machgroup = mach->group; mips_machgroup = mach->group;
mips_machtype = mach->type; mips_machtype = mach->type;
......
/* /*
* This file is subject to the terms and conditions of the GNU General Public+ * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
...@@ -16,38 +16,17 @@ ...@@ -16,38 +16,17 @@
/* Master romvec interface. */ /* Master romvec interface. */
struct linux_romvec *romvec; struct linux_romvec *romvec;
struct linux_promblock *sgi_pblock;
int prom_argc; int prom_argc;
char **prom_argv, **prom_envp; LONG *_prom_argv, *_prom_envp;
unsigned short prom_vers, prom_rev;
extern void prom_testtree(void);
extern void arc_setup_console(void);
void __init prom_init(int argc, char **argv, char **envp, int *prom_vec) void __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
{ {
struct linux_promblock *pb; PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
romvec = ROMVECTOR; romvec = ROMVECTOR;
pb = sgi_pblock = PROMBLOCK;
prom_argc = argc; prom_argc = argc;
prom_argv = argv; _prom_argv = (LONG *) argv;
prom_envp = envp; _prom_envp = (LONG *) envp;
#if 0
/* arc_printf should not use prom_printf as soon as we free
* the prom buffers - This horribly breaks on Indys with framebuffer
* as it simply stops after initialising swap - On the Indigo2 serial
* console you will get A LOT illegal instructions - Only enable
* this for early init crashes - This also brings up artefacts of
* printing everything twice on serial console and on GFX Console
* this has the effect of having the prom printing everything
* in the small rectangle and the kernel printing around.
*/
arc_setup_console();
#endif
if (pb->magic != 0x53435241) { if (pb->magic != 0x53435241) {
prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic); prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic);
while(1) while(1)
...@@ -55,19 +34,14 @@ void __init prom_init(int argc, char **argv, char **envp, int *prom_vec) ...@@ -55,19 +34,14 @@ void __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
} }
prom_init_cmdline(); prom_init_cmdline();
prom_vers = pb->ver;
prom_rev = pb->rev;
prom_identify_arch(); prom_identify_arch();
printk("PROMLIB: ARC firmware Version %d Revision %d\n", printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n",
prom_vers, prom_rev); pb->ver, pb->rev);
prom_meminit(); prom_meminit();
#ifdef DEBUG_PROM_INIT #ifdef DEBUG_PROM_INIT
{
prom_printf("Press a key to reboot\n"); prom_printf("Press a key to reboot\n");
(void) prom_getchar(); prom_getchar();
romvec->imode(); ArcEnterInteractiveMode();
}
#endif #endif
} }
...@@ -2,7 +2,14 @@ ...@@ -2,7 +2,14 @@
* memory.c: PROM library functions for acquiring/using memory descriptors * memory.c: PROM library functions for acquiring/using memory descriptors
* given to us from the ARCS firmware. * given to us from the ARCS firmware.
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * 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/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -19,10 +26,9 @@ ...@@ -19,10 +26,9 @@
#undef DEBUG #undef DEBUG
struct linux_mdesc * __init struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
ArcGetMemoryDescriptor(struct linux_mdesc *Current)
{ {
return romvec->get_mdesc(Current); return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
} }
#ifdef DEBUG /* convenient for debugging */ #ifdef DEBUG /* convenient for debugging */
...@@ -47,7 +53,8 @@ static char *arc_mtypes[8] = { ...@@ -47,7 +53,8 @@ static char *arc_mtypes[8] = {
"FirmwarePermanent", "FirmwarePermanent",
"FreeContiguous" "FreeContiguous"
}; };
#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc] #define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
: arc_mtypes[a.arc]
#endif #endif
static inline int memtype_classify_arcs (union linux_memtypes type) static inline int memtype_classify_arcs (union linux_memtypes type)
...@@ -128,8 +135,7 @@ void __init prom_meminit(void) ...@@ -128,8 +135,7 @@ void __init prom_meminit(void)
} }
} }
void __init void __init prom_free_prom_memory (void)
prom_free_prom_memory (void)
{ {
unsigned long freed = 0; unsigned long freed = 0;
unsigned long addr; unsigned long addr;
...@@ -149,5 +155,5 @@ prom_free_prom_memory (void) ...@@ -149,5 +155,5 @@ prom_free_prom_memory (void)
freed += PAGE_SIZE; freed += PAGE_SIZE;
} }
} }
printk("Freeing prom memory: %ldkb freed\n", freed >> 10); printk(KERN_INFO "Freeing prom memory: %ldkb freed\n", freed >> 10);
} }
/* /*
* misc.c: Miscellaneous ARCS PROM routines. * 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 (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc.
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <asm/bcache.h> #include <asm/bcache.h>
#include <asm/arc/types.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -15,68 +23,81 @@ ...@@ -15,68 +23,81 @@
extern void *sgiwd93_host; extern void *sgiwd93_host;
extern void reset_wd33c93(void *instance); extern void reset_wd33c93(void *instance);
void prom_halt(void) VOID
ArcHalt(VOID)
{ {
bc_disable(); bc_disable();
cli(); local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93 #ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host); reset_wd33c93(sgiwd93_host);
#endif #endif
romvec->halt(); ARC_CALL0(halt);
never: goto never;
} }
void prom_powerdown(void) VOID
ArcPowerDown(VOID)
{ {
bc_disable(); bc_disable();
cli(); local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93 #ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host); reset_wd33c93(sgiwd93_host);
#endif #endif
romvec->pdown(); ARC_CALL0(pdown);
never: goto never;
} }
/* XXX is this a soft reset basically? XXX */ /* XXX is this a soft reset basically? XXX */
void prom_restart(void) VOID
ArcRestart(VOID)
{ {
bc_disable(); bc_disable();
cli(); local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93 #ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host); reset_wd33c93(sgiwd93_host);
#endif #endif
romvec->restart(); ARC_CALL0(restart);
never: goto never;
} }
void prom_reboot(void) VOID
ArcReboot(VOID)
{ {
bc_disable(); bc_disable();
cli(); local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93 #ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host); reset_wd33c93(sgiwd93_host);
#endif #endif
romvec->reboot(); ARC_CALL0(reboot);
never: goto never;
} }
void ArcEnterInteractiveMode(void) VOID
ArcEnterInteractiveMode(VOID)
{ {
bc_disable(); bc_disable();
cli(); local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93 #ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host); reset_wd33c93(sgiwd93_host);
#endif #endif
romvec->imode(); ARC_CALL0(imode);
never: goto never;
} }
long prom_cfgsave(void) LONG
ArcSaveConfiguration(VOID)
{ {
return romvec->cfg_save(); return ARC_CALL0(cfg_save);
} }
struct linux_sysid *prom_getsysid(void) struct linux_sysid *
ArcGetSystemId(VOID)
{ {
return romvec->get_sysid(); return (struct linux_sysid *) ARC_CALL0(get_sysid);
} }
void __init prom_cacheflush(void) VOID __init
ArcFlushAllCaches(VOID)
{ {
romvec->cache_flush(); ARC_CALL0(cache_flush);
} }
...@@ -4,30 +4,40 @@ ...@@ -4,30 +4,40 @@
* for more details. * for more details.
* *
* Copyright (C) 1996 David S. Miller (dm@sgi.com) * Copyright (C) 1996 David S. Miller (dm@sgi.com)
* Compability with board caches, Ulf Carlsson
*/ */
#include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
#include <asm/bcache.h>
static char ppbuf[1024]; /*
* 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_printf(char *fmt, ...) void prom_putchar(char c)
{ {
va_list args; ULONG cnt;
char ch, *bptr; CHAR it = c;
int i;
va_start(args, fmt); bc_disable();
i = vsprintf(ppbuf, fmt, args); ArcWrite(1, &it, 1, &cnt);
bc_enable();
}
bptr = ppbuf; char prom_getchar(void)
{
ULONG cnt;
CHAR c;
while((ch = *(bptr++)) != 0) { bc_disable();
if(ch == '\n') ArcRead(0, &c, 1, &cnt);
prom_putchar('\r'); bc_enable();
prom_putchar(ch); return c;
}
va_end(args);
return;
} }
/* /*
* salone.c: Routines to load into memory and execute stand-along * Routines to load into memory and execute stand-along program images using
* program images using ARCS PROM firmware. * ARCS PROM firmware.
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
* $Id: salone.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
long __init prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr) LONG __init ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr)
{ {
return romvec->load(name, end, pc, eaddr); return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr);
} }
long __init prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp) LONG __init ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[],
CHAR *Envp[])
{ {
return romvec->invoke(pc, sp, argc, argv, envp); return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp);
} }
long __init prom_exec(char *name, long argc, char **argv, char **envp) LONG __init ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[])
{ {
return romvec->exec(name, argc, argv, envp); return ARC_CALL4(exec, Path, Argc, Argv, Envp);
} }
/* /*
* time.c: Extracting time information from ARCS prom. * 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@engr.sgi.com) * Extracting time information from ARCS prom.
* *
* $Id: time.c,v 1.1 1998/10/18 13:32:10 tsbogend Exp $ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <asm/arc/types.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
struct linux_tinfo * __init prom_gettinfo(void) struct linux_tinfo * __init
ArcGetTime(VOID)
{ {
return romvec->get_tinfo(); return (struct linux_tinfo *) ARC_CALL0(get_tinfo);
} }
unsigned long __init prom_getrtime(void) ULONG __init
ArcGetRelativeTime(VOID)
{ {
return romvec->get_rtime(); return ARC_CALL0(get_rtime);
} }
/* /*
* tree.c: PROM component device tree code. * 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@engr.sgi.com) * PROM component device tree code.
* *
* $Id: tree.c,v 1.1 1998/10/18 13:32:10 tsbogend Exp $ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc.
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <asm/arc/types.h>
#include <asm/sgialib.h> #include <asm/sgialib.h>
#define DEBUG_PROM_TREE #undef DEBUG_PROM_TREE
pcomponent * __init prom_getsibling(pcomponent *this) pcomponent * __init
ArcGetPeer(pcomponent *Current)
{ {
if(this == PROM_NULL_COMPONENT) if (Current == PROM_NULL_COMPONENT)
return PROM_NULL_COMPONENT; return PROM_NULL_COMPONENT;
return romvec->next_component(this);
return (pcomponent *) ARC_CALL1(next_component, Current);
} }
pcomponent * __init prom_getchild(pcomponent *this) pcomponent * __init
ArcGetChild(pcomponent *Current)
{ {
return romvec->child_component(this); return (pcomponent *) ARC_CALL1(child_component, Current);
} }
pcomponent * __init prom_getparent(pcomponent *child) pcomponent * __init
ArcGetParent(pcomponent *Current)
{ {
if(child == PROM_NULL_COMPONENT) if (Current == PROM_NULL_COMPONENT)
return PROM_NULL_COMPONENT; return PROM_NULL_COMPONENT;
return romvec->parent_component(child);
return (pcomponent *) ARC_CALL1(parent_component, Current);
} }
long __init prom_getcdata(void *buffer, pcomponent *this) LONG __init
ArcGetConfigurationData(VOID *Buffer, pcomponent *Current)
{ {
return romvec->component_data(buffer, this); return ARC_CALL2(component_data, Buffer, Current);
} }
pcomponent * __init prom_childadd(pcomponent *this, pcomponent *tmp, void *data) pcomponent * __init
ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData)
{ {
return romvec->child_add(this, tmp, data); return (pcomponent *)
ARC_CALL3(child_add, Current, Template, ConfigurationData);
} }
long __init prom_delcomponent(pcomponent *this) LONG __init
ArcDeleteComponent(pcomponent *ComponentToDelete)
{ {
return romvec->comp_del(this); return ARC_CALL1(comp_del, ComponentToDelete);
} }
pcomponent * __init prom_componentbypath(char *path) pcomponent * __init
ArcGetComponent(CHAR *Path)
{ {
return romvec->component_by_path(path); return (pcomponent *)ARC_CALL1(component_by_path, Path);
} }
#ifdef DEBUG_PROM_TREE #ifdef DEBUG_PROM_TREE
static char *classes[] = { static char *classes[] = {
"system", "processor", "cache", "adapter", "controller", "peripheral", "system", "processor", "cache", "adapter", "controller", "peripheral",
"memory" "memory"
}; };
static char *types[] = { static char *types[] = {
"arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache", "sccache", "arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache",
"memdev", "eisa adapter", "tc adapter", "scsi adapter", "dti adapter", "sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter",
"multi-func adapter", "disk controller", "tp controller", "dti adapter", "multi-func adapter", "disk controller",
"cdrom controller", "worm controller", "serial controller", "tp controller", "cdrom controller", "worm controller",
"net controller", "display controller", "parallel controller", "serial controller", "net controller", "display controller",
"pointer controller", "keyboard controller", "audio controller", "parallel controller", "pointer controller", "keyboard controller",
"misc controller", "disk peripheral", "floppy peripheral", "audio controller", "misc controller", "disk peripheral",
"tp peripheral", "modem peripheral", "monitor peripheral", "floppy peripheral", "tp peripheral", "modem peripheral",
"printer peripheral", "pointer peripheral", "keyboard peripheral", "monitor peripheral", "printer peripheral", "pointer peripheral",
"terminal peripheral", "line peripheral", "net peripheral", "keyboard peripheral", "terminal peripheral", "line peripheral",
"misc peripheral", "anonymous" "net peripheral", "misc peripheral", "anonymous"
}; };
static char *iflags[] = { static char *iflags[] = {
...@@ -74,7 +90,8 @@ static char *iflags[] = { ...@@ -74,7 +90,8 @@ static char *iflags[] = {
"input", "output" "input", "output"
}; };
static void __init dump_component(pcomponent *p) static void __init
dump_component(pcomponent *p)
{ {
prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>", prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>",
p, classes[p->class], types[p->type], p, classes[p->class], types[p->type],
...@@ -83,27 +100,28 @@ static void __init dump_component(pcomponent *p) ...@@ -83,27 +100,28 @@ static void __init dump_component(pcomponent *p)
p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname); p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
} }
static void __init traverse(pcomponent *p, int op) static void __init
traverse(pcomponent *p, int op)
{ {
dump_component(p); dump_component(p);
if(prom_getchild(p)) if(ArcGetChild(p))
traverse(prom_getchild(p), 1); traverse(ArcGetChild(p), 1);
if(prom_getsibling(p) && op) if(ArcGetPeer(p) && op)
traverse(prom_getsibling(p), 1); traverse(ArcGetPeer(p), 1);
} }
void __init prom_testtree(void) void __init
prom_testtree(void)
{ {
pcomponent *p; pcomponent *p;
p = prom_getchild(PROM_NULL_COMPONENT); p = ArcGetChild(PROM_NULL_COMPONENT);
dump_component(p); dump_component(p);
p = prom_getchild(p); p = ArcGetChild(p);
while(p) { while(p) {
dump_component(p); dump_component(p);
p = prom_getsibling(p); p = ArcGetPeer(p);
} }
prom_printf("press a key\n");
prom_getchar();
} }
#endif
#endif /* DEBUG_PROM_TREE */
#
# Makefile for the ARC prom monitor library routines under Linux.
#
lib-y := console.o init.o identify.o tree.o env.o cmdline.o misc.o time.o \
file.o
lib-$(CONFIG_ARC_MEMORY) += memory.o
lib-$(CONFIG_ARC_CONSOLE) += arc_con.o
/*
* Wrap-around code for a console using the
* ARC io-routines.
*
* Copyright (c) 1998 Harald Koerfgen
* Copyright (c) 2001 Ralf Baechle
*/
#include <linux/tty.h>
#include <linux/major.h>
#include <linux/ptrace.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/fs.h>
#include <asm/sgialib.h>
extern void prom_printf (char *, ...);
void prom_putchar(char c)
{
ULONG cnt;
CHAR it = c;
ArcWrite(1, &it, 1, &cnt);
}
static void prom_console_write(struct console *co, const char *s,
unsigned count)
{
unsigned i;
/*
* Now, do each character
*/
for (i = 0; i < count; i++) {
if (*s == 10)
prom_printf("%c", 13);
prom_printf("%c", *s++);
}
}
static int prom_console_wait_key(struct console *co)
{
return 0;
}
static int __init prom_console_setup(struct console *co, char *options)
{
return 0;
}
static kdev_t prom_console_device(struct console *c)
{
return MKDEV(TTY_MAJOR, 64 + c->index);
}
static struct console arc_cons = {
"ttyS",
prom_console_write,
NULL,
prom_console_device,
prom_console_wait_key,
NULL,
prom_console_setup,
CON_PRINTBUFFER,
-1,
0,
NULL
};
/*
* Register console.
*/
void __init arc_console_init(void)
{
register_console(&arc_cons);
}
/*
* 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 (dm@engr.sgi.com)
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/sgialib.h>
#include <asm/bootinfo.h>
/* #define DEBUG_CMDLINE */
char arcs_cmdline[CL_SIZE];
char * __init prom_getcmdline(void)
{
return &(arcs_cmdline[0]);
}
static char *ignored[] = {
"ConsoleIn=",
"ConsoleOut=",
"SystemPartition=",
"OSLoader=",
"OSLoadPartition=",
"OSLoadFilename=",
"OSLoadOptions="
};
#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0])))))
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 < NENTS(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 = strstr(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[0]);
/*
* 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 < NENTS(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[0])) /* get rid of trailing space */
--cp;
*cp = '\0';
#ifdef DEBUG_CMDLINE
prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0]));
#endif
}
/*
* 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 (dm@engr.sgi.com)
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/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);
}
/*
* 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 <linux/init.h>
#include <asm/arc/types.h>
#include <asm/sgialib.h>
LONG __init
ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer,
ULONG N, ULONG *Count)
{
return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count);
}
LONG __init
ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID)
{
return ARC_CALL3(open, Path, OpenMode, FileID);
}
LONG __init
ArcClose(ULONG FileID)
{
return ARC_CALL1(close, FileID);
}
LONG __init
ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count)
{
return ARC_CALL4(read, FileID, Buffer, N, Count);
}
LONG __init
ArcGetReadStatus(ULONG FileID)
{
return ARC_CALL1(get_rstatus, FileID);
}
LONG __init
ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count)
{
return ARC_CALL4(write, FileID, Buffer, N, Count);
}
LONG __init
ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode)
{
return ARC_CALL3(seek, FileID, Position, SeekMode);
}
LONG __init
ArcMount(char *name, enum linux_mountops op)
{
return ARC_CALL2(mount, name, op);
}
LONG __init
ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information)
{
return ARC_CALL2(get_finfo, FileID, Information);
}
LONG __init ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags,
ULONG AttributeMask)
{
return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask);
}
/*
* 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 (dm@engr.sgi.com)
*/
#include <linux/init.h>
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
#include <asm/sgialib.h>
#include <asm/bootinfo.h>
struct smatch {
char *name;
int group;
int type;
int flags;
};
static struct smatch mach_table[] = {
{ "SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, PROM_FLAG_ARCS },
{ "SGI-IP27", MACH_GROUP_SGI, MACH_SGI_IP27, PROM_FLAG_ARCS },
{ "Microsoft-Jazz", MACH_GROUP_JAZZ, MACH_MIPS_MAGNUM_4000, 0 },
{ "PICA-61", MACH_GROUP_JAZZ, MACH_ACER_PICA_61, 0 },
{ "RM200PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, 0 }
};
int prom_flags;
static struct smatch * __init
string_to_mach(const char *s)
{
int i;
for (i = 0; i < (sizeof (mach_table) / sizeof (mach_table[0])); i++) {
if(!strcmp(s, mach_table[i].name))
return &mach_table[i];
}
panic("\nYeee, could not determine architecture type <%s>", s);
return NULL;
}
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 bisbehaves, seems to not implement ARC
GetChild(). So we just assume it's an IP27. */
iname = "SGI-IP27";
#endif
} else
iname = (char *) (long) p->iname;
printk("ARCH: %s\n", iname);
mach = string_to_mach(iname);
mips_machgroup = mach->group;
mips_machtype = mach->type;
prom_flags = mach->flags;
}
/*
* 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 (dm@engr.sgi.com)
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/sgialib.h>
#undef DEBUG_PROM_INIT
/* Master romvec interface. */
struct linux_romvec *romvec;
PSYSTEM_PARAMETER_BLOCK sgi_pblock;
int prom_argc;
LONG *_prom_argv, *_prom_envp;
unsigned short prom_vers, prom_rev;
extern void prom_testtree(void);
int __init
prom_init(int argc, char **argv, char **envp)
{
PSYSTEM_PARAMETER_BLOCK pb;
romvec = ROMVECTOR;
pb = sgi_pblock = PROMBLOCK;
prom_argc = argc;
_prom_argv = (LONG *) argv;
_prom_envp = (LONG *) envp;
if(pb->magic != 0x53435241) {
prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic);
while(1)
;
}
prom_init_cmdline();
prom_vers = pb->ver;
prom_rev = pb->rev;
prom_identify_arch();
printk("PROMLIB: ARC firmware Version %d Revision %d\n",
prom_vers, prom_rev);
prom_meminit();
#ifdef DEBUG_PROM_INIT
{
prom_printf("Press a key to reboot\n");
(void) prom_getchar();
ArcEnterInteractiveMode();
}
#endif
return 0;
}
/*
* 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
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;
prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
i=0;
prom_printf ("i=%d\n", i);
p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
prom_printf ("i=%d\n", i);
while(p) {
prom_printf("[%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 << PAGE_SHIFT;
size = p->pages << PAGE_SHIFT;
type = prom_memtype_classify(p->type);
add_memory_region(base, size, type);
}
}
void __init prom_free_prom_memory (void)
{
unsigned long freed = 0;
unsigned long addr;
int i;
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;
while (addr < boot_mem_map.map[i].addr
+ boot_mem_map.map[i].size) {
ClearPageReserved(virt_to_page(__va(addr)));
set_page_count(virt_to_page(__va(addr)), 1);
free_page((unsigned long)__va(addr));
addr += PAGE_SIZE;
freed += PAGE_SIZE;
}
}
printk(KERN_INFO "Freeing prom memory: %ldkb freed\n", freed >> 10);
}
/*
* 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 (dm@engr.sgi.com)
* Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/bcache.h>
#include <asm/arc/types.h>
#include <asm/sgialib.h>
#include <asm/bootinfo.h>
#include <asm/system.h>
extern unsigned long mips_cputype;
extern void *sgiwd93_host;
extern void reset_wd33c93(void *instance);
VOID
ArcHalt(VOID)
{
bc_disable();
cli();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
ARC_CALL0(halt);
never: goto never;
}
VOID
ArcPowerDown(VOID)
{
bc_disable();
cli();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
ARC_CALL0(pdown);
never: goto never;
}
/* XXX is this a soft reset basically? XXX */
VOID
ArcRestart(VOID)
{
bc_disable();
cli();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
ARC_CALL0(restart);
never: goto never;
}
VOID
ArcReboot(VOID)
{
bc_disable();
cli();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
ARC_CALL0(reboot);
never: goto never;
}
VOID
ArcEnterInteractiveMode(VOID)
{
bc_disable();
cli();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
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);
}
/*
* Routines to load into memory and execute stand-along program images using
* ARCS PROM firmware.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*/
#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);
}
/*
* 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 (dm@engr.sgi.com)
*/
#include <linux/init.h>
#include <asm/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);
}
/*
* 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 (dm@engr.sgi.com)
* Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
#include <linux/init.h>
#include <asm/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)
{
prom_printf("[%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);
prom_printf("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 */
/* /*
* sgialib.h: SGI ARCS firmware interface library for the Linux kernel. * 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.
*
* SGI ARCS firmware interface library for the Linux kernel.
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 2001, 2002 Ralf Baechle (ralf@gnu.org)
*/ */
#ifndef _ASM_SGIALIB_H #ifndef _ASM_SGIALIB_H
#define _ASM_SGIALIB_H #define _ASM_SGIALIB_H
#include <asm/sgiarcs.h> #include <asm/sgiarcs.h>
extern struct linux_promblock *sgi_pblock;
extern struct linux_romvec *romvec; extern struct linux_romvec *romvec;
extern int prom_argc; extern int prom_argc;
extern char **prom_argv, **prom_envp;
extern LONG *_prom_argv, *_prom_envp;
/* A 32-bit ARC PROM pass arguments and environment as 32-bit pointer.
These macros take care of sign extension. */
#define prom_argv(index) ((char *) (long) _prom_argv[(index)])
#define prom_argc(index) ((char *) (long) _prom_argc[(index)])
extern int prom_flags; extern int prom_flags;
#define PROM_FLAG_ARCS 1 #define PROM_FLAG_ARCS 1
#define PROM_FLAG_USE_AS_CONSOLE 2
/* /* Init the PROM library and it's internal data structures. */
* Init the PROM library and it's internal data structures. Called
* at boot time from head.S before start_kernel is invoked.
*/
extern void prom_init(int argc, char **argv, char **envp, int *prom_vec); extern void prom_init(int argc, char **argv, char **envp, int *prom_vec);
/* Simple char-by-char console I/O. */ /* Simple char-by-char console I/O. */
...@@ -29,21 +37,34 @@ extern char prom_getchar(void); ...@@ -29,21 +37,34 @@ extern char prom_getchar(void);
/* Generic printf() using ARCS console I/O. */ /* Generic printf() using ARCS console I/O. */
extern void prom_printf(char *fmt, ...); extern void prom_printf(char *fmt, ...);
/* Memory descriptor management. */
#define PROM_MAX_PMEMBLOCKS 32
struct prom_pmemblock {
LONG base; /* Within KSEG0 or XKPHYS. */
ULONG size; /* In bytes. */
ULONG type; /* free or prom memory */
};
/* Get next memory descriptor after CURR, returns first descriptor
* in chain is CURR is NULL.
*/
extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr);
#define PROM_NULL_MDESC ((struct linux_mdesc *) 0) #define PROM_NULL_MDESC ((struct linux_mdesc *) 0)
/* Called by prom_init to setup the physical memory pmemblock /* Called by prom_init to setup the physical memory pmemblock
* array. * array.
*/ */
extern void prom_meminit(void); extern void prom_meminit(void);
extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
/* PROM device tree library routines. */ /* PROM device tree library routines. */
#define PROM_NULL_COMPONENT ((pcomponent *) 0) #define PROM_NULL_COMPONENT ((pcomponent *) 0)
/* Get sibling component of THIS. */ /* Get sibling component of THIS. */
extern pcomponent *prom_getsibling(pcomponent *this); extern pcomponent *ArcGetPeer(pcomponent *this);
/* Get child component of THIS. */ /* Get child component of THIS. */
extern pcomponent *prom_getchild(pcomponent *this); extern pcomponent *ArcGetChild(pcomponent *this);
/* Get parent component of CHILD. */ /* Get parent component of CHILD. */
extern pcomponent *prom_getparent(pcomponent *child); extern pcomponent *prom_getparent(pcomponent *child);
...@@ -65,7 +86,7 @@ extern pcomponent *prom_componentbypath(char *path); ...@@ -65,7 +86,7 @@ extern pcomponent *prom_componentbypath(char *path);
extern void prom_identify_arch(void); extern void prom_identify_arch(void);
/* Environment variable routines. */ /* Environment variable routines. */
extern PCHAR ArcGetEnvironmentVariable(CHAR *name); extern PCHAR ArcGetEnvironmentVariable(PCHAR name);
extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value); extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value);
/* ARCS command line acquisition and parsing. */ /* ARCS command line acquisition and parsing. */
...@@ -80,9 +101,9 @@ extern unsigned long prom_getrtime(void); ...@@ -80,9 +101,9 @@ extern unsigned long prom_getrtime(void);
extern long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt); extern long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt);
extern long prom_open(char *name, enum linux_omode md, unsigned long *fd); extern long prom_open(char *name, enum linux_omode md, unsigned long *fd);
extern long prom_close(unsigned long fd); extern long prom_close(unsigned long fd);
extern long prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt); extern LONG ArcRead(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
extern long prom_getrstatus(unsigned long fd); extern long prom_getrstatus(unsigned long fd);
extern long prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt); extern LONG ArcWrite(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
extern long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm); extern long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm);
extern long prom_mount(char *name, enum linux_mountops op); extern long prom_mount(char *name, enum linux_mountops op);
extern long prom_getfinfo(unsigned long fd, struct linux_finfo *buf); extern long prom_getfinfo(unsigned long fd, struct linux_finfo *buf);
...@@ -94,13 +115,13 @@ extern long prom_invoke(unsigned long pc, unsigned long sp, long argc, char **ar ...@@ -94,13 +115,13 @@ extern long prom_invoke(unsigned long pc, unsigned long sp, long argc, char **ar
extern long prom_exec(char *name, long argc, char **argv, char **envp); extern long prom_exec(char *name, long argc, char **argv, char **envp);
/* Misc. routines. */ /* Misc. routines. */
extern void prom_halt(void) __attribute__((noreturn)); extern VOID prom_halt(VOID) __attribute__((noreturn));
extern void prom_powerdown(void) __attribute__((noreturn)); extern VOID prom_powerdown(VOID) __attribute__((noreturn));
extern void prom_restart(void) __attribute__((noreturn)); extern VOID prom_restart(VOID) __attribute__((noreturn));
extern void prom_reboot(void) __attribute__((noreturn)); extern VOID ArcReboot(VOID) __attribute__((noreturn));
extern void ArcEnterInteractiveMode(void) __attribute__((noreturn)); extern VOID ArcEnterInteractiveMode(VOID) __attribute__((noreturn));
extern long prom_cfgsave(void); extern long prom_cfgsave(VOID);
extern struct linux_sysid *prom_getsysid(void); extern struct linux_sysid *prom_getsysid(VOID);
extern void prom_cacheflush(void); extern VOID ArcFlushAllCaches(VOID);
#endif /* _ASM_SGIALIB_H */ #endif /* _ASM_SGIALIB_H */
/* $Id: sgiarcs.h,v 1.3 1999/02/25 20:55:08 tsbogend Exp $ /*
* 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.
* *
* SGI ARCS firmware interface defines. * ARC firmware interface defines.
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1999, 2001 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc.
*/ */
#ifndef _ASM_SGIARCS_H #ifndef _ASM_SGIARCS_H
#define _ASM_SGIARCS_H #define _ASM_SGIARCS_H
#include <linux/config.h>
#include <asm/types.h>
#include <asm/arc/types.h> #include <asm/arc/types.h>
/* Various ARCS error codes. */ /* Various ARCS error codes. */
...@@ -74,13 +81,13 @@ struct linux_component { ...@@ -74,13 +81,13 @@ struct linux_component {
enum linux_devclass class; /* node class */ enum linux_devclass class; /* node class */
enum linux_devtypes type; /* node type */ enum linux_devtypes type; /* node type */
enum linux_identifier iflags; /* node flags */ enum linux_identifier iflags; /* node flags */
unsigned short vers; /* node version */ USHORT vers; /* node version */
unsigned short rev; /* node revision */ USHORT rev; /* node revision */
unsigned long key; /* completely magic */ ULONG key; /* completely magic */
unsigned long amask; /* XXX affinity mask??? */ ULONG amask; /* XXX affinity mask??? */
unsigned long cdsize; /* size of configuration data */ ULONG cdsize; /* size of configuration data */
unsigned long ilen; /* length of string identifier */ ULONG ilen; /* length of string identifier */
char *iname; /* string identifier */ _PULONG iname; /* string identifier */
}; };
typedef struct linux_component pcomponent; typedef struct linux_component pcomponent;
...@@ -119,8 +126,8 @@ union linux_memtypes { ...@@ -119,8 +126,8 @@ union linux_memtypes {
struct linux_mdesc { struct linux_mdesc {
union linux_memtypes type; union linux_memtypes type;
unsigned long base; ULONG base;
unsigned long pages; ULONG pages;
}; };
/* Time of day descriptor. */ /* Time of day descriptor. */
...@@ -136,7 +143,7 @@ struct linux_tinfo { ...@@ -136,7 +143,7 @@ struct linux_tinfo {
/* ARCS virtual dirents. */ /* ARCS virtual dirents. */
struct linux_vdirent { struct linux_vdirent {
unsigned long namelen; ULONG namelen;
unsigned char attr; unsigned char attr;
char fname[32]; /* XXX imperical, should be a define */ char fname[32]; /* XXX imperical, should be a define */
}; };
...@@ -158,11 +165,11 @@ enum linux_mountops { ...@@ -158,11 +165,11 @@ enum linux_mountops {
/* This prom has a bolixed design. */ /* This prom has a bolixed design. */
struct linux_bigint { struct linux_bigint {
#ifdef __MIPSEL__ #ifdef __MIPSEL__
unsigned long lo; u32 lo;
long hi; s32 hi;
#else /* !(__MIPSEL__) */ #else /* !(__MIPSEL__) */
long hi; s32 hi;
unsigned long lo; u32 lo;
#endif #endif
}; };
...@@ -176,104 +183,91 @@ struct linux_finfo { ...@@ -176,104 +183,91 @@ struct linux_finfo {
char name[32]; /* XXX imperical, should be define */ char name[32]; /* XXX imperical, should be define */
}; };
/* This describes the vector containing function pointers to the ARC
firmware functions. */
struct linux_romvec { struct linux_romvec {
/* Load an executable image. */ LONG load; /* Load an executable image. */
long (*load)(char *file, unsigned long end, LONG invoke; /* Invoke a standalong image. */
unsigned long *start_pc, LONG exec; /* Load and begin execution of a
unsigned long *end_addr); standalone image. */
LONG halt; /* Halt the machine. */
/* Invoke a standalong image. */ LONG pdown; /* Power down the machine. */
long (*invoke)(unsigned long startpc, unsigned long sp, LONG restart; /* XXX soft reset??? */
long argc, char **argv, char **envp); LONG reboot; /* Reboot the machine. */
LONG imode; /* Enter PROM interactive mode. */
/* Load and begin execution of a standalong image. */ LONG _unused1; /* Was ReturnFromMain(). */
long (*exec)(char *file, long argc, char **argv, char **envp);
void (*halt)(void) __attribute__((noreturn)); /* Halt the machine. */
void (*pdown)(void) __attribute__((noreturn)); /* Power down the machine. */
void (*restart)(void) __attribute__((noreturn)); /* XXX soft reset??? */
void (*reboot)(void) __attribute__((noreturn)); /* Reboot the machine. */
void (*imode)(void) __attribute__((noreturn)); /* Enter PROM interactive mode. */
int _unused1; /* padding */
/* PROM device tree interface. */ /* PROM device tree interface. */
pcomponent *(*next_component)(pcomponent *this); LONG next_component;
pcomponent *(*child_component)(pcomponent *this); LONG child_component;
pcomponent *(*parent_component)(pcomponent *this); LONG parent_component;
long (*component_data)(void *opaque_data, pcomponent *this); LONG component_data;
pcomponent *(*child_add)(pcomponent *this, LONG child_add;
pcomponent *tmp, LONG comp_del;
void *opaque_data); LONG component_by_path;
long (*comp_del)(pcomponent *this);
pcomponent *(*component_by_path)(char *file);
/* Misc. stuff. */ /* Misc. stuff. */
long (*cfg_save)(void); LONG cfg_save;
struct linux_sysid *(*get_sysid)(void); LONG get_sysid;
/* Probing for memory. */ /* Probing for memory. */
struct linux_mdesc *(*get_mdesc)(struct linux_mdesc *curr); LONG get_mdesc;
long _unused2; /* padding */ LONG _unused2; /* was Signal() */
struct linux_tinfo *(*get_tinfo)(void); LONG get_tinfo;
unsigned long (*get_rtime)(void); LONG get_rtime;
/* File type operations. */ /* File type operations. */
long (*get_vdirent)(unsigned long fd, struct linux_vdirent *entry, LONG get_vdirent;
unsigned long num, unsigned long *count); LONG open;
long (*open)(char *file, enum linux_omode mode, unsigned long *fd); LONG close;
long (*close)(unsigned long fd); LONG read;
long (*read)(unsigned long fd, void *buffer, unsigned long num, LONG get_rstatus;
unsigned long *count); LONG write;
long (*get_rstatus)(unsigned long fd); LONG seek;
long (*write)(unsigned long fd, void *buffer, unsigned long num, LONG mount;
unsigned long *count);
long (*seek)(unsigned long fd, struct linux_bigint *offset,
enum linux_seekmode smode);
long (*mount)(char *file, enum linux_mountops op);
/* Dealing with firmware environment variables. */ /* Dealing with firmware environment variables. */
PCHAR (*get_evar)(CHAR *name); LONG get_evar;
LONG (*set_evar)(PCHAR name, PCHAR value); LONG set_evar;
long (*get_finfo)(unsigned long fd, struct linux_finfo *buf); LONG get_finfo;
long (*set_finfo)(unsigned long fd, unsigned long flags, LONG set_finfo;
unsigned long mask);
/* Miscellaneous. */ /* Miscellaneous. */
void (*cache_flush)(void); LONG cache_flush;
}; };
/* The SGI ARCS parameter block is in a fixed location for standalone /* The SGI ARCS parameter block is in a fixed location for standalone
* programs to access PROM facilities easily. * programs to access PROM facilities easily.
*/ */
struct linux_promblock { typedef struct _SYSTEM_PARAMETER_BLOCK {
long magic; /* magic cookie */ ULONG magic; /* magic cookie */
#define PROMBLOCK_MAGIC 0x53435241 #define PROMBLOCK_MAGIC 0x53435241
unsigned long len; /* length of parm block */ ULONG len; /* length of parm block */
unsigned short ver; /* ARCS firmware version */ USHORT ver; /* ARCS firmware version */
unsigned short rev; /* ARCS firmware revision */ USHORT rev; /* ARCS firmware revision */
long *rs_block; /* Restart block. */ _PLONG rs_block; /* Restart block. */
long *dbg_block; /* Debug block. */ _PLONG dbg_block; /* Debug block. */
long *gevect; /* XXX General vector??? */ _PLONG gevect; /* XXX General vector??? */
long *utlbvect; /* XXX UTLB vector??? */ _PLONG utlbvect; /* XXX UTLB vector??? */
unsigned long rveclen; /* Size of romvec struct. */ ULONG rveclen; /* Size of romvec struct. */
struct linux_romvec *romvec; /* Function interface. */ _PVOID romvec; /* Function interface. */
unsigned long pveclen; /* Length of private vector. */ ULONG pveclen; /* Length of private vector. */
long *pvector; /* Private vector. */ _PVOID pvector; /* Private vector. */
long adap_cnt; /* Adapter count. */ ULONG adap_cnt; /* Adapter count. */
long adap_typ0; /* First adapter type. */ ULONG adap_typ0; /* First adapter type. */
long adap_vcnt0; /* Adapter 0 vector count. */ ULONG adap_vcnt0; /* Adapter 0 vector count. */
long *adap_vector; /* Adapter 0 vector ptr. */ _PVOID adap_vector; /* Adapter 0 vector ptr. */
long adap_typ1; /* Second adapter type. */ ULONG adap_typ1; /* Second adapter type. */
long adap_vcnt1; /* Adapter 1 vector count. */ ULONG adap_vcnt1; /* Adapter 1 vector count. */
long *adap_vector1; /* Adapter 1 vector ptr. */ _PVOID adap_vector1; /* Adapter 1 vector ptr. */
/* More adapter vectors go here... */ /* More adapter vectors go here... */
}; } SYSTEM_PARAMETER_BLOCK, *PSYSTEM_PARAMETER_BLOCK;
#define PROMBLOCK ((struct linux_promblock *)0xA0001000UL) #define PROMBLOCK ((PSYSTEM_PARAMETER_BLOCK) (int)0xA0001000)
#define ROMVECTOR ((PROMBLOCK)->romvec) #define ROMVECTOR ((struct linux_romvec *) (long)(PROMBLOCK)->romvec)
/* Cache layout parameter block. */ /* Cache layout parameter block. */
union linux_cache_key { union linux_cache_key {
...@@ -367,4 +361,187 @@ struct linux_smonblock { ...@@ -367,4 +361,187 @@ struct linux_smonblock {
int smax; /* Max # of symbols. */ int smax; /* Max # of symbols. */
}; };
/*
* Macros for calling a 32-bit ARC implementation from 64-bit code
*/
#if defined(CONFIG_MIPS64) && defined(CONFIG_ARC32)
#define __arc_clobbers \
"$2","$3" /* ... */, "$8","$9","$10","$11", \
"$12","$13","$14","$15","$16","$24","25","$31"
#define ARC_CALL0(dest) \
({ long __res; \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec) \
: __arc_clobbers, "$4","$5","$6","$7"); \
(unsigned long) __res; \
})
#define ARC_CALL1(dest,a1) \
({ long __res; \
register signed int __a1 __asm__("$4") = (int) (long) (a1); \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1) \
: __arc_clobbers, "$5","$6","$7"); \
(unsigned long) __res; \
})
#define ARC_CALL2(dest,a1,a2) \
({ long __res; \
register signed int __a1 __asm__("$4") = (int) (long) (a1); \
register signed int __a2 __asm__("$5") = (int) (long) (a2); \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1), "r" (__a2) \
: __arc_clobbers, "$6","$7"); \
__res; \
})
#define ARC_CALL3(dest,a1,a2,a3) \
({ long __res; \
register signed int __a1 __asm__("$4") = (int) (long) (a1); \
register signed int __a2 __asm__("$5") = (int) (long) (a2); \
register signed int __a3 __asm__("$6") = (int) (long) (a3); \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3) \
: __arc_clobbers, "$7"); \
__res; \
})
#define ARC_CALL4(dest,a1,a2,a3,a4) \
({ long __res; \
register signed int __a1 __asm__("$4") = (int) (long) (a1); \
register signed int __a2 __asm__("$5") = (int) (long) (a2); \
register signed int __a3 __asm__("$6") = (int) (long) (a3); \
register signed int __a4 __asm__("$7") = (int) (long) (a4); \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3), \
"r" (__a4) \
: __arc_clobbers); \
__res; \
})
#define ARC_CALL5(dest,a1,a2,a3,a4,a5) \
({ long __res; \
register signed int __a1 __asm__("$4") = (int) (long) (a1); \
register signed int __a2 __asm__("$5") = (int) (long) (a2); \
register signed int __a3 __asm__("$6") = (int) (long) (a3); \
register signed int __a4 __asm__("$7") = (int) (long) (a4); \
register signed int __a5 = (a5); \
long __vec = (long) romvec->dest; \
__asm__ __volatile__( \
"dsubu\t$29, 32\n\t" \
"sw\t%6, 16($29)\n\t" \
"jalr\t%1\n\t" \
"daddu\t$29, 32\n\t" \
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), \
"r" (__a1), "r" (__a2), "r" (__a3), "r" (__a4), \
"r" (__a5) \
: __arc_clobbers); \
__res; \
})
#endif /* defined(CONFIG_MIPS64) && defined(CONFIG_ARC32) */
#if (defined(CONFIG_MIPS32) && defined(CONFIG_ARC32)) || \
(defined(CONFIG_MIPS64) && defined(CONFIG_ARC64))
#define ARC_CALL0(dest) \
({ long __res; \
long (*__vec)(void) = (void *) romvec->dest; \
\
__res = __vec(); \
__res; \
})
#define ARC_CALL1(dest,a1) \
({ long __res; \
long __a1 = (long) (a1); \
long (*__vec)(long) = (void *) romvec->dest; \
\
__res = __vec(__a1); \
__res; \
})
#define ARC_CALL2(dest,a1,a2) \
({ long __res; \
long __a1 = (long) (a1); \
long __a2 = (long) (a2); \
long (*__vec)(long, long) = (void *) romvec->dest; \
\
__res = __vec(__a1, __a2); \
__res; \
})
#define ARC_CALL3(dest,a1,a2,a3) \
({ long __res; \
long __a1 = (long) (a1); \
long __a2 = (long) (a2); \
long __a3 = (long) (a3); \
long (*__vec)(long, long, long) = (void *) romvec->dest; \
\
__res = __vec(__a1, __a2, __a3); \
__res; \
})
#define ARC_CALL4(dest,a1,a2,a3,a4) \
({ long __res; \
long __a1 = (long) (a1); \
long __a2 = (long) (a2); \
long __a3 = (long) (a3); \
long __a4 = (long) (a4); \
long (*__vec)(long, long, long, long) = (void *) romvec->dest; \
\
__res = __vec(__a1, __a2, __a3, __a4); \
__res; \
})
#define ARC_CALL5(dest,a1,a2,a3,a4,a5) \
({ long __res; \
long __a1 = (long) (a1); \
long __a2 = (long) (a2); \
long __a3 = (long) (a3); \
long __a4 = (long) (a4); \
long __a5 = (long) (a5); \
long (*__vec)(long, long, long, long, long); \
__vec = (void *) romvec->dest; \
\
__res = __vec(__a1, __a2, __a3, __a4, __a5); \
__res; \
})
#endif /* both kernel and ARC either 32-bit or 64-bit */
#endif /* _ASM_SGIARCS_H */ #endif /* _ASM_SGIARCS_H */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* SGI ARCS firmware interface library for the Linux kernel. * SGI ARCS firmware interface library for the Linux kernel.
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 2001 Ralf Baechle (ralf@gnu.org) * Copyright (C) 2001, 2002 Ralf Baechle (ralf@gnu.org)
*/ */
#ifndef _ASM_SGIALIB_H #ifndef _ASM_SGIALIB_H
#define _ASM_SGIALIB_H #define _ASM_SGIALIB_H
...@@ -25,11 +25,10 @@ extern LONG *_prom_argv, *_prom_envp; ...@@ -25,11 +25,10 @@ extern LONG *_prom_argv, *_prom_envp;
extern int prom_flags; extern int prom_flags;
#define PROM_FLAG_ARCS 1 #define PROM_FLAG_ARCS 1
#define PROM_FLAG_USE_AS_CONSOLE 2
/* Init the PROM library and it's internal data structures. Called /* Init the PROM library and it's internal data structures. */
* at boot time from head.S before start_kernel is invoked. extern void prom_init(int argc, char **argv, char **envp, int *prom_vec);
*/
extern int prom_init(int argc, char **argv, char **envp);
/* Simple char-by-char console I/O. */ /* Simple char-by-char console I/O. */
extern void prom_putchar(char c); extern void prom_putchar(char c);
...@@ -58,9 +57,6 @@ extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr); ...@@ -58,9 +57,6 @@ extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr);
extern void prom_meminit(void); extern void prom_meminit(void);
extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
/* Returns pointer to PROM physical memory block array. */
extern struct prom_pmemblock *prom_getpblock_array(void);
/* PROM device tree library routines. */ /* PROM device tree library routines. */
#define PROM_NULL_COMPONENT ((pcomponent *) 0) #define PROM_NULL_COMPONENT ((pcomponent *) 0)
......
...@@ -6,13 +6,14 @@ ...@@ -6,13 +6,14 @@
* ARC firmware interface defines. * ARC firmware interface defines.
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999, 2001 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 1999 Silicon Graphics, Inc.
*/ */
#ifndef _ASM_SGIARCS_H #ifndef _ASM_SGIARCS_H
#define _ASM_SGIARCS_H #define _ASM_SGIARCS_H
#include <linux/config.h> #include <linux/config.h>
#include <asm/types.h>
#include <asm/arc/types.h> #include <asm/arc/types.h>
/* Various ARCS error codes. */ /* Various ARCS error codes. */
...@@ -164,11 +165,11 @@ enum linux_mountops { ...@@ -164,11 +165,11 @@ enum linux_mountops {
/* This prom has a bolixed design. */ /* This prom has a bolixed design. */
struct linux_bigint { struct linux_bigint {
#ifdef __MIPSEL__ #ifdef __MIPSEL__
unsigned long lo; u32 lo;
long hi; s32 hi;
#else /* !(__MIPSEL__) */ #else /* !(__MIPSEL__) */
long hi; s32 hi;
unsigned long lo; u32 lo;
#endif #endif
}; };
...@@ -364,9 +365,10 @@ struct linux_smonblock { ...@@ -364,9 +365,10 @@ struct linux_smonblock {
* Macros for calling a 32-bit ARC implementation from 64-bit code * Macros for calling a 32-bit ARC implementation from 64-bit code
*/ */
#ifdef CONFIG_ARC32 #if defined(CONFIG_MIPS64) && defined(CONFIG_ARC32)
#define __arc_clobbers \ #define __arc_clobbers \
"$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ "$2","$3" /* ... */, "$8","$9","$10","$11", \
"$12","$13","$14","$15","$16","$24","25","$31" "$12","$13","$14","$15","$16","$24","25","$31"
#define ARC_CALL0(dest) \ #define ARC_CALL0(dest) \
...@@ -379,7 +381,7 @@ struct linux_smonblock { ...@@ -379,7 +381,7 @@ struct linux_smonblock {
"move\t%0, $2" \ "move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \ : "=r" (__res), "=r" (__vec) \
: "1" (__vec) \ : "1" (__vec) \
: __arc_clobbers); \ : __arc_clobbers, "$4","$5","$6","$7"); \
(unsigned long) __res; \ (unsigned long) __res; \
}) })
...@@ -394,7 +396,7 @@ struct linux_smonblock { ...@@ -394,7 +396,7 @@ struct linux_smonblock {
"move\t%0, $2" \ "move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \ : "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1) \ : "1" (__vec), "r" (__a1) \
: __arc_clobbers); \ : __arc_clobbers, "$5","$6","$7"); \
(unsigned long) __res; \ (unsigned long) __res; \
}) })
...@@ -410,7 +412,7 @@ struct linux_smonblock { ...@@ -410,7 +412,7 @@ struct linux_smonblock {
"move\t%0, $2" \ "move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \ : "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1), "r" (__a2) \ : "1" (__vec), "r" (__a1), "r" (__a2) \
: __arc_clobbers); \ : __arc_clobbers, "$6","$7"); \
__res; \ __res; \
}) })
...@@ -427,7 +429,7 @@ struct linux_smonblock { ...@@ -427,7 +429,7 @@ struct linux_smonblock {
"move\t%0, $2" \ "move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \ : "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3) \ : "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3) \
: __arc_clobbers); \ : __arc_clobbers, "$7"); \
__res; \ __res; \
}) })
...@@ -471,9 +473,11 @@ struct linux_smonblock { ...@@ -471,9 +473,11 @@ struct linux_smonblock {
: __arc_clobbers); \ : __arc_clobbers); \
__res; \ __res; \
}) })
#endif /* CONFIG_ARC32 */
#ifdef CONFIG_ARC64 #endif /* defined(CONFIG_MIPS64) && defined(CONFIG_ARC32) */
#if (defined(CONFIG_MIPS32) && defined(CONFIG_ARC32)) || \
(defined(CONFIG_MIPS64) && defined(CONFIG_ARC64))
#define ARC_CALL0(dest) \ #define ARC_CALL0(dest) \
({ long __res; \ ({ long __res; \
...@@ -538,6 +542,6 @@ struct linux_smonblock { ...@@ -538,6 +542,6 @@ struct linux_smonblock {
__res = __vec(__a1, __a2, __a3, __a4, __a5); \ __res = __vec(__a1, __a2, __a3, __a4, __a5); \
__res; \ __res; \
}) })
#endif /* CONFIG_ARC64 */ #endif /* both kernel and ARC either 32-bit or 64-bit */
#endif /* _ASM_SGIARCS_H */ #endif /* _ASM_SGIARCS_H */
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