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
# under Linux.
# Makefile for the ARC prom monitor library routines under Linux.
#
lib-y += console.o init.o memory.o tree.o env.o cmdline.o misc.o \
time.o file.o identify.o
lib-y += cmdline.o env.o file.o identify.o init.o \
misc.o time.o tree.o
lib-$(CONFIG_ARC_CONSOLE) += arc_con.o
lib-$(CONFIG_ARC_MEMORY) += memory.o
lib-$(CONFIG_ARC_CONSOLE) += arc_con.o
lib-$(CONFIG_ARC_PROMLIB) += promlib.o
......@@ -2,69 +2,49 @@
* Wrap-around code for a console using the
* 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/major.h>
#include <linux/ptrace.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/fs.h>
extern char prom_getchar (void);
extern void prom_printf (char *, ...);
#include <asm/sgialib.h>
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++);
/* Do each character */
while (count--) {
if (*s == '\n')
prom_putchar('\r');
prom_putchar(*s++);
}
}
static int prom_console_wait_key(struct console *co)
{
return prom_getchar();
}
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);
return !(prom_flags & PROM_FLAG_USE_AS_CONSOLE);
}
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
.name = "arc",
.write = prom_console_write,
.setup = prom_console_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
};
/*
* Register console.
*/
static void __init arc_console_init(void)
static int __init arc_console_init(void)
{
register_console(&arc_cons);
return 0;
}
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.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
......@@ -12,11 +16,11 @@
#undef DEBUG_CMDLINE
char arcs_cmdline[COMMAND_LINE_SIZE];
char arcs_cmdline[CL_SIZE];
char * __init prom_getcmdline(void)
{
return &(arcs_cmdline[0]);
return arcs_cmdline;
}
static char *ignored[] = {
......@@ -28,7 +32,6 @@ static char *ignored[] = {
"OSLoadFilename=",
"OSLoadOptions="
};
#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0])))))
static char *used_arc[][2] = {
{ "OSLoadPartition=", "root=" },
......@@ -43,16 +46,16 @@ static char * __init move_firmware_args(char* cp)
actr = 1; /* Always ignore argv[0] */
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]);
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... */
strcat(cp, used_arc[i][1]);
cp += strlen(used_arc[i][1]);
/* ... and now the argument */
s = strstr(prom_argv[actr], "=");
if(s) {
s = strstr(prom_argv(actr), "=");
if (s) {
s++;
strcpy(cp, s);
cp += strlen(s);
......@@ -67,7 +70,6 @@ static char * __init move_firmware_args(char* cp)
return cp;
}
void __init prom_init_cmdline(void)
{
char *cp;
......@@ -75,33 +77,34 @@ void __init prom_init_cmdline(void)
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
* overridden by later arguments.
*/
cp = move_firmware_args(cp);
while (actr < prom_argc) {
for (i = 0; i < NENTS(ignored); i++) {
for (i = 0; i < ARRAY_SIZE(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;
}
/* Ok, we want it. */
strcpy(cp, prom_argv[actr]);
cp += strlen(prom_argv[actr]);
strcpy(cp, prom_argv(actr));
cp += strlen(prom_argv(actr));
*cp++ = ' ';
pic_cont:
actr++;
}
if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
if (cp != arcs_cmdline) /* get rid of trailing space */
--cp;
*cp = '\0';
#ifdef DEBUG_CMDLINE
prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0]));
printk(KERN_DEBUG "prom cmdline: %s\n", arcs_cmdline);
#endif
}
......@@ -6,14 +6,9 @@
* Copyright (C) 1996 David S. Miller (dm@sgi.com)
* Compability with board caches, Ulf Carlsson
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/sgialib.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
......@@ -27,44 +22,42 @@
void prom_putchar(char c)
{
long cnt;
char it = c;
ULONG cnt;
CHAR it = c;
bc_disable();
romvec->write(1, &it, 1, &cnt);
ArcWrite(1, &it, 1, &cnt);
bc_enable();
}
char __init prom_getchar(void)
char prom_getchar(void)
{
long cnt;
char c;
ULONG cnt;
CHAR c;
bc_disable();
romvec->read(0, &c, 1, &cnt);
ArcRead(0, &c, 1, &cnt);
bc_enable();
return c;
}
static char ppbuf[1024];
void prom_printf(char *fmt, ...)
{
va_list args;
char ch, *bptr;
int i;
char ppbuf[1024];
char *bptr;
va_start(args, fmt);
i = vsprintf(ppbuf, fmt, args);
vsprintf(ppbuf, fmt, args);
bptr = ppbuf;
while ((ch = *(bptr++)) != 0) {
if (ch == '\n')
while (*bptr != 0) {
if (*bptr == '\n')
prom_putchar('\r');
prom_putchar(ch);
prom_putchar(*bptr++);
}
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.
*
* 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/kernel.h>
#include <linux/string.h>
#include <asm/arc/types.h>
#include <asm/sgialib.h>
PCHAR __init
ArcGetEnvironmentVariable(CHAR *name)
{
return romvec->get_evar(name);
return (CHAR *) ARC_CALL1(get_evar, name);
}
LONG __init
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 <asm/arc/types.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
*
* 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/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
#include <asm/sgi/sgi.h>
#include <asm/sgialib.h>
#include <asm/bootinfo.h>
struct smatch {
char *name;
char *arcname;
char *liname;
int group;
int type;
int flags;
};
static struct smatch mach_table[] = {
{"SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, 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}
{ "SGI-IP22",
"SGI Indy",
MACH_GROUP_SGI,
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;
static struct smatch *__init string_to_mach(char *s)
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))
if (!strcmp(s, mach_table[i].arcname))
return &mach_table[i];
}
prom_printf("\nYeee, could not determine architecture type <%s>\n",
s);
prom_printf("press a key to reboot\n");
prom_getchar();
romvec->imode();
return NULL;
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.
* The root component tells us what machine architecture we have here.
*/
p = prom_getchild(PROM_NULL_COMPONENT);
printk("ARCH: %s\n", p->iname);
mach = string_to_mach(p->iname);
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;
mips_machgroup = mach->group;
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
* for more details.
*
......@@ -16,38 +16,17 @@
/* Master romvec interface. */
struct linux_romvec *romvec;
struct linux_promblock *sgi_pblock;
int prom_argc;
char **prom_argv, **prom_envp;
unsigned short prom_vers, prom_rev;
extern void prom_testtree(void);
extern void arc_setup_console(void);
LONG *_prom_argv, *_prom_envp;
void __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
{
struct linux_promblock *pb;
PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
romvec = ROMVECTOR;
pb = sgi_pblock = PROMBLOCK;
prom_argc = argc;
prom_argv = argv;
prom_envp = 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.
*/
_prom_argv = (LONG *) argv;
_prom_envp = (LONG *) envp;
arc_setup_console();
#endif
if (pb->magic != 0x53435241) {
prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic);
while(1)
......@@ -55,19 +34,14 @@ void __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
}
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);
printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n",
pb->ver, pb->rev);
prom_meminit();
#ifdef DEBUG_PROM_INIT
{
prom_printf("Press a key to reboot\n");
(void) prom_getchar();
romvec->imode();
}
prom_printf("Press a key to reboot\n");
prom_getchar();
ArcEnterInteractiveMode();
#endif
}
......@@ -2,7 +2,14 @@
* memory.c: PROM library functions for acquiring/using memory descriptors
* 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/kernel.h>
......@@ -19,10 +26,9 @@
#undef DEBUG
struct linux_mdesc * __init
ArcGetMemoryDescriptor(struct linux_mdesc *Current)
struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
{
return romvec->get_mdesc(Current);
return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
}
#ifdef DEBUG /* convenient for debugging */
......@@ -47,7 +53,8 @@ static char *arc_mtypes[8] = {
"FirmwarePermanent",
"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
static inline int memtype_classify_arcs (union linux_memtypes type)
......@@ -92,7 +99,7 @@ static inline int memtype_classify_arc (union linux_memtypes type)
static int __init prom_memtype_classify (union linux_memtypes type)
{
if (prom_flags & PROM_FLAG_ARCS) /* SGI is ``different'' ... */
if (prom_flags & PROM_FLAG_ARCS) /* SGI is ``different'' ... */
return memtype_classify_arcs(type);
return memtype_classify_arc(type);
......@@ -128,8 +135,7 @@ void __init prom_meminit(void)
}
}
void __init
prom_free_prom_memory (void)
void __init prom_free_prom_memory (void)
{
unsigned long freed = 0;
unsigned long addr;
......@@ -149,5 +155,5 @@ prom_free_prom_memory (void)
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) 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>
......@@ -15,68 +23,81 @@
extern void *sgiwd93_host;
extern void reset_wd33c93(void *instance);
void prom_halt(void)
VOID
ArcHalt(VOID)
{
bc_disable();
cli();
local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
romvec->halt();
ARC_CALL0(halt);
never: goto never;
}
void prom_powerdown(void)
VOID
ArcPowerDown(VOID)
{
bc_disable();
cli();
local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
romvec->pdown();
ARC_CALL0(pdown);
never: goto never;
}
/* XXX is this a soft reset basically? XXX */
void prom_restart(void)
VOID
ArcRestart(VOID)
{
bc_disable();
cli();
local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
romvec->restart();
ARC_CALL0(restart);
never: goto never;
}
void prom_reboot(void)
VOID
ArcReboot(VOID)
{
bc_disable();
cli();
local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
romvec->reboot();
ARC_CALL0(reboot);
never: goto never;
}
void ArcEnterInteractiveMode(void)
VOID
ArcEnterInteractiveMode(VOID)
{
bc_disable();
cli();
local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#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 @@
* for more details.
*
* Copyright (C) 1996 David S. Miller (dm@sgi.com)
* Compability with board caches, Ulf Carlsson
*/
#include <linux/init.h>
#include <linux/kernel.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;
char ch, *bptr;
int i;
ULONG cnt;
CHAR it = c;
va_start(args, fmt);
i = vsprintf(ppbuf, fmt, args);
bc_disable();
ArcWrite(1, &it, 1, &cnt);
bc_enable();
}
bptr = ppbuf;
char prom_getchar(void)
{
ULONG cnt;
CHAR c;
while((ch = *(bptr++)) != 0) {
if(ch == '\n')
prom_putchar('\r');
bc_disable();
ArcRead(0, &c, 1, &cnt);
bc_enable();
prom_putchar(ch);
}
va_end(args);
return;
return c;
}
/*
* salone.c: Routines to load into memory and execute stand-along
* program images using ARCS PROM firmware.
* 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)
*
* $Id: salone.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $
*/
#include <linux/init.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 <asm/arc/types.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 <asm/arc/types.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 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 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
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"
"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[] = {
......@@ -74,7 +90,8 @@ static char *iflags[] = {
"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>",
p, classes[p->class], types[p->type],
......@@ -83,27 +100,28 @@ static void __init dump_component(pcomponent *p)
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);
if(prom_getchild(p))
traverse(prom_getchild(p), 1);
if(prom_getsibling(p) && op)
traverse(prom_getsibling(p), 1);
if(ArcGetChild(p))
traverse(ArcGetChild(p), 1);
if(ArcGetPeer(p) && op)
traverse(ArcGetPeer(p), 1);
}
void __init prom_testtree(void)
void __init
prom_testtree(void)
{
pcomponent *p;
p = prom_getchild(PROM_NULL_COMPONENT);
p = ArcGetChild(PROM_NULL_COMPONENT);
dump_component(p);
p = prom_getchild(p);
p = ArcGetChild(p);
while(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) 2001, 2002 Ralf Baechle (ralf@gnu.org)
*/
#ifndef _ASM_SGIALIB_H
#define _ASM_SGIALIB_H
#include <asm/sgiarcs.h>
extern struct linux_promblock *sgi_pblock;
extern struct linux_romvec *romvec;
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;
#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
* at boot time from head.S before start_kernel is invoked.
*/
/* Init the PROM library and it's internal data structures. */
extern void prom_init(int argc, char **argv, char **envp, int *prom_vec);
/* Simple char-by-char console I/O. */
......@@ -29,21 +37,34 @@ extern char prom_getchar(void);
/* Generic printf() using ARCS console I/O. */
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)
/* Called by prom_init to setup the physical memory pmemblock
* array.
*/
extern void prom_meminit(void);
extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
/* PROM device tree library routines. */
#define PROM_NULL_COMPONENT ((pcomponent *) 0)
/* Get sibling component of THIS. */
extern pcomponent *prom_getsibling(pcomponent *this);
extern pcomponent *ArcGetPeer(pcomponent *this);
/* Get child component of THIS. */
extern pcomponent *prom_getchild(pcomponent *this);
extern pcomponent *ArcGetChild(pcomponent *this);
/* Get parent component of CHILD. */
extern pcomponent *prom_getparent(pcomponent *child);
......@@ -65,7 +86,7 @@ extern pcomponent *prom_componentbypath(char *path);
extern void prom_identify_arch(void);
/* Environment variable routines. */
extern PCHAR ArcGetEnvironmentVariable(CHAR *name);
extern PCHAR ArcGetEnvironmentVariable(PCHAR name);
extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value);
/* ARCS command line acquisition and parsing. */
......@@ -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_open(char *name, enum linux_omode md, 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_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_mount(char *name, enum linux_mountops op);
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
extern long prom_exec(char *name, long argc, char **argv, char **envp);
/* Misc. routines. */
extern void prom_halt(void) __attribute__((noreturn));
extern void prom_powerdown(void) __attribute__((noreturn));
extern void prom_restart(void) __attribute__((noreturn));
extern void prom_reboot(void) __attribute__((noreturn));
extern void ArcEnterInteractiveMode(void) __attribute__((noreturn));
extern long prom_cfgsave(void);
extern struct linux_sysid *prom_getsysid(void);
extern void prom_cacheflush(void);
extern VOID prom_halt(VOID) __attribute__((noreturn));
extern VOID prom_powerdown(VOID) __attribute__((noreturn));
extern VOID prom_restart(VOID) __attribute__((noreturn));
extern VOID ArcReboot(VOID) __attribute__((noreturn));
extern VOID ArcEnterInteractiveMode(VOID) __attribute__((noreturn));
extern long prom_cfgsave(VOID);
extern struct linux_sysid *prom_getsysid(VOID);
extern VOID ArcFlushAllCaches(VOID);
#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) 1999, 2001 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
#ifndef _ASM_SGIARCS_H
#define _ASM_SGIARCS_H
#include <linux/config.h>
#include <asm/types.h>
#include <asm/arc/types.h>
/* Various ARCS error codes. */
......@@ -71,16 +78,16 @@ enum linux_identifier {
/* A prom device tree component. */
struct linux_component {
enum linux_devclass class; /* node class */
enum linux_devtypes type; /* node type */
enum linux_identifier iflags; /* node flags */
unsigned short vers; /* node version */
unsigned short rev; /* node revision */
unsigned long key; /* completely magic */
unsigned long amask; /* XXX affinity mask??? */
unsigned long cdsize; /* size of configuration data */
unsigned long ilen; /* length of string identifier */
char *iname; /* string identifier */
enum linux_devclass class; /* node class */
enum linux_devtypes type; /* node type */
enum linux_identifier iflags; /* node flags */
USHORT vers; /* node version */
USHORT rev; /* node revision */
ULONG key; /* completely magic */
ULONG amask; /* XXX affinity mask??? */
ULONG cdsize; /* size of configuration data */
ULONG ilen; /* length of string identifier */
_PULONG iname; /* string identifier */
};
typedef struct linux_component pcomponent;
......@@ -109,7 +116,7 @@ enum arc_memtypes {
arc_prog, /* A loaded program resides here */
arc_atmp, /* temporary storage area */
arc_aperm, /* permanent storage */
arc_fcontig, /* Contiguous and free */
arc_fcontig, /* Contiguous and free */
};
union linux_memtypes {
......@@ -118,9 +125,9 @@ union linux_memtypes {
};
struct linux_mdesc {
union linux_memtypes type;
unsigned long base;
unsigned long pages;
union linux_memtypes type;
ULONG base;
ULONG pages;
};
/* Time of day descriptor. */
......@@ -136,7 +143,7 @@ struct linux_tinfo {
/* ARCS virtual dirents. */
struct linux_vdirent {
unsigned long namelen;
ULONG namelen;
unsigned char attr;
char fname[32]; /* XXX imperical, should be a define */
};
......@@ -158,11 +165,11 @@ enum linux_mountops {
/* This prom has a bolixed design. */
struct linux_bigint {
#ifdef __MIPSEL__
unsigned long lo;
long hi;
u32 lo;
s32 hi;
#else /* !(__MIPSEL__) */
long hi;
unsigned long lo;
s32 hi;
u32 lo;
#endif
};
......@@ -170,110 +177,97 @@ struct linux_finfo {
struct linux_bigint begin;
struct linux_bigint end;
struct linux_bigint cur;
enum linux_devtypes dtype;
enum linux_devtypes dtype;
unsigned long namelen;
unsigned char attr;
char name[32]; /* XXX imperical, should be define */
};
/* This describes the vector containing function pointers to the ARC
firmware functions. */
struct linux_romvec {
/* Load an executable image. */
long (*load)(char *file, unsigned long end,
unsigned long *start_pc,
unsigned long *end_addr);
/* Invoke a standalong image. */
long (*invoke)(unsigned long startpc, unsigned long sp,
long argc, char **argv, char **envp);
/* Load and begin execution of a standalong image. */
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 */
LONG load; /* Load an executable image. */
LONG invoke; /* Invoke a standalong image. */
LONG exec; /* Load and begin execution of a
standalone image. */
LONG halt; /* Halt the machine. */
LONG pdown; /* Power down the machine. */
LONG restart; /* XXX soft reset??? */
LONG reboot; /* Reboot the machine. */
LONG imode; /* Enter PROM interactive mode. */
LONG _unused1; /* Was ReturnFromMain(). */
/* PROM device tree interface. */
pcomponent *(*next_component)(pcomponent *this);
pcomponent *(*child_component)(pcomponent *this);
pcomponent *(*parent_component)(pcomponent *this);
long (*component_data)(void *opaque_data, pcomponent *this);
pcomponent *(*child_add)(pcomponent *this,
pcomponent *tmp,
void *opaque_data);
long (*comp_del)(pcomponent *this);
pcomponent *(*component_by_path)(char *file);
LONG next_component;
LONG child_component;
LONG parent_component;
LONG component_data;
LONG child_add;
LONG comp_del;
LONG component_by_path;
/* Misc. stuff. */
long (*cfg_save)(void);
struct linux_sysid *(*get_sysid)(void);
LONG cfg_save;
LONG get_sysid;
/* Probing for memory. */
struct linux_mdesc *(*get_mdesc)(struct linux_mdesc *curr);
long _unused2; /* padding */
LONG get_mdesc;
LONG _unused2; /* was Signal() */
struct linux_tinfo *(*get_tinfo)(void);
unsigned long (*get_rtime)(void);
LONG get_tinfo;
LONG get_rtime;
/* File type operations. */
long (*get_vdirent)(unsigned long fd, struct linux_vdirent *entry,
unsigned long num, unsigned long *count);
long (*open)(char *file, enum linux_omode mode, unsigned long *fd);
long (*close)(unsigned long fd);
long (*read)(unsigned long fd, void *buffer, unsigned long num,
unsigned long *count);
long (*get_rstatus)(unsigned long fd);
long (*write)(unsigned long fd, void *buffer, unsigned long num,
unsigned long *count);
long (*seek)(unsigned long fd, struct linux_bigint *offset,
enum linux_seekmode smode);
long (*mount)(char *file, enum linux_mountops op);
LONG get_vdirent;
LONG open;
LONG close;
LONG read;
LONG get_rstatus;
LONG write;
LONG seek;
LONG mount;
/* Dealing with firmware environment variables. */
PCHAR (*get_evar)(CHAR *name);
LONG (*set_evar)(PCHAR name, PCHAR value);
LONG get_evar;
LONG set_evar;
long (*get_finfo)(unsigned long fd, struct linux_finfo *buf);
long (*set_finfo)(unsigned long fd, unsigned long flags,
unsigned long mask);
LONG get_finfo;
LONG set_finfo;
/* Miscellaneous. */
void (*cache_flush)(void);
LONG cache_flush;
};
/* The SGI ARCS parameter block is in a fixed location for standalone
* programs to access PROM facilities easily.
*/
struct linux_promblock {
long magic; /* magic cookie */
typedef struct _SYSTEM_PARAMETER_BLOCK {
ULONG magic; /* magic cookie */
#define PROMBLOCK_MAGIC 0x53435241
unsigned long len; /* length of parm block */
unsigned short ver; /* ARCS firmware version */
unsigned short rev; /* ARCS firmware revision */
long *rs_block; /* Restart block. */
long *dbg_block; /* Debug block. */
long *gevect; /* XXX General vector??? */
long *utlbvect; /* XXX UTLB vector??? */
unsigned long rveclen; /* Size of romvec struct. */
struct linux_romvec *romvec; /* Function interface. */
unsigned long pveclen; /* Length of private vector. */
long *pvector; /* Private vector. */
long adap_cnt; /* Adapter count. */
long adap_typ0; /* First adapter type. */
long adap_vcnt0; /* Adapter 0 vector count. */
long *adap_vector; /* Adapter 0 vector ptr. */
long adap_typ1; /* Second adapter type. */
long adap_vcnt1; /* Adapter 1 vector count. */
long *adap_vector1; /* Adapter 1 vector ptr. */
ULONG len; /* length of parm block */
USHORT ver; /* ARCS firmware version */
USHORT rev; /* ARCS firmware revision */
_PLONG rs_block; /* Restart block. */
_PLONG dbg_block; /* Debug block. */
_PLONG gevect; /* XXX General vector??? */
_PLONG utlbvect; /* XXX UTLB vector??? */
ULONG rveclen; /* Size of romvec struct. */
_PVOID romvec; /* Function interface. */
ULONG pveclen; /* Length of private vector. */
_PVOID pvector; /* Private vector. */
ULONG adap_cnt; /* Adapter count. */
ULONG adap_typ0; /* First adapter type. */
ULONG adap_vcnt0; /* Adapter 0 vector count. */
_PVOID adap_vector; /* Adapter 0 vector ptr. */
ULONG adap_typ1; /* Second adapter type. */
ULONG adap_vcnt1; /* Adapter 1 vector count. */
_PVOID adap_vector1; /* Adapter 1 vector ptr. */
/* More adapter vectors go here... */
};
} SYSTEM_PARAMETER_BLOCK, *PSYSTEM_PARAMETER_BLOCK;
#define PROMBLOCK ((struct linux_promblock *)0xA0001000UL)
#define ROMVECTOR ((PROMBLOCK)->romvec)
#define PROMBLOCK ((PSYSTEM_PARAMETER_BLOCK) (int)0xA0001000)
#define ROMVECTOR ((struct linux_romvec *) (long)(PROMBLOCK)->romvec)
/* Cache layout parameter block. */
union linux_cache_key {
......@@ -367,4 +361,187 @@ struct linux_smonblock {
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 */
......@@ -6,7 +6,7 @@
* SGI ARCS firmware interface library for the Linux kernel.
*
* 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
#define _ASM_SGIALIB_H
......@@ -24,12 +24,11 @@ extern LONG *_prom_argv, *_prom_envp;
#define prom_argc(index) ((char *) (long) _prom_argc[(index)])
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
* at boot time from head.S before start_kernel is invoked.
*/
extern int prom_init(int argc, char **argv, char **envp);
/* Init the PROM library and it's internal data structures. */
extern void prom_init(int argc, char **argv, char **envp, int *prom_vec);
/* Simple char-by-char console I/O. */
extern void prom_putchar(char c);
......@@ -41,9 +40,9 @@ extern void prom_printf(char *fmt, ...);
/* Memory descriptor management. */
#define PROM_MAX_PMEMBLOCKS 32
struct prom_pmemblock {
LONG base; /* Within KSEG0 or XKPHYS. */
LONG base; /* Within KSEG0 or XKPHYS. */
ULONG size; /* In bytes. */
ULONG type; /* free or prom memory */
ULONG type; /* free or prom memory */
};
/* Get next memory descriptor after CURR, returns first descriptor
......@@ -58,9 +57,6 @@ extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr);
extern void prom_meminit(void);
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. */
#define PROM_NULL_COMPONENT ((pcomponent *) 0)
......
......@@ -6,13 +6,14 @@
* ARC firmware interface defines.
*
* 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.
*/
#ifndef _ASM_SGIARCS_H
#define _ASM_SGIARCS_H
#include <linux/config.h>
#include <asm/types.h>
#include <asm/arc/types.h>
/* Various ARCS error codes. */
......@@ -115,7 +116,7 @@ enum arc_memtypes {
arc_prog, /* A loaded program resides here */
arc_atmp, /* temporary storage area */
arc_aperm, /* permanent storage */
arc_fcontig, /* Contiguous and free */
arc_fcontig, /* Contiguous and free */
};
union linux_memtypes {
......@@ -164,11 +165,11 @@ enum linux_mountops {
/* This prom has a bolixed design. */
struct linux_bigint {
#ifdef __MIPSEL__
unsigned long lo;
long hi;
u32 lo;
s32 hi;
#else /* !(__MIPSEL__) */
long hi;
unsigned long lo;
s32 hi;
u32 lo;
#endif
};
......@@ -364,9 +365,10 @@ struct linux_smonblock {
* 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 \
"$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
"$2","$3" /* ... */, "$8","$9","$10","$11", \
"$12","$13","$14","$15","$16","$24","25","$31"
#define ARC_CALL0(dest) \
......@@ -379,7 +381,7 @@ struct linux_smonblock {
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec) \
: __arc_clobbers); \
: __arc_clobbers, "$4","$5","$6","$7"); \
(unsigned long) __res; \
})
......@@ -394,7 +396,7 @@ struct linux_smonblock {
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1) \
: __arc_clobbers); \
: __arc_clobbers, "$5","$6","$7"); \
(unsigned long) __res; \
})
......@@ -410,7 +412,7 @@ struct linux_smonblock {
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1), "r" (__a2) \
: __arc_clobbers); \
: __arc_clobbers, "$6","$7"); \
__res; \
})
......@@ -427,7 +429,7 @@ struct linux_smonblock {
"move\t%0, $2" \
: "=r" (__res), "=r" (__vec) \
: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3) \
: __arc_clobbers); \
: __arc_clobbers, "$7"); \
__res; \
})
......@@ -471,9 +473,11 @@ struct linux_smonblock {
: __arc_clobbers); \
__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) \
({ long __res; \
......@@ -538,6 +542,6 @@ struct linux_smonblock {
__res = __vec(__a1, __a2, __a3, __a4, __a5); \
__res; \
})
#endif /* CONFIG_ARC64 */
#endif /* both kernel and ARC either 32-bit or 64-bit */
#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