Commit 697b7103 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.9pre5

parent e06171a8
......@@ -337,6 +337,10 @@ S: 4 Place Jussieu
S: 75252 Paris Cedex 05
S: France
N: Ulf Carlsson
D: SGI Indy audio (HAL2) drivers
E: ulfc@bun.falkenberg.se
N: Ed Carp
E: ecarp@netcom.com
D: uucp, elm, pine, pico port
......@@ -466,6 +470,14 @@ S: 3000 FORE Drive
S: Warrendale, Pennsylvania 15086
S: USA
N: Alex deVries
E: puffin@redhat.com
D: Various SGI parts, bits of HAL2 and Newport
S: 18 Bernier Terrace
S: Kanata, Ontario
S: K2L 2V@
S: CANADA
N: Eddie C. Dost
E: ecd@skynet.be
D: Linux/Sparc kernel hacker
......@@ -977,12 +989,14 @@ S: Dr. Holsts Vej 34, lejl. 164
S: DK-8230 byhj
S: Denmark
N: Andrzej Krzysztofowicz
E: ankry@green.mif.pg.gda.pl
N: Andrzej M. Krzysztofowicz
E: ankry@mif.pg.gda.pl
D: XT disk driver
D: Aladdin 1533/1543(C) chipset IDE
D: PIIX chipset IDE
S: Faculty of Applied Phys. & Math.
S: Technical University of Gdansk
S: ul. Matemblewska 1B/10
S: 80-283 Gdansk
S: Poland
N: Michael K. Johnson
E: johnsonm@redhat.com
......
......@@ -1527,8 +1527,8 @@ CONFIG_SGI_SERIAL
If you want to use your SGI's built-in serial ports under Linux,
answer Y.
SGI graphics support
CONFIG_SGI_GRAPHICS
SGI Newport Graphics support
CONFIG_SGI_NEWPORT_GFX
If you have an SGI machine and you want to compile the graphics
drivers, say Y here. This will include the code for the
/dev/graphics and /dev/gfx drivers into the kernel for supporting
......
......@@ -162,6 +162,10 @@ ifdef CONFIG_PNP
DRIVERS := $(DRIVERS) drivers/pnp/pnp.a
endif
ifdef CONFIG_SGI
DRIVERS := $(DRIVERS) drivers/sgi/sgi.a
endif
ifdef CONFIG_VT
DRIVERS := $(DRIVERS) drivers/video/video.a
endif
......@@ -174,6 +178,10 @@ ifdef CONFIG_HAMRADIO
DRIVERS := $(DRIVERS) drivers/net/hamradio/hamradio.a
endif
ifeq ($(CONFIG_TC),y)
DRIVERS := $(DRIVERS) drivers/tc/tc.a
endif
ifeq ($(CONFIG_USB),y)
DRIVERS := $(DRIVERS) drivers/usb/usb.a
endif
......
......@@ -200,11 +200,11 @@ start_kernel(void)
load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE);
load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE);
memset((char*)ZERO_PAGE, 0, PAGE_SIZE);
strcpy((char*)ZERO_PAGE, envval);
memset((char*)ZERO_PAGE(0), 0, PAGE_SIZE);
strcpy((char*)ZERO_PAGE(0), envval);
#ifdef INITRD_SIZE
((long *)(ZERO_PAGE+256))[0] = initrd_start;
((long *)(ZERO_PAGE+256))[1] = INITRD_SIZE;
((long *)(ZERO_PAGE(0)+256))[0] = initrd_start;
((long *)(ZERO_PAGE(0)+256))[1] = INITRD_SIZE;
#endif
runkernel();
......
......@@ -182,7 +182,7 @@ void start_kernel(void)
nbytes = 0;
}
envval[nbytes] = '\0';
strcpy((char*)ZERO_PAGE, envval);
strcpy((char*)ZERO_PAGE(0), envval);
srm_printk(" Ok\nNow booting the kernel\n");
runkernel();
......
......@@ -66,7 +66,7 @@ static void get_sysnames(long, long, char **, char **);
* initialized, we need to copy things out into a more permanent
* place.
*/
#define PARAM ZERO_PAGE
#define PARAM ZERO_PAGE(0)
#define COMMAND_LINE ((char*)(PARAM + 0x0000))
#define COMMAND_LINE_SIZE 256
#define INITRD_START (*(unsigned long *) (PARAM+0x100))
......
......@@ -219,7 +219,7 @@ paging_init(unsigned long start_mem, unsigned long end_mem)
/* Initialize the kernel's page tables. Linux puts the vptb in
the last slot of the L1 page table. */
memset((void *) ZERO_PAGE, 0, PAGE_SIZE);
memset((void *) ZERO_PAGE(0), 0, PAGE_SIZE);
memset(swapper_pg_dir, 0, PAGE_SIZE);
newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
pgd_val(swapper_pg_dir[1023]) =
......
......@@ -85,7 +85,7 @@ CONFIG_BLK_DEV_IDEDISK=y
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_BLK_DEV_IDEDMA=y
CONFIG_BLK_DEV_OFFBOARD=y
CONFIG_IDEDMA_AUTO=y
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_NS87415 is not set
......
......@@ -36,7 +36,7 @@ ifdef CONFIG_CROSSCOMPILE
CROSS_COMPILE = $(tool-prefix)
endif
LINKFLAGS = -static #-N
LINKFLAGS = -static -N
MODFLAGS += -mlong-calls
#
......@@ -97,22 +97,37 @@ CORE_FILES += arch/mips/algor/algor.o
SUBDIRS += arch/mips/algor
#LOADADDR += 0x80000000
endif
#
# DECstation family
#
ifdef CONFIG_DECSTATION
CORE_FILES += arch/mips/dec/dec.o
SUBDIRS += arch/mips/dec arch/mips/dec/prom
LIBS += arch/mips/dec/prom/rexlib.a
LOADADDR += 0x80040000
endif
#
# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
#
ifdef CONFIG_MIPS_JAZZ
CORE_FILES += arch/mips/jazz/jazz.o
SUBDIRS += arch/mips/jazz
LOADADDR += 0x80000000
SUBDIRS += arch/mips/jazz arch/mips/arc
LIBS += arch/mips/arc/arclib.a
LOADADDR += 0x80080000
endif
ifdef CONFIG_SNI_RM200_PCI
CORE_FILES += arch/mips/sni/sni.o
SUBDIRS += arch/mips/sni
LOADADDR += 0x80000000
SUBDIRS += arch/mips/sni arch/mips/arc
LIBS += arch/mips/arc/arclib.a
LOADADDR += 0x80080000
endif
ifdef CONFIG_SGI
LIBS += arch/mips/sgi/kernel/sgikern.a arch/mips/sgi/prom/promlib.a
SUBDIRS += arch/mips/sgi/kernel arch/mips/sgi/prom
LIBS += arch/mips/sgi/kernel/sgikern.a arch/mips/arc/arclib.a
SUBDIRS += arch/mips/sgi/kernel arch/mips/arc
#
# Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
# 0x88002000 for production kernels. Note that the value must be
......@@ -122,6 +137,14 @@ LOADADDR += 0x88002000
HOSTCC = cc
endif
#
# Baget/MIPS
#
ifdef CONFIG_BAGET_MIPS
SUBDIRS += arch/mips/baget arch/mips/baget/prom
LIBS += arch/mips/baget/baget.a arch/mips/baget/prom/bagetlib.a
endif
#
# Choosing incompatible machines durings configuration will result in
# error messages during linking. Select a default linkscript if
......@@ -150,7 +173,16 @@ HEAD := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
SUBDIRS := $(SUBDIRS) $(addprefix arch/mips/, kernel mm lib tools)
CORE_FILES := arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(CORE_FILES)
LIBS := arch/mips/lib/lib.a $(LIBS) arch/mips/lib/lib.a
LIBS := arch/mips/lib/lib.a $(LIBS)
ifdef CONFIG_BAGET_MIPS
BAGETBOOT = $(MAKE) -C arch/$(ARCH)/baget
balo: vmlinux
$(BAGETBOOT) balo
endif
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
......
The code for the Algorithmics P4032 evaluation board is currently under
development. I'll release it when it's up to the same strength as
the other ports.
Ralf
# $Id: Makefile,v 1.1.1.1 1997/06/01 03:16:40 ralf Exp $
# $Id: Makefile,v 1.1 1998/10/18 13:32:08 tsbogend Exp $
# Makefile for the SGI arcs prom monitor library routines
# under Linux.
#
......@@ -8,13 +8,13 @@
#
# Note 2! The CFLAGS definitions are now in the main makefile...
OBJS = console.o init.o printf.o memory.o tree.o tags.o env.o \
cmdline.o misc.o time.o file.o
OBJS = console.o init.o printf.o memory.o tree.o env.o \
cmdline.o misc.o time.o file.o identify.o
all: promlib.a
all: arclib.a
promlib.a: $(OBJS)
$(AR) rcs promlib.a $(OBJS)
arclib.a: $(OBJS)
$(AR) rcs arclib.a $(OBJS)
sync
dep:
......
......@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
* $Id: cmdline.c,v 1.3 1998/03/27 08:53:46 ralf Exp $
* $Id: cmdline.c,v 1.1 1998/10/18 13:32:08 tsbogend Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
......@@ -14,7 +14,7 @@
/* #define DEBUG_CMDLINE */
extern char arcs_cmdline[CL_SIZE];
char arcs_cmdline[CL_SIZE];
__initfunc(char *prom_getcmdline(void))
{
......
......@@ -2,25 +2,48 @@
* console.c: SGI arcs console code.
*
* Copyright (C) 1996 David S. Miller (dm@sgi.com)
* Compability with board caches, Ulf Carlsson
*
* $Id: console.c,v 1.2 1998/03/27 08:53:46 ralf Exp $
* $Id: console.c,v 1.2 1999/06/12 18:42:38 ulfc Exp $
*/
#include <linux/init.h>
#include <asm/sgialib.h>
#include <asm/bcache.h>
/* The romvec 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 romvec write and read functions seem to interfere with the serial lines
* in some way. You should be careful with them.
*/
extern struct bcache_ops *bcops;
#ifdef CONFIG_SGI_PROM_CONSOLE
void prom_putchar(char c)
#else
__initfunc(void prom_putchar(char c))
#endif
{
long cnt;
char it = c;
bcops->bc_disable();
romvec->write(1, &it, 1, &cnt);
bcops->bc_enable();
}
#ifdef CONFIG_SGI_PROM_CONSOLE
char prom_getchar(void)
#else
__initfunc(char prom_getchar(void))
#endif
{
long cnt;
char c;
bcops->bc_disable();
romvec->read(0, &c, 1, &cnt);
bcops->bc_enable();
return c;
}
......@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
* $Id: env.c,v 1.2 1998/03/27 08:53:46 ralf Exp $
* $Id: env.c,v 1.1 1998/10/18 13:32:08 tsbogend Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
......
......@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
* $Id: file.c,v 1.2 1998/03/27 08:53:47 ralf Exp $
* $Id: file.c,v 1.1 1998/10/18 13:32:08 tsbogend Exp $
*/
#include <linux/init.h>
#include <asm/sgialib.h>
......
/*
* 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)
*
* $Id: identify.c,v 1.2 1999/02/25 21:04:13 tsbogend Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
#include <asm/sgi.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 },
{ "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(char *s)
{
int i;
for (i = 0; i < sizeof (mach_table); i++) {
if(!strcmp(s, mach_table[i].name))
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;
}
void __init prom_identify_arch(void)
{
pcomponent *p;
struct smatch *mach;
/* 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);
mips_machgroup = mach->group;
mips_machtype = mach->type;
prom_flags = mach->flags;
}
......@@ -3,10 +3,11 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
* $Id: init.c,v 1.2 1998/03/27 08:53:47 ralf Exp $
* $Id: init.c,v 1.2 1999/02/25 21:22:49 tsbogend Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/config.h>
#include <asm/sgialib.h>
......@@ -41,10 +42,15 @@ __initfunc(int prom_init(int argc, char **argv, char **envp))
prom_vers = pb->ver;
prom_rev = pb->rev;
prom_identify_arch();
#ifdef CONFIG_SGI
printk("PROMLIB: SGI ARCS firmware Version %d Revision %d\n",
prom_vers, prom_rev);
#else
printk("PROMLIB: ARC firmware Version %d Revision %d\n",
prom_vers, prom_rev);
#endif
prom_meminit();
prom_setup_archtags();
#if 0
prom_testtree();
......
......@@ -4,7 +4,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
* $Id: memory.c,v 1.2 1998/03/27 08:53:47 ralf Exp $
* $Id: memory.c,v 1.5 1999/04/14 21:25:02 tsbogend Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
......@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/config.h>
#include <asm/sgialib.h>
#include <asm/page.h>
......@@ -26,7 +27,7 @@ __initfunc(struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr))
}
#ifdef DEBUG /* convenient for debugging */
static char *mtypes[8] = {
static char *arcs_mtypes[8] = {
"Exception Block",
"ARCS Romvec Page",
"Free/Contig RAM",
......@@ -36,6 +37,18 @@ static char *mtypes[8] = {
"ARCS Temp Storage Area",
"ARCS Permanent Storage Area"
};
static char *arc_mtypes[8] = {
"Exception Block",
"SystemParameterBlock",
"FreeMemory",
"Bad Memory",
"LoadedProgram",
"FirmwareTemporary",
"FirmwarePermanent",
"FreeContigiuous"
};
#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc]
#endif
static struct prom_pmemblock prom_pblocks[PROM_MAX_PMEMBLOCKS];
......@@ -45,6 +58,38 @@ __initfunc(struct prom_pmemblock *prom_getpblock_array(void))
return &prom_pblocks[0];
}
#define MEMTYPE_DONTUSE 0
#define MEMTYPE_PROM 1
#define MEMTYPE_FREE 2
static int __init prom_memtype_classify (union linux_memtypes type)
{
if (prom_flags & PROM_FLAG_ARCS) {
switch (type.arcs) {
case arcs_free:
case arcs_fcontig:
return MEMTYPE_FREE;
case arcs_atmp:
case arcs_aperm:
return MEMTYPE_PROM;
default:
return MEMTYPE_DONTUSE;
}
} else {
switch (type.arc) {
case arc_free:
case arc_fcontig:
return MEMTYPE_FREE;
case arc_rvpage:
case arc_atmp:
case arc_aperm:
return MEMTYPE_PROM;
default:
return MEMTYPE_DONTUSE;
}
}
}
__initfunc(static void prom_setup_memupper(void))
{
struct prom_pmemblock *p, *highest;
......@@ -73,7 +118,7 @@ __initfunc(void prom_meminit(void))
prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
while(p) {
prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
i, p, p->base, p->pages, mtypes[p->type]);
i, p, p->base, p->pages, mtypes(p->type));
p = prom_getmdesc(p);
i++;
}
......@@ -82,19 +127,31 @@ __initfunc(void prom_meminit(void))
totram = 0;
i = 0;
while(p) {
if(p->type == free || p->type == fcontig) {
prom_pblocks[i].base =
((p->base<<PAGE_SHIFT) + 0x80000000);
prom_pblocks[i].size = p->pages << PAGE_SHIFT;
totram += prom_pblocks[i].size;
prom_pblocks[i].type = prom_memtype_classify (p->type);
prom_pblocks[i].base = ((p->base<<PAGE_SHIFT) + 0x80000000);
prom_pblocks[i].size = p->pages << PAGE_SHIFT;
switch (prom_pblocks[i].type) {
case MEMTYPE_FREE:
totram += prom_pblocks[i].size;
#ifdef DEBUG
prom_printf("free_chunk[%d]: base=%08lx size=%d\n",
i, prom_pblocks[i].base,
prom_pblocks[i].size);
prom_printf("free_chunk[%d]: base=%08lx size=%d\n",
i, prom_pblocks[i].base,
prom_pblocks[i].size);
#endif
i++;
}
p = prom_getmdesc(p);
i++;
break;
case MEMTYPE_PROM:
#ifdef DEBUG
prom_printf("prom_chunk[%d]: base=%08lx size=%d\n",
i, prom_pblocks[i].base,
prom_pblocks[i].size);
#endif
i++;
break;
default:
break;
}
p = prom_getmdesc(p);
}
prom_pblocks[i].base = 0xdeadbeef;
prom_pblocks[i].size = 0; /* indicates last elem. of array */
......@@ -116,16 +173,37 @@ __initfunc(void prom_fixup_mem_map(unsigned long start, unsigned long end))
for(i = 0; p[i].size; i++)
;
nents = i;
restart:
while(start < end) {
for(i = 0; i < nents; i++) {
if((start >= (p[i].base)) &&
if((p[i].type == MEMTYPE_FREE) &&
(start >= (p[i].base)) &&
(start < (p[i].base + p[i].size))) {
start = p[i].base + p[i].size;
start &= PAGE_MASK;
continue;
goto restart;
}
}
set_bit(PG_reserved, &mem_map[MAP_NR(start)].flags);
start += PAGE_SIZE;
}
}
void prom_free_prom_memory (void)
{
struct prom_pmemblock *p;
unsigned long addr;
unsigned long num_pages = 0;
for(p = prom_getpblock_array(); p->size != 0; p++) {
if (p->type == MEMTYPE_PROM) {
for (addr = p->base; addr < p->base + p->size; addr += PAGE_SIZE) {
mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
atomic_set(&mem_map[MAP_NR(addr)].count, 1);
free_page(addr);
num_pages++;
}
}
}
printk ("Freeing prom memory: %dk freed\n",num_pages << (PAGE_SHIFT - 10));
}
/* $Id: misc.c,v 1.6 1998/07/08 15:59:13 ralf Exp $
/* $Id: misc.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $
*
* misc.c: Miscellaneous ARCS PROM routines.
*
......
......@@ -4,7 +4,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@sgi.com)
*
* $Id: printf.c,v 1.2 1998/03/27 08:53:48 ralf Exp $
* $Id: printf.c,v 1.2 1999/06/12 18:42:38 ulfc Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
......@@ -13,7 +13,11 @@
static char ppbuf[1024];
#ifdef CONFIG_SGI_PROM_CONSOLE
void prom_printf(char *fmt, ...)
#else
__initfunc(void prom_printf(char *fmt, ...))
#endif
{
va_list args;
char ch, *bptr;
......
......@@ -4,7 +4,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
* $Id: salone.c,v 1.2 1998/03/27 08:53:48 ralf Exp $
* $Id: salone.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $
*/
#include <linux/init.h>
#include <asm/sgialib.h>
......
......@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
* $Id: time.c,v 1.2 1998/03/27 08:53:49 ralf Exp $
* $Id: time.c,v 1.1 1998/10/18 13:32:10 tsbogend Exp $
*/
#include <linux/init.h>
#include <asm/sgialib.h>
......
......@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
* $Id: tree.c,v 1.2 1998/03/27 08:53:49 ralf Exp $
* $Id: tree.c,v 1.1 1998/10/18 13:32:10 tsbogend Exp $
*/
#include <linux/init.h>
#include <asm/sgialib.h>
......
# $Id$
#
# Makefile for the Baget specific kernel interface routines
# under Linux.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile...
all: baget.a
image: ../../../vmlinux
cp -f $< $@
O_TARGET := baget.a
O_OBJS := baget.o print.o setup.o time.o irq.o bagetIRQ.o reset.o wbflush.o
ifeq ($(CONFIG_SERIAL),y)
OX_OBJS += vacserial.o
else
ifeq ($(CONFIG_SERIAL),m)
MX_OBJS += vacserial.o
endif
endif
ifeq ($(CONFIG_VAC_RTC),y)
OX_OBJS += vacrtc.o
else
ifeq ($(CONFIG_VAC_RTC),m)
MX_OBJS += vacrtc.o
endif
endif
bagetIRQ.o : bagetIRQ.S
$(CC) $(CFLAGS) -c -o $@ $<
##################### Baget Loader stuff ########################
dummy.c:
touch $@
image.bin: image
$(OBJCOPY) -O binary $< $@
ramdisk.bin:
echo "Dummy ramdisk used. Provide your own if needed !" > $@
dummy.o: dummy.c image.bin ramdisk.bin
$(CC) $(CFLAGS) -c -o $@ $<
$(OBJCOPY) --add-section=.vmlinux=image.bin \
--add-section=.ramdisk=ramdisk.bin $@
balo.h: image
$(NM) $< | awk ' \
BEGIN { printf "/* DO NOT EDIT THIS FILE */\n" } \
/kernel_entry/ { printf "#define START 0x%s\n", $$1 } \
/balo_ramdisk_base/ { printf "#define RAMDISK_BASE 0x%s\n", $$1 } \
/balo_ramdisk_size/ { printf "#define RAMDISK_SIZE 0x%s\n", $$1 } \
' > $@
balo.o: balo.c balo.h
$(CC) $(CFLAGS) -c $<
balo_supp.o: balo_supp.S
$(CC) $(CFLAGS) -c $<
balo: balo.o dummy.o balo_supp.o print.o
$(LD) $(LDFLAGS) -T ld.script.balo -o $@ $^
clean:
rm -f balo.o balo.h dummy.o dummy.c hello.o image.bin image balo_supp.o
rm -f $(O_OBJS) $(O_TARGET)
include $(TOPDIR)/Rules.make
/* $Id$
*
* baget.c: Baget low level stuff
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
*
*/
#include <stdarg.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/system.h>
#include <asm/bootinfo.h>
#include <asm/mipsregs.h>
#include <asm/pgtable.h>
#include <asm/baget/baget.h>
/*
* Following values are set by BALO into RAM disk buffer parameters
*/
unsigned long balo_ramdisk_base = 0xBA; /* Signature for BALO ! */
unsigned long balo_ramdisk_size = 0;
/*
* Following code is based on routines from 'mm/vmalloc.c'
* Additional parameters ioaddr is needed to iterate across real I/O address.
*/
static inline int alloc_area_pte(pte_t * pte, unsigned long address,
unsigned long size, unsigned long ioaddr)
{
unsigned long end;
address &= ~PMD_MASK;
end = address + size;
if (end > PMD_SIZE)
end = PMD_SIZE;
while (address < end) {
unsigned long page;
if (!pte_none(*pte))
printk("kseg2_alloc_io: page already exists\n");
/*
* For MIPS looks pretty to have transparent mapping
* for KSEG2 areas -- user can't access one, and no
* problems with virtual <--> physical translation.
*/
page = ioaddr & PAGE_MASK;
set_pte(pte, __pte(page | pgprot_val(PAGE_USERIO) |
_PAGE_GLOBAL | __READABLE | __WRITEABLE));
address += PAGE_SIZE;
ioaddr += PAGE_SIZE;
pte++;
}
return 0;
}
static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address,
unsigned long size, unsigned long ioaddr)
{
unsigned long end;
address &= ~PGDIR_MASK;
end = address + size;
if (end > PGDIR_SIZE)
end = PGDIR_SIZE;
while (address < end) {
pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
if (alloc_area_pte(pte, address, end - address, ioaddr))
return -ENOMEM;
address = (address + PMD_SIZE) & PMD_MASK;
ioaddr += PMD_SIZE;
pmd++;
}
return 0;
}
int kseg2_alloc_io (unsigned long address, unsigned long size)
{
pgd_t * dir;
unsigned long end = address + size;
dir = pgd_offset_k(address);
flush_cache_all();
while (address < end) {
pmd_t *pmd;
pgd_t olddir = *dir;
pmd = pmd_alloc_kernel(dir, address);
if (!pmd)
return -ENOMEM;
if (alloc_area_pmd(pmd, address, end - address, address))
return -ENOMEM;
if (pgd_val(olddir) != pgd_val(*dir))
set_pgdir(address, *dir);
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
flush_tlb_all();
return 0;
}
/* $Id$
* bagetIRQ.S: Interrupt exception dispatch code for Baget/MIPS
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
*/
#include <asm/asm.h>
#include <asm/mipsconfig.h>
#include <asm/mipsregs.h>
#include <asm/regdef.h>
#include <asm/stackframe.h>
#include <asm/addrspace.h>
.text
.set mips1
.set reorder
.set macro
.set noat
.align 5
NESTED(bagetIRQ, PT_SIZE, sp)
SAVE_ALL
CLI # Important: mark KERNEL mode !
la a1, baget_interrupt
.set push
.set noreorder
jal a1
.set pop
move a0, sp
la a1, ret_from_irq
jr a1
END(bagetIRQ)
#define DBE_HANDLER 0x1C
NESTED(try_read, PT_SIZE, sp)
mfc0 t3, CP0_STATUS # save flags and
CLI # disable interrupts
li t0, KSEG2
sltu t1, t0, a0 # Is it KSEG2 address ?
beqz t1, mapped # No - already mapped !
move t0, a0
ori t0, 0xfff
xori t0, 0xfff # round address to page
ori t1, t0, 0xf00 # prepare EntryLo (N,V,D,G)
mfc0 t2, CP0_ENTRYHI # save ASID value
mtc0 zero, CP0_INDEX
mtc0 t0, CP0_ENTRYHI # Load MMU values ...
mtc0 t1, CP0_ENTRYLO0
nop # let it understand
nop
tlbwi # ... and write ones
nop
nop
mtc0 t2, CP0_ENTRYHI
mapped:
la t0, exception_handlers
lw t1, DBE_HANDLER(t0) # save real handler
la t2, dbe_handler
sw t2, DBE_HANDLER(t0) # set temporary local handler
li v0, -1 # default (failure) value
li t2, 1
beq t2, a1, 1f
li t2, 2
beq t2, a1, 2f
li t2, 4
beq t2, a1, 4f
b out
1: lbu v0, (a0) # byte
b out
2: lhu v0, (a0) # short
b out
4: lw v0, (a0) # word
out:
sw t1, DBE_HANDLER(t0) # restore real handler
mtc0 t3, CP0_STATUS # restore CPU flags
jr ra
dbe_handler:
li v0, -1 # mark our failure
.set push
.set noreorder
b out # "no problems !"
rfe # return from trap
.set pop
END(try_read)
/* $Id$
*
* balo.c: BAget LOader
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
*
*/
#include <linux/kernel.h>
#include <asm/system.h>
#include <asm/ptrace.h>
#include <asm/addrspace.h>
#include <asm/baget/baget.h>
#include "balo.h" /* Includes some kernel symbol values */
static char *banner = "\nBaget Linux Loader v0.2\n";
static void mem_move (long *to, long *from, long size)
{
while (size > 0) {
*to++ = *from++;
size -= sizeof(long);
}
}
static volatile int *mem_limit = (volatile int*)KSEG1;
static volatile int *mem_limit_dbe = (volatile int*)KSEG1;
static int can_write (volatile int* p) {
return p < (int*)(KSEG1+BALO_OFFSET) ||
p >= (int*)(KSEG1+BALO_OFFSET+BALO_SIZE);
}
static volatile enum balo_state_enum {
BALO_INIT,
MEM_INIT,
MEM_PROBE,
START_KERNEL
} balo_state = BALO_INIT;
static __inline__ void reset_and_jump(int start, int mem_upper)
{
__asm__ __volatile__(
".set\tnoreorder\n\t"
".set\tnoat\n\t"
"mfc0\t$1,$12\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"ori\t$1,$1,0xff00\n\t"
"xori\t$1,$1,0xff00\n\t"
"mtc0\t$1,$12\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"move\t$4,%1\n\t"
"jr\t%0\n\t"
"nop\n\t"
".set\tat\n\t"
".set\treorder"
: /* no outputs */
:"Ir" (start), "Ir" (mem_upper)
:"$1", "$4", "memory");
}
static void start_kernel(void)
{
extern char _vmlinux_start, _vmlinux_end;
extern char _ramdisk_start, _ramdisk_end;
outs( "Relocating Linux... " );
mem_move((long*)KSEG0, (long*)&_vmlinux_start,
&_vmlinux_end-&_vmlinux_start);
outs("done.\n");
if (&_ramdisk_start != &_ramdisk_end) {
outs("Setting up RAMDISK... ");
if (*(unsigned long*)RAMDISK_BASE != 0xBA) {
outs("Bad RAMDISK_BASE signature in system image.\n");
balo_hungup();
}
*(unsigned long*)RAMDISK_BASE = (unsigned long)&_ramdisk_start;
*(unsigned long*)RAMDISK_SIZE = &_ramdisk_end -&_ramdisk_start;
outs("done.\n");
}
{
extern void flush_cache_low(int isize, int dsize);
flush_cache_low(256*1024,256*1024);
}
balo_printf( "Kernel entry: %x\n\n", START);
balo_state = START_KERNEL;
reset_and_jump(START, (int)mem_limit-KSEG1+KSEG0);
}
static void mem_probe(void)
{
balo_state = MEM_PROBE;
outs("RAM: <");
while(mem_limit < mem_limit_dbe) {
if (can_write(mem_limit) && *mem_limit != 0)
break; /* cycle found */
outc('.');
if (can_write(mem_limit))
*mem_limit = -1; /* mark */
mem_limit += 0x40000;
}
outs(">\n");
start_kernel();
}
volatile unsigned int int_cause;
volatile unsigned int epc;
volatile unsigned int badvaddr;
static void print_regs(void)
{
balo_printf("CAUSE=%x EPC=%x BADVADDR=%x\n",
int_cause, epc, badvaddr);
}
void int_handler(struct pt_regs *regs)
{
switch (balo_state) {
case BALO_INIT:
balo_printf("\nBALO: trap in balo itself.\n");
print_regs();
balo_hungup();
break;
case MEM_INIT:
if ((int_cause & CAUSE_MASK) != CAUSE_DBE) {
balo_printf("\nBALO: unexpected trap during memory init.\n");
print_regs();
balo_hungup();
} else {
mem_probe();
}
break;
case MEM_PROBE:
balo_printf("\nBALO: unexpected trap during memory probe.\n");
print_regs();
balo_hungup();
break;
case START_KERNEL:
balo_printf("\nBALO: unexpected kernel trap.\n");
print_regs();
balo_hungup();
break;
}
balo_printf("\nBALO: unexpected return from handler.\n");
print_regs();
balo_hungup();
}
static void mem_init(void)
{
balo_state = MEM_INIT;
while(1) {
*mem_limit_dbe;
if (can_write(mem_limit_dbe))
*mem_limit_dbe = 0;
mem_limit_dbe += 0x40000; /* +1M */
}
/* no return: must go to int_handler */
}
void balo_entry(void)
{
extern void except_vec3_generic(void);
cli();
outs(banner);
memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80);
mem_init();
}
/* Needed for linking */
int vsprintf(char *buf, const char *fmt, va_list arg)
{
outs("BALO: vsprintf called.\n");
balo_hungup();
return 0;
}
/* $Id$
* balo_supp.S: BAget Loader supplement
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
*/
#include <linux/config.h>
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/stackframe.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
.text
.set mips1
/* General exception vector. */
NESTED(except_vec3_generic, 0, sp)
.set noat
la k0, except_vec3_generic_code
jr k0
END(except_vec3_generic)
NESTED(except_vec3_generic_code, 0, sp)
SAVE_ALL
mfc0 k1, CP0_CAUSE
la k0, int_cause
sw k1, (k0)
mfc0 k1, CP0_EPC
la k0, epc
sw k1, (k0)
mfc0 k1, CP0_BADVADDR
la k0, badvaddr
sw k1, (k0)
la k0, int_handler
.set noreorder
jal k0
.set reorder
move a0, sp
RESTORE_ALL_AND_RET
END(except_vec3_generic_code)
.align 5
NESTED(flush_cache_low, PT_SIZE, sp)
.set at
.set macro
.set noreorder
move t1, a0 # ISIZE
move t2, a1 # DSIZE
mfc0 t3, CP0_STATUS # Save the status register.
mtc0 zero, CP0_STATUS # Disable interrupts.
la v0, 1f
or v0, KSEG1 # Run uncached.
j v0
nop
/*
* Flush the instruction cache.
*/
1:
li v0, ST0_DE | ST0_CE
mtc0 v0, CP0_STATUS # Isolate and swap caches.
li t0, KSEG1
subu t0, t0, t1
li t1, KSEG1
la v0, 1f # Run cached
j v0
nop
1:
addu t0, t0, 64
sb zero, -64(t0)
sb zero, -60(t0)
sb zero, -56(t0)
sb zero, -52(t0)
sb zero, -48(t0)
sb zero, -44(t0)
sb zero, -40(t0)
sb zero, -36(t0)
sb zero, -32(t0)
sb zero, -28(t0)
sb zero, -24(t0)
sb zero, -20(t0)
sb zero, -16(t0)
sb zero, -12(t0)
sb zero, -8(t0)
bne t0, t1, 1b
sb zero, -4(t0)
la v0, 1f
or v0, KSEG1
j v0 # Run uncached
nop
/*
* Flush the data cache.
*/
1:
li v0, ST0_DE
mtc0 v0, CP0_STATUS # Isolate and swap back caches
li t0, KSEG1
subu t0, t0, t2
la v0, 1f
j v0 # Back to cached mode
nop
1:
addu t0, t0, 64
sb zero, -64(t0)
sb zero, -60(t0)
sb zero, -56(t0)
sb zero, -52(t0)
sb zero, -48(t0)
sb zero, -44(t0)
sb zero, -40(t0)
sb zero, -36(t0)
sb zero, -32(t0)
sb zero, -28(t0)
sb zero, -24(t0)
sb zero, -20(t0)
sb zero, -16(t0)
sb zero, -12(t0)
sb zero, -8(t0)
bne t0, t1, 1b
sb zero, -4(t0)
nop # Insure isolated stores
nop # out of pipe.
nop
nop
mtc0 t3, CP0_STATUS # Restore status reg.
nop # Insure cache unisolated.
nop
nop
nop
j ra
nop
END(flush_cache_low)
/* To satisfy macros only */
EXPORT(kernelsp)
PTR 0x80001000
This diff is collapsed.
OUTPUT_FORMAT("elf32-bigmips")
OUTPUT_ARCH(mips)
ENTRY(balo_entry)
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = 0x80400000;
.rel.text : { *(.rel.text) }
.rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
.rela.data : { *(.rela.data) }
.rel.rodata : { *(.rel.rodata) }
.rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) } =0
.text :
{
_ftext = . ;
*(.text)
*(.rodata)
*(.rodata1)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
_etext = .;
PROVIDE (etext = .);
/* Startup code */
. = ALIGN(4096);
__init_begin = .;
*(.text.init)
*(.data.init)
. = ALIGN(4096); /* Align double page for init_task_union */
__init_end = .;
*(.fini)
*(.reginfo)
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. It would
be more correct to do this:
. = .;
The current expression does not correctly handle the case of a
text segment ending precisely at the end of a page; it causes the
data segment to skip a page. The above expression does not have
this problem, but it will currently (2/95) cause BFD to allocate
a single segment, combining both text and data, for this case.
This will prevent the text segment from being shared among
multiple executions of the program; I think that is more
important than losing a page of the virtual address space (note
that no actual memory is lost; the page which is skipped can not
be referenced). */
. = .;
_fdata = . ;
*(.data)
CONSTRUCTORS
*(.data1)
_gp = . + 0x8000;
*(.lit8)
*(.lit4)
*(.ctors)
*(.dtors)
*(.got.plt) *(.got)
*(.dynamic)
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
*(.sdata)
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
_fbss = .;
*(.dynbss)
*(.bss)
*(COMMON)
_end = . ;
PROVIDE (end = .);
*(.sbss)
*(.scommon)
/* These are needed for ELF backends which have not yet been
converted to the new style linker. */
*(.stab)
*(.stabstr)
/* DWARF debug sections.
Symbols in the .debug DWARF section are relative to the beginning of the
section so we begin .debug at 0. It's not clear yet what needs to happen
for the others. */
*(.debug)
*(.debug_srcinfo)
*(.debug_aranges)
*(.debug_pubnames)
*(.debug_sfnames)
*(.line)
/* These must appear regardless of . */
*(.gptab.data) *(.gptab.sdata)
*(.gptab.bss) *(.gptab.sbss)
_vmlinux_start = .;
*(.vmlinux)
_vmlinux_end = .;
_ramdisk_start = .;
*(.ramdisk)
_ramdisk_end = .;
} =0
}
/* $Id$
*
* print.c: Simple print fascility
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
*
*/
#include <stdarg.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/baget/baget.h>
/*
* Define this to see 'baget_printk' (debug) messages
*/
// #define BAGET_PRINTK
/*
* This function is same for BALO and Linux baget_printk,
* and normally prints characted to second (UART A) console.
*/
static void delay(void) {}
static void outc_low(char c)
{
int i;
vac_outb(c, VAC_UART_B_TX);
for (i=0; i<10000; i++)
delay();
}
void outc(char c)
{
if (c == '\n')
outc_low('\r');
outc_low(c);
}
void outs(char *s)
{
while(*s) outc(*s++);
}
void baget_write(char *s, int l)
{
while(l--)
outc(*s++);
}
int baget_printk(const char *fmt, ...)
{
#ifdef BAGET_PRINTK
va_list args;
int i;
static char buf[1024];
va_start(args, fmt);
i = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf)-4 */
va_end(args);
baget_write(buf, i);
return i;
#else
return 0;
#endif
}
static __inline__ void puthex( int a )
{
static char s[9];
static char e[] = "0123456789ABCDEF";
int i;
for( i = 7; i >= 0; i--, a >>= 4 ) s[i] = e[a & 0x0F];
s[8] = '\0';
outs( s );
}
__initfunc(void balo_printf( char *f, ... ))
{
int *arg = (int*)&f + 1;
char c;
int format = 0;
while((c = *f++) != 0) {
switch(c) {
default:
if(format) {
outc('%');
format = 0;
}
outc( c );
break;
case '%':
if( format ){
format = 0;
outc(c);
} else format = 1;
break;
case 'x':
if(format) puthex( *arg++ );
else outc(c);
format = 0;
break;
case 's':
if( format ) outs((char *)*arg++);
else outc(c);
format = 0;
break;
}
}
}
__initfunc(void balo_hungup(void))
{
outs("Hunging up.\n");
while(1);
}
# $Id$
# Makefile for the Baget/MIPS prom emulator library routines.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile...
O_TARGET := bagetlib.a
O_OBJS := init.o
all: $(O_TARGET)
include $(TOPDIR)/Rules.make
/*
* init.c: PROM library initialisation code.
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
*
* $Id$
*/
#include <linux/init.h>
#include <linux/config.h>
#include <asm/bootinfo.h>
char arcs_cmdline[CL_SIZE];
__initfunc(int prom_init(unsigned int mem_upper))
{
mips_memory_upper = mem_upper;
mips_machgroup = MACH_GROUP_UNKNOWN;
mips_machtype = MACH_UNKNOWN;
arcs_cmdline[0] = 0;
return 0;
}
#include <linux/kernel.h>
#include <asm/system.h>
#include <asm/baget/baget.h>
#define R3000_RESET_VEC 0xbfc00000
typedef void vector(void);
static void baget_reboot(char *from_fun)
{
cli();
baget_printk("\n%s: jumping to RESET code...\n", from_fun);
(*(vector*)R3000_RESET_VEC)();
}
/* fixme: proper functionality */
void baget_machine_restart(char *command)
{
baget_reboot("restart");
}
void baget_machine_halt(void)
{
baget_reboot("halt");
}
void baget_machine_power_off(void)
{
baget_reboot("power off");
}
This diff is collapsed.
/* $Id$
* time.c: Baget/MIPS specific time handling details
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/kernel_stat.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/baget/baget.h>
/*
* To have precision clock, we need to fix available clock frequency
*/
#define FREQ_NOM 79125 /* Baget frequency ratio */
#define FREQ_DEN 10000
static inline int timer_intr_valid(void)
{
static unsigned long long ticks, valid_ticks;
if (ticks++ * FREQ_DEN >= valid_ticks * FREQ_NOM) {
/*
* We need no overflow checks,
* due baget unable to work 3000 years...
* At least without reboot...
*/
valid_ticks++;
return 1;
}
return 0;
}
void static timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
if (timer_intr_valid()) {
sti();
do_timer(regs);
}
}
__initfunc(static void timer_enable(void))
{
unsigned char ss0cr0 = vic_inb(VIC_SS0CR0);
ss0cr0 &= ~VIC_SS0CR0_TIMER_FREQ_MASK;
ss0cr0 |= VIC_SS0CR0_TIMER_FREQ_1000HZ;
vic_outb(ss0cr0, VIC_SS0CR0);
vic_outb(VIC_INT_IPL(6)|VIC_INT_NOAUTO|VIC_INT_EDGE|
VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2);
}
__initfunc(void time_init(void))
{
if (request_irq(BAGET_VIC_TIMER_IRQ, timer_interrupt,
SA_INTERRUPT|SA_STATIC_ALLOC, "timer", NULL) < 0)
printk("time_init: unable request irq for system timer\n");
timer_enable();
/* We don't call sti() here, because it is too early for baget */
}
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
save_and_cli(flags);
*tv = xtime;
restore_flags(flags);
}
void do_settimeofday(struct timeval *tv)
{
unsigned long flags;
save_and_cli(flags);
xtime = *tv;
time_state = TIME_BAD;
time_maxerror = MAXPHASE;
time_esterror = MAXPHASE;
restore_flags(flags);
}
This diff is collapsed.
/*
* Setup the right wbflush routine for Baget/MIPS.
*
* Copyright (C) 1999 Gleb Raiko & Vladimir Roganov
*/
#include <asm/bootinfo.h>
#include <asm/init.h>
void (*__wbflush) (void);
static void wbflush_baget(void);
__initfunc(void wbflush_setup(void))
{
__wbflush = wbflush_baget;
}
/*
* Baget/MIPS doesnt need to write back the WB.
*/
static void wbflush_baget(void)
{
}
#
# arch/mips/boot/Makefile
# $Id: Makefile,v 1.9 1999/04/07 18:45:23 harald 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.
#
# Copyright (C) 1995 by Ralf Baechle
# Copyright (C) 1995, 1998 by Ralf Baechle
#
.S.s:
......@@ -15,6 +14,15 @@
OBJS = milo.o a.out.o
#
# Some DECstations need all possible sections of an ECOFF executable
#
ifdef CONFIG_DECSTATION
E2EFLAGS = -a
else
E2EFLAGS =
endif
#
# Drop some uninteresting sections in the kernel.
# This is only relevant for ELF kernels but doesn't hurt a.out
......@@ -22,29 +30,22 @@ OBJS = milo.o a.out.o
drop-sections = .reginfo .mdebug
strip-flags = $(addprefix --remove-section=,$(drop-sections))
#
# Fake compressed boot
#
zImage: $(CONFIGURE) mkboot $(TOPDIR)/vmlinux
$(OBJCOPY) $(strip-flags) $(TOPDIR)/vmlinux zImage.tmp
./mkboot zImage.tmp zImage
rm -f zImage.tmp
all: vmlinux.ecoff addinitrd
mkboot: mkboot.c
vmlinux.ecoff: $(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux
./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS)
elf2ecoff: elf2ecoff.c
$(HOSTCC) -o $@ $^
zdisk: zImage
if [ -f /etc/remote-mcopy ]; then \
ssh rio mcopy -o - a:vmlinux <zImage; \
else \
mcopy -o zImage a:vmlinux; \
fi
addinitrd: addinitrd.c
$(HOSTCC) -o $@ $^
# Don't build dependencies, this may die if $(CC) isn't gcc
dep:
clean:
rm -f zImage zImage.tmp mkboot
rm -f vmlinux.ecoff
dummy:
......
/*
* addinitrd - program to add a initrd image to an ecoff kernel
*
* (C) 1999 Thomas Bogendoerfer
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "ecoff.h"
#define MIPS_PAGE_SIZE 4096
#define MIPS_PAGE_MASK (MIPS_PAGE_SIZE-1)
#define swab16(x) \
((unsigned short)( \
(((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
(((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
#define swab32(x) \
((unsigned int)( \
(((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
(((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \
(((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
(((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
#define SWAB(a) (swab ? swab32(a) : (a))
void die (char *s)
{
perror (s);
exit (1);
}
int main (int argc, char *argv[])
{
int fd_vmlinux,fd_initrd,fd_outfile;
FILHDR efile;
AOUTHDR eaout;
SCNHDR esecs[3];
struct stat st;
char buf[1024];
unsigned long loadaddr;
unsigned long initrd_header[2];
int i;
int swab = 0;
if (argc != 4) {
printf ("Usage: %s <vmlinux> <initrd> <outfile>\n",argv[0]);
exit (1);
}
if ((fd_vmlinux = open (argv[1],O_RDWR)) < 0)
die ("open vmlinux");
if (read (fd_vmlinux, &efile, sizeof efile) != sizeof efile)
die ("read file header");
if (read (fd_vmlinux, &eaout, sizeof eaout) != sizeof eaout)
die ("read aout header");
if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs)
die ("read section headers");
/*
* check whether the file is good for us
*/
/* TBD */
/*
* check, if we have to swab words
*/
if (ntohs(0xaa55) == 0xaa55) {
if (efile.f_magic == swab16(MIPSELMAGIC))
swab = 1;
} else {
if (efile.f_magic == swab16(MIPSEBMAGIC))
swab = 1;
}
if ((fd_initrd = open (argv[2], O_RDONLY)) < 0)
die ("open initrd");
if (fstat (fd_initrd, &st) < 0)
die ("fstat initrd");
loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
+ MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
loadaddr += MIPS_PAGE_SIZE;
initrd_header[0] = SWAB(0x494E5244);
initrd_header[1] = SWAB(st.st_size);
eaout.dsize = esecs[1].s_size = initrd_header[1] = SWAB(st.st_size+8);
eaout.data_start = esecs[1].s_vaddr = esecs[1].s_paddr = SWAB(loadaddr);
if ((fd_outfile = open (argv[3], O_RDWR|O_CREAT|O_TRUNC,0666)) < 0)
die ("open outfile");
if (write (fd_outfile, &efile, sizeof efile) != sizeof efile)
die ("write file header");
if (write (fd_outfile, &eaout, sizeof eaout) != sizeof eaout)
die ("write aout header");
if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs)
die ("write section headers");
while ((i = read (fd_vmlinux, buf, sizeof buf)) > 0)
if (write (fd_outfile, buf, i) != i)
die ("write vmlinux");
if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header)
die ("write initrd header");
while ((i = read (fd_initrd, buf, sizeof buf)) > 0)
if (write (fd_outfile, buf, i) != i)
die ("write initrd");
close (fd_vmlinux);
close (fd_initrd);
return 0;
}
/*
* Some ECOFF definitions.
*/
typedef struct filehdr {
unsigned short f_magic; /* magic number */
unsigned short f_nscns; /* number of sections */
long f_timdat; /* time & date stamp */
long f_symptr; /* file pointer to symbolic header */
long f_nsyms; /* sizeof(symbolic hdr) */
unsigned short f_opthdr; /* sizeof(optional hdr) */
unsigned short f_flags; /* flags */
} FILHDR;
#define FILHSZ sizeof(FILHDR)
#define OMAGIC 0407
#define MIPSEBMAGIC 0x160
#define MIPSELMAGIC 0x162
typedef struct scnhdr {
char s_name[8]; /* section name */
long s_paddr; /* physical address, aliased s_nlib */
long s_vaddr; /* virtual address */
long s_size; /* section size */
long s_scnptr; /* file ptr to raw data for section */
long s_relptr; /* file ptr to relocation */
long s_lnnoptr; /* file ptr to gp histogram */
unsigned short s_nreloc; /* number of relocation entries */
unsigned short s_nlnno; /* number of gp histogram entries */
long s_flags; /* flags */
} SCNHDR;
#define SCNHSZ sizeof(SCNHDR)
#define SCNROUND ((long)16)
typedef struct aouthdr {
short magic; /* see above */
short vstamp; /* version stamp */
long tsize; /* text size in bytes, padded to DW bdry*/
long dsize; /* initialized data " " */
long bsize; /* uninitialized data " " */
long entry; /* entry pt. */
long text_start; /* base of text used for this file */
long data_start; /* base of data used for this file */
long bss_start; /* base of bss used for this file */
long gprmask; /* general purpose register mask */
long cprmask[4]; /* co-processor register masks */
long gp_value; /* the gp value used for this object */
} AOUTHDR;
#define AOUTHSZ sizeof(AOUTHDR)
#define OMAGIC 0407
#define NMAGIC 0410
#define ZMAGIC 0413
#define SMAGIC 0411
#define LIBMAGIC 0443
#define N_TXTOFF(f, a) \
((a).magic == ZMAGIC || (a).magic == LIBMAGIC ? 0 : \
((a).vstamp < 23 ? \
((FILHSZ + AOUTHSZ + (f).f_nscns * SCNHSZ + 7) & 0xfffffff8) : \
((FILHSZ + AOUTHSZ + (f).f_nscns * SCNHSZ + SCNROUND-1) & ~(SCNROUND-1)) ) )
#define N_DATOFF(f, a) \
N_TXTOFF(f, a) + (a).tsize;
This diff is collapsed.
#
# $Id: config.in,v 1.27 1999/06/17 13:25:44 ralf Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
......@@ -14,6 +14,8 @@ comment 'Machine selection'
bool 'Support for Acer PICA 1 chipset' CONFIG_ACER_PICA_61
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'Support for Algorithmics P4032' CONFIG_ALGOR_P4032
bool 'Support for BAGET MIPS series' CONFIG_BAGET_MIPS
bool 'Support for DECstations' CONFIG_DECSTATION
fi
bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000
bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
......@@ -33,14 +35,13 @@ fi
if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
"$CONFIG_OLIVETTI_M700" = "y" ]; then
define_bool CONFIG_MIPS_JAZZ y
define_bool CONFIG_VIDEO_G364 y
define_bool CONFIG_VGA_CONSOLE y
define_bool CONFIG_FB y
define_bool CONFIG_FB_G364 y
fi
if [ "$CONFIG_ACER_PICA_61" = "y" ]; then
define_bool CONFIG_MIPS_JAZZ y
fi
if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
define_bool CONFIG_VGA_CONSOLE y
define_bool CONFIG_PCI y
fi
endmenu
......@@ -61,14 +62,23 @@ endmenu
mainmenu_option next_comment
comment 'General setup'
if [ "$CONFIG_PCI" = "y" ]; then
bool ' PCI quirks' CONFIG_PCI_QUIRKS
if [ "$CONFIG_PCI_QUIRKS" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
fi
bool ' Backward-compatible /proc/pci' CONFIG_PCI_OLD_PROC
fi
if [ "$CONFIG_DECSTATION" = "y" ]; then
bool 'Compile the kernel into the ECOFF object format' CONFIG_ECOFF_KERNEL
define_bool CONFIG_CPU_LITTLE_ENDIAN y
else
define_bool CONFIG_ELF_KERNEL y
bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
fi
define_bool CONFIG_ELF_KERNEL y
if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
define_bool CONFIG_BINFMT_IRIX y
define_bool CONFIG_FORWARD_KEYBOARD y
......@@ -82,7 +92,7 @@ bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
bool 'Sysctl support' CONFIG_SYSCTL
if [ "$CONFIG_SGI" != "y" ]; then
if [ "$CONFIG_SGI" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then
tristate 'Parallel port support' CONFIG_PARPORT
fi
endmenu
......@@ -101,6 +111,20 @@ fi
endmenu
if [ "$CONFIG_DECSTATION" = "y" ]; then
mainmenu_option next_comment
comment 'TURBOchannel support'
bool 'TURBOchannel support' CONFIG_TC
# if [ "$CONFIG_TC" = "y" ]; then
# tristate 'MAGMA Parallel port support' CONFIG_PARPORT
# fi
endmenu
fi
source drivers/i2o/Config.in
source drivers/pnp/Config.in
source drivers/block/Config.in
if [ "$CONFIG_NET" = "y" ]; then
......@@ -113,7 +137,7 @@ comment 'SCSI support'
tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then
if [ "$CONFIG_SGI" = "y" ]; then
if [ "$CONFIG_SGI" = "y" -o "$CONFIG_DECSTATION" = "y" ]; then
comment 'SCSI support type (disk, tape, CDrom)'
dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
......@@ -129,8 +153,14 @@ if [ "$CONFIG_SCSI" != "n" ]; then
#mainmenu_option next_comment
comment 'SCSI low-level drivers'
if [ "$CONFIG_SGI" = "y" ]; then
dep_tristate 'SGI wd93 Scsi Driver' CONFIG_SCSI_SGIWD93 $CONFIG_SCSI
else
if [ "$CONFIG_TC" = "y" ]; then
dep_tristate 'DEC NCR53C94 Scsi Driver' CONFIG_SCSI_DECNCR $CONFIG_SCSI
fi
dep_tristate 'DEC SII Scsi Driver' CONFIG_SCSI_DECSII $CONFIG_SCSI
fi
else
source drivers/scsi/Config.in
fi
......@@ -143,7 +173,7 @@ if [ "$CONFIG_NET" = "y" ]; then
bool 'Network device support' CONFIG_NETDEVICES
if [ "$CONFIG_NETDEVICES" = "y" ]; then
if [ "$CONFIG_SGI" != "y" ]; then
if [ "$CONFIG_SGI" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then
source drivers/net/Config.in
else
tristate 'Dummy net driver support' CONFIG_DUMMY
......@@ -156,52 +186,113 @@ if [ "$CONFIG_NET" = "y" ]; then
if [ ! "$CONFIG_PPP" = "n" ]; then
comment 'CCP compressors for PPP are only built as modules.'
fi
if [ "$CONFIG_SGI" = "y" ]; then
bool 'SGI Seeq ethernet controller support' CONFIG_SGISEEQ
fi
if [ "$CONFIG_DECSTATION" = "y" ]; then
bool 'DEC LANCE ethernet controller support' CONFIG_DECLANCE
fi
if [ "$CONFIG_BAGET_MIPS" = "y" ]; then
tristate 'Baget AMD LANCE support' CONFIG_BAGETLANCE
tristate 'Baget Backplane Shared Memory support' CONFIG_BAGETBSM
fi
fi
fi
endmenu
fi
if [ "$CONFIG_SGI" != "y" ]; then
source drivers/net/hamradio/Config.in
if [ "$CONFIG_SGI" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then
source drivers/net/hamradio/Config.in
mainmenu_option next_comment
comment 'ISDN subsystem'
tristate 'ISDN support' CONFIG_ISDN
if [ "$CONFIG_ISDN" != "n" ]; then
source drivers/isdn/Config.in
fi
endmenu
mainmenu_option next_comment
comment 'ISDN subsystem'
mainmenu_option next_comment
comment 'Old CD-ROM drivers (not SCSI, not IDE)'
if [ "$CONFIG_NET" != "n" ]; then
tristate 'ISDN support' CONFIG_ISDN
if [ "$CONFIG_ISDN" != "n" ]; then
source drivers/isdn/Config.in
fi
fi
endmenu
bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
source drivers/cdrom/Config.in
fi
endmenu
mainmenu_option next_comment
comment comment 'Old CD-ROM drivers (not SCSI, not IDE)'
bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
source drivers/cdrom/Config.in
fi
endmenu
fi
source drivers/char/Config.in
if [ "$CONFIG_DECSTATION" != "y" ]; then
source drivers/char/Config.in
else
mainmenu_option next_comment
comment 'DECstation Character devices'
bool 'Virtual terminal' CONFIG_VT
if [ "$CONFIG_VT" = "y" ]; then
bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
fi
tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
if [ "$CONFIG_SGI" = "y" ]; then
bool 'SGI PROM Console Support' CONFIG_SGI_PROM_CONSOLE
fi
if [ "$CONFIG_SERIAL" = "y" ]; then
bool 'DZ11 Serial Support' CONFIG_DZ
if [ "$CONFIG_TC" = "y" ]; then
bool 'Z85C30 Serial Support' CONFIG_ZS
fi
bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE
fi
bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
fi
bool 'Keyboard Support' CONFIG_KEYBOARD
bool 'Mouse Support' CONFIG_MOUSE
# bool 'Enhanced Real Time Clock Support' CONFIG_RTC
endmenu
fi
source drivers/usb/Config.in
source fs/Config.in
comment 'Console drivers'
source drivers/video/Config.in
if [ "$CONFIG_VT" = "y" ]; then
mainmenu_option next_comment
comment 'Console drivers'
if [ "$CONFIG_SGI" = "y" ]; then
tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then
define_bool CONFIG_DUMMY_CONSOLE y
fi
else
if [ "$CONFIG_DECSTATION" != "y" ]; then
bool 'VGA text console' CONFIG_VGA_CONSOLE
fi
bool 'Support for frame buffer devices' CONFIG_FB
source drivers/video/Config.in
fi
endmenu
fi
mainmenu_option next_comment
comment 'Sound'
if [ "$CONFIG_DECSTATION" != "y" ]; then
mainmenu_option next_comment
comment 'Sound'
tristate 'Sound card support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then
tristate 'Sound card support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then
source drivers/sound/Config.in
fi
endmenu
fi
endmenu
if [ "$CONFIG_SGI" = "y" ]; then
source drivers/sgi/char/Config.in
source drivers/sgi/Config.in
fi
mainmenu_option next_comment
......@@ -212,6 +303,8 @@ bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
if [ "$CONFIG_MODULES" = "y" ]; then
bool ' Build fp execption handler module' CONFIG_MIPS_FPE_MODULE
fi
bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
if [ "$CONFIG_SERIAL" = "y" ]; then
bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
fi
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
endmenu
#
# Makefile for the DECstation family specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
.S.s:
$(CPP) $(CFLAGS) $< -o $*.s
.S.o:
$(CC) $(CFLAGS) -c $< -o $*.o
all: dec.o
O_TARGET := dec.o
O_OBJS := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o wbflush.o
ifdef CONFIG_PROM_CONSOLE
O_OBJS += promcon.o
endif
ifdef CONFIG_SERIAL
O_OBJS += serial.o
endif
int-handler.o: int-handler.S
clean:
include $(TOPDIR)/Rules.make
#
# Makefile for the DECstation family specific parts of the kernel
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
.S.s:
$(CPP) $(CFLAGS) $< -o $*.s
.S.o:
$(CC) $(CFLAGS) -c $< -o $*.o
netboot: all
mipsel-linux-ld -N -G 0 -T ld.ecoff ../../boot/zImage \
dec_boot.o ramdisk.img -o nbImage
all: dec_boot.o
O_TARGET := dec_boot.o
O_OBJS := decstation.o
clean:
rm -f nbImage
include $(TOPDIR)/Rules.make
/*
* arch/mips/dec/decstation.c
*/
#include <linux/config.h>
#define RELOC
#define INITRD
#define DEBUG_BOOT
/*
* Magic number indicating REX PROM available on DECSTATION.
*/
#define REX_PROM_MAGIC 0x30464354
#define REX_PROM_CLEARCACHE 0x7c/4
#define REX_PROM_PRINTF 0x30/4
#define VEC_RESET 0xBFC00000 /* Prom base address */
#define PMAX_PROM_ENTRY(x) (VEC_RESET+((x)*8)) /* Prom jump table */
#define PMAX_PROM_PRINTF PMAX_PROM_ENTRY(17)
#define PARAM (k_start + 0x2000)
#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
#define INITRD_START (*(unsigned long *) (PARAM+0x218))
#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
extern int _ftext, _end; /* begin and end of kernel image */
extern void *__rd_start, *__rd_end; /* begin and end of ramdisk image */
extern void kernel_entry(int, char **, unsigned long, int *);
void * memcpy(void * dest, const void *src, unsigned int count)
{
unsigned long *tmp = (unsigned long *) dest, *s = (unsigned long *) src;
count >>= 2;
while (count--)
*tmp++ = *s++;
return dest;
}
void dec_entry(int argc, char **argv,
unsigned long magic, int *prom_vec)
{
void (*rex_clear_cache)(void);
int (*prom_printf)(char *, ...);
unsigned long k_start, len;
/*
* The DS5100 leaves cpu with BEV enabled, clear it.
*/
asm( "lui\t$8,0x3000\n\t"
"mtc0\t$8,$12\n\t"
".section\t.sdata\n\t"
".section\t.sbss\n\t"
".section\t.text"
: : : "$8");
#ifdef DEBUG_BOOT
if (magic == REX_PROM_MAGIC) {
prom_printf = (int (*)(char *, ...)) *(prom_vec + REX_PROM_PRINTF);
} else {
prom_printf = (int (*)(char *, ...)) PMAX_PROM_PRINTF;
}
prom_printf("Launching kernel...\n");
#endif
k_start = (unsigned long) (&kernel_entry) & 0xffff0000;
#ifdef RELOC
/*
* Now copy kernel image to it's destination.
*/
len = ((unsigned long) (&_end) - k_start);
memcpy((void *)k_start, &_ftext, len);
#endif
if (magic == REX_PROM_MAGIC) {
rex_clear_cache = (void (*)(void)) * (prom_vec + REX_PROM_CLEARCACHE);
rex_clear_cache();
}
#ifdef CONFIG_BLK_DEV_INITRD
LOADER_TYPE = 1;
INITRD_START = (long)&__rd_start;
INITRD_SIZE = (long)&__rd_end - (long)&__rd_start;
#endif
kernel_entry(argc, argv, magic, prom_vec);
}
OUTPUT_FORMAT("ecoff-littlemips")
OUTPUT_ARCH(mips)
ENTRY(dec_entry)
SECTIONS
{
. = 0x80200000;
.text :
{
_ftext = .;
*(.text)
*(.fixup)
}
.rdata :
{
*(.rodata .rdata)
}
.data :
{
. = ALIGN(0x1000);
ramdisk.img (.data)
*(.data)
}
.sdata :
{
*(.sdata)
}
_gp = .;
.sbss :
{
*(.sbss)
*(.scommon)
}
.bss :
{
*(.dynbss)
*(.bss)
*(COMMON)
}
/DISCARD/ : {
*(.reginfo .mdebug .note)
}
}
/*
* arch/mips/dec/int-handler.S
*
* Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
*
* Written by Ralf Baechle and Andreas Busse, modified for DECStation
* support by Paul Antoine and Harald Koerfgen.
*
* completly rewritten:
* Copyright (C) 1998 Harald Koerfgen
*
*/
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
#include <asm/addrspace.h>
#include <asm/dec/interrupts.h>
.text
.set noreorder
/*
* decstation_handle_int: Interrupt handler for DECStations
*
* FIXME: Detection of spurious interrupts not yet implemented!
*
* We follow the model in the Indy interrupt code by David Miller, where he
* says: a lot of complication here is taken away because:
*
* 1) We handle one interrupt and return, sitting in a loop
* and moving across all the pending IRQ bits in the cause
* register is _NOT_ the answer, the common case is one
* pending IRQ so optimize in that direction.
*
* 2) We need not check against bits in the status register
* IRQ mask, that would make this routine slow as hell.
*
* 3) Linux only thinks in terms of all IRQs on or all IRQs
* off, nothing in between like BSD spl() brain-damage.
*
* Furthermore, the IRQs on the DECStations look basically (barring
* software IRQs which we don't use at all) like...
*
* DS2100/3100's, aka kn01, aka Pmax:
*
* MIPS IRQ Source
* -------- ------
* 0 Software (ignored)
* 1 Software (ignored)
* 2 SCSI
* 3 Lance Ethernet
* 4 DZ11 serial
* 5 RTC
* 6 Memory Controller
* 7 FPU
*
* DS5000/200, aka kn02, aka 3max:
*
* MIPS IRQ Source
* -------- ------
* 0 Software (ignored)
* 1 Software (ignored)
* 2 TurboChannel
* 3 RTC
* 4 Reserved
* 5 Memory Controller
* 6 Reserved
* 7 FPU
*
* DS5000/1xx's, aka kn02ba, aka 3min:
*
* MIPS IRQ Source
* -------- ------
* 0 Software (ignored)
* 1 Software (ignored)
* 2 TurboChannel Slot 0
* 3 TurboChannel Slot 1
* 4 TurboChannel Slot 2
* 5 TurboChannel Slot 3 (ASIC)
* 6 Halt button
* 7 FPU
*
* DS5000/2x's, aka kn02ca, aka maxine:
*
* MIPS IRQ Source
* -------- ------
* 0 Software (ignored)
* 1 Software (ignored)
* 2 Periodic Interrupt (100usec)
* 3 RTC
* 4 I/O write timeout
* 5 TurboChannel (ASIC)
* 6 Halt Keycode from Access.Bus keyboard (CTRL-ALT-ENTER)
* 7 FPU
*
* DS5000/2xx's, aka kn03, aka 3maxplus:
*
* MIPS IRQ Source
* -------- ------
* 0 Software (ignored)
* 1 Software (ignored)
* 2 System Board (ASIC)
* 3 RTC
* 4 Reserved
* 5 Memory
* 6 Halt Button
* 7 FPU
*
* We handle the IRQ according to _our_ priority.
* Priority is:
*
* Highest ---- RTC
* SCSI (if separate from TC)
* Ethernet (if separate from TC)
* Serial (if separate from TC)
* TurboChannel (if there is one!)
* Memory Controller (execept kmin)
* Lowest ---- Halt (if there is one!)
*
* then we just return, if multiple IRQs are pending then we will just take
* another exception, big deal.
*
*/
.align 5
NESTED(decstation_handle_int, PT_SIZE, ra)
.set noat
SAVE_ALL
CLI # TEST: interrupts should be off
.set at
.set noreorder
/*
* Get pending Interrupts
*/
mfc0 t0,CP0_CAUSE # get pending interrupts
mfc0 t2,CP0_STATUS
la t1,cpu_mask_tbl
and t0,t2 # isolate allowed ones
/* insert detection of spurious interrupts here */
/*
* Find irq with highest priority
*/
1: lw t2,(t1)
move t3,t0
and t3,t2
beq t3,zero,1b
addu t1,PTRSIZE # delay slot
/*
* Do the low-level stuff
*/
lw a0,%lo(cpu_irq_nr-cpu_mask_tbl-PTRSIZE)(t1)
lw t0,%lo(cpu_ivec_tbl-cpu_mask_tbl-PTRSIZE)(t1)
bgez a0, handle_it # irq_nr >= 0?
# irq_nr < 0: a0 contains an address
nop
jr t0
nop # delay slot
/*
* Handle "IRQ Controller" Interrupts
* Masked Interrupts are still visible and have to be masked "by hand".
* %hi(KN02_CSR_ADDR) does not work so all addresses are hardcoded :-(.
*/
EXPORT(kn02_io_int)
kn02_io_int: lui t0,0xbff0 # get interrupt status and mask
lw t0,(t0)
la t1,asic_mask_tbl
move t3,t0
sll t3,16 # shift interrupt status
b find_int
and t0,t3 # mask out allowed ones
EXPORT(kn03_io_int)
kn03_io_int: lui t2,0xbf84 # upper part of IOASIC Address
lw t0,0x0110(t2) # get status: IOASIC isr
lw t3,0x0120(t2) # get mask: IOASIC isrm
la t1,asic_mask_tbl
b find_int
and t0,t3 # mask out allowed ones
EXPORT(kn02ba_io_int)
kn02ba_io_int: lui t2,0xbc04
lw t0,0x0110(t2) # IOASIC isr, works for maxine also
lw t3,0x0120(t2) # IOASIC isrm
la t1,asic_mask_tbl
and t0,t3
/*
* Find irq with highest priority
*/
find_int: lw t2,(t1)
move t3,t0
and t3,t2
beq zero,t3,find_int
addu t1,PTRSIZE # delay slot
/*
* Do the low-level stuff
*/
lw a0,%lo(asic_irq_nr-asic_mask_tbl-PTRSIZE)(t1)
nop
handle_it: jal do_IRQ
move a1,sp
j ret_from_irq
nop
END(decstation_handle_int)
/*
* Interrupt routines common to all DECStations first.
*/
EXPORT(dec_intr_fpu)
dec_intr_fpu: PANIC("Unimplemented FPU interrupt handler")
/*
* Halt interrupt
*/
EXPORT(intr_halt)
intr_halt: la k0,0xbc000000
jr k0
nop
/*
* Generic unimplemented interrupt routines - ivec_tbl is initialised to
* point all interrupts here. The table is then filled in by machine-specific
* initialisation in dec_setup().
*/
EXPORT(dec_intr_unimplemented)
dec_intr_unimplemented:
mfc0 a1,CP0_CAUSE # cheats way of printing an arg!
nop # to be sure...
PANIC("Unimplemented cpu interrupt! CP0_CAUSE: 0x%x");
EXPORT(asic_intr_unimplemented)
asic_intr_unimplemented:
move a1,t0 # cheats way of printing an arg!
PANIC("Unimplemented asic interrupt! ASIC ISR: 0x%x");
/*
* FIXME: This interrupt vector table is experimental. It is initialised with
* *_intr_unimplemented and filled in with the addresses of
* machine-specific interrupt routines in dec_setup() Paul 10/5/97.
*
* The mask_tbls contain the interrupt masks which are used. It is
* initialised with all possible interrupt status bits set, so that
* unused Interrupts are catched. Harald
*/
.data
EXPORT(cpu_mask_tbl)
cpu_mask_tbl:
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000 # these two are unlikely
.word 0x00000000 # to be used
.word 0x0000ff00 # End of list
EXPORT(cpu_irq_nr)
cpu_irq_nr:
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000 # these two are unlikely
.word 0x00000000 # to be used
.word 0x00ffffff # End of list
EXPORT(cpu_ivec_tbl)
cpu_ivec_tbl:
PTR dec_intr_unimplemented
PTR dec_intr_unimplemented
PTR dec_intr_unimplemented
PTR dec_intr_unimplemented
PTR dec_intr_unimplemented
PTR dec_intr_unimplemented
PTR dec_intr_unimplemented # these two are unlikely
PTR dec_intr_unimplemented # to be used
PTR dec_intr_unimplemented # EOL
EXPORT(asic_mask_tbl)
asic_mask_tbl:
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0xffffffff # EOL
EXPORT(asic_irq_nr)
asic_irq_nr:
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0xffffffff # EOL
/*
* Code to handle DECstation IRQs plus some generic interrupt stuff.
*
* Copyright (C) 1992 Linus Torvalds
* Copyright (C) 1994, 1995, 1996, 1997 Ralf Baechle
*
* $Id: irq.c,v 1.3 1999/04/11 17:06:16 harald Exp $
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/malloc.h>
#include <linux/random.h>
#include <asm/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/dec/interrupts.h>
extern volatile unsigned int *isr; /* address of the interrupt status register */
extern volatile unsigned int *imr; /* address of the interrupt mask register */
extern decint_t dec_interrupt[NR_INTS];
unsigned int local_bh_count[NR_CPUS];
unsigned int local_irq_count[NR_CPUS];
unsigned long spurious_count = 0;
static inline void mask_irq(unsigned int irq_nr)
{
unsigned int dummy;
if (dec_interrupt[irq_nr].iemask) { /* This is an ASIC interrupt */
*imr &= ~dec_interrupt[irq_nr].iemask;
dummy = *imr;
dummy = *imr;
} else /* This is a cpu interrupt */
set_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) & ~dec_interrupt[irq_nr].cpu_mask);
}
static inline void unmask_irq(unsigned int irq_nr)
{
unsigned int dummy;
if (dec_interrupt[irq_nr].iemask) { /* This is an ASIC interrupt */
*imr |= dec_interrupt[irq_nr].iemask;
dummy = *imr;
dummy = *imr;
}
set_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) | dec_interrupt[irq_nr].cpu_mask);
}
void disable_irq(unsigned int irq_nr)
{
unsigned long flags;
save_and_cli(flags);
mask_irq(irq_nr);
restore_flags(flags);
}
void enable_irq(unsigned int irq_nr)
{
unsigned long flags;
save_and_cli(flags);
unmask_irq(irq_nr);
restore_flags(flags);
}
/*
* Pointers to the low-level handlers: first the general ones, then the
* fast ones, then the bad ones.
*/
extern void interrupt(void);
static struct irqaction *irq_action[32] =
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
int get_irq_list(char *buf)
{
int i, len = 0;
struct irqaction *action;
for (i = 0; i < 32; i++) {
action = irq_action[i];
if (!action)
continue;
len += sprintf(buf + len, "%2d: %8d %c %s",
i, kstat.irqs[0][i],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action = action->next; action; action = action->next) {
len += sprintf(buf + len, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
len += sprintf(buf + len, "\n");
}
return len;
}
atomic_t __mips_bh_counter;
/*
* do_IRQ handles IRQ's that have been installed without the
* SA_INTERRUPT flag: it uses the full signal-handling return
* and runs with other interrupts enabled. All relatively slow
* IRQ's should use this format: notably the keyboard/timer
* routines.
*/
asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
{
struct irqaction *action;
int do_random, cpu;
cpu = smp_processor_id();
hardirq_enter(cpu);
kstat.irqs[cpu][irq]++;
mask_irq(irq);
action = *(irq + irq_action);
if (action) {
if (!(action->flags & SA_INTERRUPT))
__sti();
action = *(irq + irq_action);
do_random = 0;
do {
do_random |= action->flags;
action->handler(irq, action->dev_id, regs);
action = action->next;
} while (action);
if (do_random & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
unmask_irq(irq);
__cli();
}
hardirq_exit(cpu);
/* unmasking and bottom half handling is done magically for us. */
}
/*
* Idea is to put all interrupts
* in a single table and differenciate them just by number.
*/
int setup_dec_irq(int irq, struct irqaction *new)
{
int shared = 0;
struct irqaction *old, **p;
unsigned long flags;
p = irq_action + irq;
if ((old = *p) != NULL) {
/* Can't share interrupts unless both agree to */
if (!(old->flags & new->flags & SA_SHIRQ))
return -EBUSY;
/* Can't share interrupts unless both are same type */
if ((old->flags ^ new->flags) & SA_INTERRUPT)
return -EBUSY;
/* add new interrupt at end of irq queue */
do {
p = &old->next;
old = *p;
} while (old);
shared = 1;
}
if (new->flags & SA_SAMPLE_RANDOM)
rand_initialize_irq(irq);
save_and_cli(flags);
*p = new;
if (!shared) {
unmask_irq(irq);
}
restore_flags(flags);
return 0;
}
int request_irq(unsigned int irq,
void (*handler) (int, void *, struct pt_regs *),
unsigned long irqflags,
const char *devname,
void *dev_id)
{
int retval;
struct irqaction *action;
if (irq >= 32)
return -EINVAL;
if (!handler)
return -EINVAL;
action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL);
if (!action)
return -ENOMEM;
action->handler = handler;
action->flags = irqflags;
action->mask = 0;
action->name = devname;
action->next = NULL;
action->dev_id = dev_id;
retval = setup_dec_irq(irq, action);
if (retval)
kfree(action);
return retval;
}
void free_irq(unsigned int irq, void *dev_id)
{
struct irqaction *action, **p;
unsigned long flags;
if (irq > 39) {
printk("Trying to free IRQ%d\n", irq);
return;
}
for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
if (action->dev_id != dev_id)
continue;
/* Found it - now free it */
save_and_cli(flags);
*p = action->next;
if (!irq[irq_action])
mask_irq(irq);
restore_flags(flags);
kfree(action);
return;
}
printk("Trying to free free IRQ%d\n", irq);
}
unsigned long probe_irq_on(void)
{
/* TODO */
return 0;
}
int probe_irq_off(unsigned long irqs)
{
/* TODO */
return 0;
}
__initfunc(void init_IRQ(void))
{
irq_setup();
}
# $Id: $
# Makefile for the DECstation prom monitor library routines
# under Linux.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile...
.S.s:
$(CPP) $(CFLAGS) $< -o $*.s
.S.o:
$(CC) $(CFLAGS) -c $< -o $*.o
OBJS = init.o memory.o cmdline.o identify.o locore.o
all: rexlib.a
rexlib.a: $(OBJS)
$(AR) rcs rexlib.a $(OBJS)
sync
locore.o: locore.S
dep:
$(CPP) -M *.c > .depend
include $(TOPDIR)/Rules.make
/*
* cmdline.c: read the command line passed to us by the PROM.
*
* Copyright (C) 1998 Harald Koerfgen
*
* $Id: $
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/string.h>
#include <asm/bootinfo.h>
#include "prom.h"
#undef PROM_DEBUG
#ifdef PROM_DEBUG
extern int (*prom_printf)(char *, ...);
#endif
char arcs_cmdline[CL_SIZE];
__initfunc(void prom_init_cmdline(int argc, char **argv, unsigned long magic))
{
int start_arg, i;
/*
* collect args and prepare cmd_line
*/
if (magic != REX_PROM_MAGIC)
start_arg = 1;
else
start_arg = 2;
for (i = start_arg; i < argc; i++) {
strcat(arcs_cmdline, argv[i]);
if (i < (argc - 1))
strcat(arcs_cmdline, " ");
}
#ifdef PROM_DEBUG
prom_printf("arcs_cmdline: %s\n", &(arcs_cmdline[0]));
#endif
}
#ifndef DECTYPES
#define DECTYPES
#define DS2100_3100 1 /* DS2100/3100 Pmax */
#define DS5000_200 2 /* DS5000/200 3max */
#define DS5000_1XX 3 /* DS5000/1xx kmin */
#define DS5000_2X0 4 /* DS5000/2x0 3max+ */
#define DS5800 5 /* DS5800 Isis */
#define DS5400 6 /* DS5400 MIPSfair */
#define DS5000_XX 7 /* DS5000/xx maxine */
#define DS5500 11 /* DS5500 MIPSfair-2 */
#define DS5100 12 /* DS5100 MIPSmate */
#endif
/*
* identify.c: machine identification code.
*
* Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine
*
* $Id: $
*/
#include <linux/init.h>
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/bootinfo.h>
#include "dectypes.h"
#include "prom.h"
extern char *(*prom_getenv)(char *);
extern int (*prom_printf)(char *, ...);
extern int (*rex_getsysid)(void);
extern unsigned long mips_machgroup;
extern unsigned long mips_machtype;
__initfunc(void prom_identify_arch (unsigned int magic))
{
unsigned char dec_cpunum, dec_firmrev, dec_etc;
int dec_systype;
unsigned long dec_sysid;
if (magic != REX_PROM_MAGIC) {
dec_sysid = simple_strtoul(prom_getenv("systype"), (char **)0, 0);
} else {
dec_sysid = rex_getsysid();
if (dec_sysid == 0) {
prom_printf("Zero sysid returned from PROMs! Assuming PMAX-like machine.\n");
dec_sysid = 1;
}
}
dec_cpunum = (dec_sysid & 0xff000000) >> 24;
dec_systype = (dec_sysid & 0xff0000) >> 16;
dec_firmrev = (dec_sysid & 0xff00) >> 8;
dec_etc = dec_sysid & 0xff;
/* We're obviously one of the DEC machines */
mips_machgroup = MACH_GROUP_DEC;
/*
* FIXME: This may not be an exhaustive list of DECStations/Servers!
* Put all model-specific initialisation calls here.
*/
prom_printf("This DECstation is a ");
switch (dec_systype) {
case DS2100_3100:
prom_printf("DS2100/3100\n");
mips_machtype = MACH_DS23100;
break;
case DS5100: /* DS5100 MIPSMATE */
prom_printf("DS5100\n");
mips_machtype = MACH_DS5100;
break;
case DS5000_200: /* DS5000 3max */
prom_printf("DS5000/200\n");
mips_machtype = MACH_DS5000_200;
break;
case DS5000_1XX: /* DS5000/100 3min */
prom_printf("DS5000/1xx\n");
mips_machtype = MACH_DS5000_1XX;
break;
case DS5000_2X0: /* DS5000/240 3max+ */
prom_printf("DS5000/2x0\n");
mips_machtype = MACH_DS5000_2X0;
break;
case DS5000_XX: /* Personal DS5000/2x */
prom_printf("Personal DS5000/xx\n");
mips_machtype = MACH_DS5000_XX;
break;
case DS5800: /* DS5800 Isis */
prom_printf("DS5800\n");
mips_machtype = MACH_DS5800;
break;
case DS5400: /* DS5400 MIPSfair */
prom_printf("DS5400\n");
mips_machtype = MACH_DS5400;
break;
case DS5500: /* DS5500 MIPSfair-2 */
prom_printf("DS5500\n");
mips_machtype = MACH_DS5500;
break;
default:
prom_printf("unknown, id is %x", dec_systype);
mips_machtype = MACH_DSUNKNOWN;
break;
}
}
/*
* init.c: PROM library initialisation code.
*
* Copyright (C) 1998 Harald Koerfgen
*
* $Id: $
*/
#include <linux/init.h>
#include <linux/config.h>
#include "prom.h"
/*
* PROM Interface (whichprom.c)
*/
typedef struct {
int pagesize;
unsigned char bitmap[0];
} memmap;
int (*rex_bootinit)(void);
int (*rex_bootread)(void);
int (*rex_getbitmap)(memmap *);
unsigned long *(*rex_slot_address)(int);
void *(*rex_gettcinfo)(void);
int (*rex_getsysid)(void);
void (*rex_clear_cache)(void);
int (*prom_getchar)(void);
char *(*prom_getenv)(char *);
int (*prom_printf)(char *, ...);
int (*pmax_open)(char*, int);
int (*pmax_lseek)(int, long, int);
int (*pmax_read)(int, void *, int);
int (*pmax_close)(int);
extern void prom_meminit(unsigned int);
extern void prom_identify_arch(unsigned int);
extern void prom_init_cmdline(int, char **, unsigned long);
/*
* Detect which PROM's the DECSTATION has, and set the callback vectors
* appropriately.
*/
__initfunc(void which_prom(unsigned long magic, int *prom_vec))
{
/*
* No sign of the REX PROM's magic number means we assume a non-REX
* machine (i.e. we're on a DS2100/3100, DS5100 or DS5000/2xx)
*/
if (magic == REX_PROM_MAGIC)
{
/*
* Set up prom abstraction structure with REX entry points.
*/
rex_bootinit = (int (*)(void)) *(prom_vec + REX_PROM_BOOTINIT);
rex_bootread = (int (*)(void)) *(prom_vec + REX_PROM_BOOTREAD);
rex_getbitmap = (int (*)(memmap *)) *(prom_vec + REX_PROM_GETBITMAP);
prom_getchar = (int (*)(void)) *(prom_vec + REX_PROM_GETCHAR);
prom_getenv = (char *(*)(char *)) *(prom_vec + REX_PROM_GETENV);
rex_getsysid = (int (*)(void)) *(prom_vec + REX_PROM_GETSYSID);
rex_gettcinfo = (void *(*)(void)) *(prom_vec + REX_PROM_GETTCINFO);
prom_printf = (int (*)(char *, ...)) *(prom_vec + REX_PROM_PRINTF);
rex_slot_address = (unsigned long *(*)(int)) *(prom_vec + REX_PROM_SLOTADDR);
rex_clear_cache = (void (*)(void)) * (prom_vec + REX_PROM_CLEARCACHE);
}
else
{
/*
* Set up prom abstraction structure with non-REX entry points.
*/
prom_getchar = (int (*)(void)) PMAX_PROM_GETCHAR;
prom_getenv = (char *(*)(char *)) PMAX_PROM_GETENV;
prom_printf = (int (*)(char *, ...)) PMAX_PROM_PRINTF;
pmax_open = (int (*)(char *, int)) PMAX_PROM_OPEN;
pmax_lseek = (int (*)(int, long, int)) PMAX_PROM_LSEEK;
pmax_read = (int (*)(int, void *, int)) PMAX_PROM_READ;
pmax_close = (int (*)(int)) PMAX_PROM_CLOSE;
}
}
__initfunc(int prom_init(int argc, char **argv,
unsigned long magic, int *prom_vec))
{
/* Determine which PROM's we have (and therefore which machine we're on!) */
which_prom(magic, prom_vec);
if (magic == REX_PROM_MAGIC)
rex_clear_cache();
prom_meminit(magic);
prom_identify_arch(magic);
prom_init_cmdline(argc, argv, magic);
return 0;
}
/*
* locore.S
*/
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
.text
/*
* Simple general exception handling routine. This one is used for the
* Memory sizing routine for pmax machines. HK
*/
NESTED(genexcept_early, 0, sp)
.set noat
.set noreorder
mfc0 k0, CP0_STATUS
la k1, mem_err
sw k0,0(k1)
mfc0 k0, CP0_EPC
nop
addiu k0,4 # skip the causing instruction
jr k0
rfe
END(genexcept_early)
/*
* memory.c: memory initialisation code.
*
* Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine
*
* $Id: $
*/
#include <asm/addrspace.h>
#include <linux/init.h>
#include <linux/config.h>
#include <linux/string.h>
#include "prom.h"
typedef struct {
int pagesize;
unsigned char bitmap[0];
} memmap;
extern int (*rex_getbitmap)(memmap *);
#undef PROM_DEBUG
#ifdef PROM_DEBUG
extern int (*prom_printf)(char *, ...);
#endif
extern unsigned long mips_memory_upper;
volatile unsigned long mem_err = 0; /* So we know an error occured */
/*
* Probe memory in 4MB chunks, waiting for an error to tell us we've fallen
* off the end of real memory. Only suitable for the 2100/3100's (PMAX).
*/
#define CHUNK_SIZE 0x400000
__initfunc(unsigned long pmax_get_memory_size(void))
{
volatile unsigned char *memory_page, dummy;
char old_handler[0x80];
extern char genexcept_early;
/* Install exception handler */
memcpy(&old_handler, (void *)(KSEG0 + 0x80), 0x80);
memcpy((void *)(KSEG0 + 0x80), &genexcept_early, 0x80);
/* read unmapped and uncached (KSEG1)
* DECstations have at least 4MB RAM
* Assume less than 480MB of RAM, as this is max for 5000/2xx
* FIXME this should be replaced by the first free page!
*/
for (memory_page = (unsigned char *) KSEG1 + CHUNK_SIZE;
(mem_err== 0) && (memory_page < ((unsigned char *) KSEG1+0x1E000000));
memory_page += CHUNK_SIZE) {
dummy = *memory_page;
}
memcpy((void *)(KSEG0 + 0x80), &old_handler, 0x80);
return (unsigned long)memory_page - KSEG1 - CHUNK_SIZE;
}
/*
* Use the REX prom calls to get hold of the memory bitmap, and thence
* determine memory size.
*/
__initfunc(unsigned long rex_get_memory_size(void))
{
int i, bitmap_size;
unsigned long mem_size = 0;
memmap *bm;
/* some free 64k */
bm = (memmap *) 0x80028000;
bitmap_size = rex_getbitmap(bm);
for (i = 0; i < bitmap_size; i++) {
/* FIXME: very simplistically only add full sets of pages */
if (bm->bitmap[i] == 0xff)
mem_size += (8 * bm->pagesize);
}
return (mem_size);
}
__initfunc(void prom_meminit(unsigned int magic))
{
if (magic != REX_PROM_MAGIC)
mips_memory_upper = KSEG0 + pmax_get_memory_size();
else
mips_memory_upper = KSEG0 + rex_get_memory_size();
#ifdef PROM_DEBUG
prom_printf("mips_memory_upper: 0x%08x\n", mips_memory_upper);
#endif
}
/* Called from mem_init() to fixup the mem_map page settings. */
__initfunc(void prom_fixup_mem_map(unsigned long start, unsigned long end))
{
}
void prom_free_prom_memory (void)
{
}
This diff is collapsed.
This diff is collapsed.
/*
* $Id: reset.c,v 1.4 1999/04/11 17:06:16 harald Exp $
*
* Reset a DECstation machine.
*
*/
void (*back_to_prom)(void) = (void (*)(void))0xBFC00000;
void dec_machine_restart(char *command)
{
back_to_prom();
}
void dec_machine_halt(void)
{
back_to_prom();
}
void dec_machine_power_off(void)
{
/* DECstations don't have a software power switch */
back_to_prom();
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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