Commit ce0bc3ba authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.82

parent 5cf40909
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 81
SUBLEVEL = 82
ARCH = i386
......@@ -18,6 +18,7 @@ CC =gcc -D__KERNEL__ -I$(TOPDIR)/include
MAKE =make
CPP =$(CC) -E
AR =ar
NM =nm
STRIP =strip
all: do-it-all
......@@ -88,7 +89,7 @@ FILESYSTEMS =fs/filesystems.a
DRIVERS =drivers/block/block.a \
drivers/char/char.a \
drivers/net/net.a
LIBS =lib/lib.a
LIBS =$(TOPDIR)/lib/lib.a
SUBDIRS =kernel drivers mm fs net ipc lib
ifdef CONFIG_SCSI
......@@ -124,7 +125,7 @@ vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
$(FILESYSTEMS) \
$(DRIVERS) \
$(LIBS) -o vmlinux
nm vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System.map
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System.map
symlinks:
rm -f include/asm
......
......@@ -8,15 +8,28 @@
# Copyright (C) 1994 by Linus Torvalds
#
LINKFLAGS = -non_shared -T 0xfffffc0000304000 -N
NM := nm -B
LINKFLAGS = -non_shared -T 0xfffffc0000310000 -N
CFLAGS := $(CFLAGS) -mno-fp-regs
HEAD := arch/alpha/kernel/head.o
SUBDIRS := $(SUBDIRS) arch/alpha/kernel arch/alpha/lib
ARCHIVES := arch/alpha/kernel/kernel.o $(ARCHIVES)
LIBS := arch/alpha/lib/lib.a $(LIBS)
SUBDIRS := $(SUBDIRS) arch/alpha/kernel arch/alpha/mm arch/alpha/lib
ARCHIVES := arch/alpha/kernel/kernel.o arch/alpha/mm/mm.o $(ARCHIVES)
LIBS := $(TOPDIR)/arch/alpha/lib/lib.a $(LIBS) $(TOPDIR)/arch/alpha/lib/lib.a
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
#
# my boot writes directly to a specific disk partition, I doubt most
# people will want to do that without changes..
#
msb my-special-boot:
@$(MAKEBOOT) msb
archclean:
@$(MAKEBOOT) clean
archdep:
@$(MAKEBOOT) dep
......@@ -8,10 +8,46 @@
# Copyright (C) 1994 by Linus Torvalds
#
boot:
@echo Wait a few days for this one..
@exit 1
.c.s:
$(CC) $(CFLAGS) -S -o $*.s $<
.s.o:
$(AS) -o $*.o $<
.c.o:
$(CC) $(CFLAGS) -c -o $*.o $<
.S.s:
$(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $<
.S.o:
$(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $<
dep:
OBJECTS = head.o main.o
all:
@echo Be careful.. This works for me, not for you
msb: tools/lxboot tools/bootlx vmlinux
( cat tools/lxboot tools/bootlx vmlinux ) > /dev/rz0a
disklabel -rw rz0 'linux' tools/lxboot tools/bootlx
vmlinux: tools/build $(TOPDIR)/vmlinux
tools/build -v $(TOPDIR)/vmlinux > vmlinux
tools/lxboot: tools/build
tools/build > tools/lxboot
tools/bootlx: bootloader tools/build
tools/build -vb bootloader > tools/bootlx
tools/build: tools/build.c
$(HOSTCC) tools/build.c -o tools/build
bootloader: $(OBJECTS)
$(LD) -non_shared -T 0x20000000 -N \
$(OBJECTS) \
$(LIBS) \
-o bootloader || \
(rm -f bootloader && exit 1)
clean:
rm -f vmlinux bootloader tools/build tools/bootlx tools/lxboot
dep:
/*
* arch/alpha/boot/head.S
*
* initial bootloader stuff..
*/
#include <asm/system.h>
#define halt .long PAL_halt
.set noreorder
.globl __start
.ent __start
__start:
bis $31,$31,$31
br 1f
/* room for the initial PCB, which comes here */
.quad 0,0,0,0,0,0,0,0
1: br $27,2f
2: ldgp $29,0($27)
lda $27,start_kernel
jsr $26,($27),start_kernel
halt
.end __start
.align 5
.globl wrent
.ent wrent
wrent:
.long PAL_wrent
ret ($26)
.end wrent
.align 5
.globl wrkgp
.ent wrkgp
wrkgp:
.long PAL_wrkgp
ret ($26)
.end wrkgp
.align 5
.globl switch_to_osf_pal
.ent switch_to_osf_pal
switch_to_osf_pal:
subq $30,128,$30
stq $26,0($30)
stq $1,8($30)
stq $2,16($30)
stq $3,24($30)
stq $4,32($30)
stq $5,40($30)
stq $6,48($30)
stq $7,56($30)
stq $8,64($30)
stq $9,72($30)
stq $10,80($30)
stq $11,88($30)
stq $12,96($30)
stq $13,104($30)
stq $14,112($30)
stq $15,120($30)
stq $30,0($17) /* save KSP in PCB */
bis $30,$30,$20 /* a4 = KSP */
br $17,__do_swppal
ldq $26,0($30)
ldq $1,8($30)
ldq $2,16($30)
ldq $3,24($30)
ldq $4,32($30)
ldq $5,40($30)
ldq $6,48($30)
ldq $7,56($30)
ldq $8,64($30)
ldq $9,72($30)
ldq $10,80($30)
ldq $11,88($30)
ldq $12,96($30)
ldq $13,104($30)
ldq $14,112($30)
ldq $15,120($30)
addq $30,128,$30
ret ($26)
__do_swppal:
.long PAL_swppal
.end switch_to_osf_pal
.globl dispatch
.ent dispatch
dispatch:
subq $30,80,$30
stq $26,0($30)
stq $29,8($30)
stq $8,16($30)
stq $9,24($30)
stq $10,32($30)
stq $11,40($30)
stq $12,48($30)
stq $13,56($30)
stq $14,64($30)
stq $15,72($30)
lda $1,0x10000000 /* hwrpb */
ldq $2,0xc0($1) /* crb offset */
addq $2,$1,$2 /* crb */
ldq $27,0($2) /* dispatch procedure value */
ldq $2,8($27) /* dispatch call address */
jsr $26,($2) /* call it (weird VMS call seq) */
ldq $26,0($30)
ldq $29,8($30)
ldq $8,16($30)
ldq $9,24($30)
ldq $10,32($30)
ldq $11,40($30)
ldq $12,48($30)
ldq $13,56($30)
ldq $14,64($30)
ldq $15,72($30)
addq $30,80,$30
ret $31,($26)
.end dispatch
/*
* arch/alpha/boot/main.c
*
* Copyright (C) 1994, 1995 Linus Torvalds
*
* This file is the bootloader for the Linux/AXP kernel
*/
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/version.h>
#include <asm/system.h>
#include <asm/console.h>
#include <asm/hwrpb.h>
#include <asm/page.h>
#include <stdarg.h>
extern int vsprintf(char *, const char *, va_list);
extern unsigned long switch_to_osf_pal(unsigned long nr,
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
unsigned long vptb, unsigned long *kstk);
int printk(const char * fmt, ...)
{
va_list args;
int i;
static char buf[1024];
va_start(args, fmt);
i = vsprintf(buf, fmt, args);
va_end(args);
puts(buf,i);
return i;
}
#define hwrpb (*INIT_HWRPB)
/*
* Find a physical address of a virtual object..
*
* This is easy using the virtual page table address.
*/
struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
{
unsigned long address = (unsigned long) pcb;
unsigned long result;
result = vptb[address >> 13];
result >>= 32;
result <<= 13;
result |= address & 0x1fff;
return (struct pcb_struct *) result;
}
/*
* This function moves into OSF/1 pal-code, and has a temporary
* PCB for that. The kernel proper should replace this PCB with
* the real one as soon as possible.
*
* The page table muckery in here depends on the fact that the boot
* code has the L1 page table identity-map itself in the second PTE
* in the L1 page table. Thus the L1-page is virtually addressable
* itself (through three levels) at virtual address 0x200802000.
*
* As we don't want it there anyway, we also move the L1 self-map
* up as high as we can, so that the last entry in the L1 page table
* maps the page tables.
*
* As a result, the OSF/1 pal-code will instead use a virtual page table
* map located at 0xffffffe00000000.
*/
#define pcb_va ((struct pcb_struct *) 0x20000000)
#define old_vptb (0x0000000200000000UL)
#define new_vptb (0xfffffffe00000000UL)
void pal_init(void)
{
unsigned long i, rev;
unsigned long *L1;
struct percpu_struct * percpu;
struct pcb_struct * pcb_pa;
/* Find the level 1 page table and duplicate it in high memory */
L1 = (unsigned long *) 0x200802000UL;
L1[1023] = L1[1];
percpu = (struct percpu_struct *) (hwrpb.processor_offset + (unsigned long) &hwrpb),
pcb_va->ksp = 0;
pcb_va->usp = 0;
pcb_va->ptbr = L1[1] >> 32;
pcb_va->asn = 0;
pcb_va->pcc = 0;
pcb_va->unique = 0;
pcb_va->flags = 1;
pcb_pa = find_pa((unsigned long *) old_vptb, pcb_va);
printk("Switching to OSF PAL-code .. ");
/*
* a0 = 2 (OSF)
* a1 = return address, but we give the asm the virtual addr of the PCB
* a2 = physical addr of PCB
* a3 = new virtual page table pointer
* a4 = KSP (but we give it 0, asm sets it)
*/
i = switch_to_osf_pal(
2,
pcb_va,
pcb_pa,
new_vptb,
0);
if (i) {
printk("failed, code %ld\n", i);
halt();
}
rev = percpu->pal_revision = percpu->palcode_avail[2];
hwrpb.vptb = new_vptb;
printk("Ok (rev %lx)\n", rev);
/* remove the old virtual page-table mapping */
L1[1] = 0;
invalidate_all();
}
extern int _end;
static inline long openboot(void)
{
char bootdev[256];
long result;
result = dispatch(CCB_GET_ENV, ENV_BOOTED_DEV, bootdev, 255);
if (result < 0)
return result;
return dispatch(CCB_OPEN, bootdev, result & 255);
}
static inline long close(long dev)
{
return dispatch(CCB_CLOSE, dev);
}
static inline long load(long dev, unsigned long addr, unsigned long count)
{
char bootfile[256];
long result;
result = dispatch(CCB_GET_ENV, ENV_BOOTED_FILE, bootfile, 255);
if (result < 0)
return result;
result &= 255;
bootfile[result] = '\0';
if (result)
printk("Boot file specification (%s) not implemented\n", bootfile);
return dispatch(CCB_READ, dev, count, addr, BOOT_SIZE/512 + 1);
}
static void runkernel(void)
{
struct pcb_struct * init_pcb = (struct pcb_struct *) INIT_PCB;
*init_pcb = *pcb_va;
init_pcb->ksp = PAGE_SIZE + INIT_STACK;
__asm__ __volatile__(
"bis %0,%0,$26\n\t"
"bis %1,%1,$16\n\t"
".long %2\n\t"
"ret ($26)"
: /* no outputs: it doesn't even return */
: "r" (START_ADDR),
"r" (init_pcb),
"i" (PAL_swpctx)
: "$16","$26");
}
void start_kernel(void)
{
long i;
long dev;
printk("Linux/AXP bootloader for Linux " UTS_RELEASE "\n");
if (hwrpb.pagesize != 8192) {
printk("Expected 8kB pages, got %ldkB\n", hwrpb.pagesize >> 10);
return;
}
pal_init();
dev = openboot();
if (dev < 0) {
printk("Unable to open boot device: %016lx\n", dev);
return;
}
dev &= 0xffffffff;
printk("Loading vmlinux ...");
i = load(dev, START_ADDR, START_SIZE);
close(dev);
if (i != START_SIZE) {
printk("Failed (%lx)\n", i);
return;
}
printk(" Ok\nNow booting the kernel\n");
runkernel();
for (i = 0 ; i < 0x100000000 ; i++)
/* nothing */;
halt();
}
......@@ -12,12 +12,11 @@
#include <asm/system.h>
#define NR_SECTORS (START_SIZE / 512)
#define MAXSECT 10
#define MAXBUF 8192
int verbose = 0;
int pad = 0;
char * program = "tools/build";
char buffer[MAXBUF];
unsigned long bootblock[64];
......@@ -25,7 +24,7 @@ struct filehdr fhdr;
struct aouthdr ahdr;
struct scnhdr shdr[MAXSECT];
char * usage = "'build system > secondary' or 'build > primary'";
char * usage = "'build [-b] system > secondary' or 'build > primary'";
static void die(char * str)
{
......@@ -41,10 +40,12 @@ static int comp(struct scnhdr * a, struct scnhdr * b)
int main(int argc, char ** argv)
{
int fd, i;
unsigned long tmp;
unsigned long start;
unsigned long tmp, start;
unsigned long system_start, system_size;
char * infile = NULL;
system_start = START_ADDR;
system_size = START_SIZE;
if (argc) {
program = *(argv++);
argc--;
......@@ -53,6 +54,11 @@ int main(int argc, char ** argv)
if (**argv == '-') {
while (*++*argv) {
switch (**argv) {
case 'b':
system_start = BOOT_ADDR;
system_size = BOOT_SIZE;
pad = 1;
break;
case 'v':
verbose++;
break;
......@@ -69,12 +75,12 @@ int main(int argc, char ** argv)
}
if (!infile) {
memcpy(bootblock, "Linux Test", 10);
bootblock[60] = NR_SECTORS; /* count (32 kB) */
bootblock[61] = 1; /* starting LBM */
bootblock[62] = 0; /* flags */
bootblock[60] = BOOT_SIZE / 512; /* count */
bootblock[61] = 1; /* starting LBM */
bootblock[62] = 0; /* flags */
tmp = 0;
for (i = 0 ; i < 63 ; i++)
tmp += ~bootblock[i];
tmp += bootblock[i];
bootblock[63] = tmp;
if (write(1, (char *) bootblock, 512) != 512) {
perror("bbwrite");
......@@ -111,7 +117,7 @@ int main(int argc, char ** argv)
}
}
qsort(shdr, fhdr.f_nscns, sizeof(shdr[1]), comp);
start = START_ADDR;
start = system_start;
for (i = 0 ; i < fhdr.f_nscns ; i++) {
unsigned long size, offset;
memset(buffer, 0, MAXBUF);
......@@ -143,9 +149,25 @@ int main(int argc, char ** argv)
shdr[i].s_scnptr);
}
}
if (start > START_ADDR + NR_SECTORS*512) {
if (start > system_start + system_size) {
fprintf(stderr, "Boot image too large\n");
exit(1);
}
if (pad) {
unsigned long count = (system_start + system_size) - start;
memset(buffer, 0, MAXBUF);
while (count > 0) {
int i = MAXBUF;
if (i > count)
i = count;
i = write(1, buffer, i);
if (i <= 0) {
perror("pad write");
exit(1);
}
count -= i;
}
}
return 0;
}
......@@ -5,10 +5,10 @@
comment 'General setup'
bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD y
bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD n
bool 'Normal harddisk support' CONFIG_BLK_DEV_HD n
bool 'XT harddisk support' CONFIG_BLK_DEV_XD n
bool 'Networking support' CONFIG_NET y
bool 'Networking support' CONFIG_NET n
bool 'System V IPC' CONFIG_SYSVIPC n
bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
......
......@@ -18,7 +18,7 @@
.S.o:
$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
OBJS = entry.o traps.o
OBJS = entry.o traps.o process.o irq.o signal.o setup.o
all: kernel.o head.o
......
......@@ -9,52 +9,85 @@
#define halt .long PAL_halt
#define rti .long PAL_rti
/*
* This defines the normal kernel pt-regs layout.
*
* regs 9-15 preserved by C code
* regs 16-18 saved by PAL-code
* regs 29-30 saved and set up by PAL-code
*/
#define SAVE_ALL \
subq $30,160,$30; \
stq $0,0($30); \
stq $1,8($30); \
stq $2,16($30); \
stq $3,24($30); \
stq $4,32($30); \
stq $5,40($30); \
stq $6,48($30); \
stq $7,56($30); \
stq $8,64($30); \
stq $19,72($30); \
stq $20,80($30); \
stq $21,88($30); \
stq $22,96($30); \
stq $23,104($30); \
stq $24,112($30); \
stq $25,120($30); \
stq $26,128($30); \
stq $27,136($30); \
stq $28,144($30)
#define RESTORE_ALL \
ldq $0,0($30); \
ldq $1,8($30); \
ldq $2,16($30); \
ldq $3,24($30); \
ldq $4,32($30); \
ldq $5,40($30); \
ldq $6,48($30); \
ldq $7,56($30); \
ldq $8,64($30); \
ldq $19,72($30); \
ldq $20,80($30); \
ldq $21,88($30); \
ldq $22,96($30); \
ldq $23,104($30); \
ldq $24,112($30); \
ldq $25,120($30); \
ldq $26,128($30); \
ldq $27,136($30); \
ldq $28,144($30); \
addq $30,160,$30
.text
.set noat
.align 6
.ent entInt
.set noat
.align 5
.globl entInt
.ent entInt
entInt:
subq $30,144,$30
stq $0,0($30)
stq $1,8($30)
stq $2,16($30)
stq $3,24($30)
stq $4,32($30)
stq $5,40($30)
stq $6,48($30)
stq $7,56($30)
stq $8,64($30)
stq $19,64($30)
stq $20,72($30)
stq $21,80($30)
stq $22,88($30)
stq $23,96($30)
stq $24,104($30)
stq $25,112($30)
stq $26,120($30)
stq $27,128($30)
stq $28,136($30)
lda $27,do_hw_interrupt
jsr $26,($27),do_hw_interrupt
ldq $0,0($30)
ldq $1,8($30)
ldq $2,16($30)
ldq $3,24($30)
ldq $4,32($30)
ldq $5,40($30)
ldq $6,48($30)
ldq $7,56($30)
ldq $8,64($30)
ldq $19,64($30)
ldq $20,72($30)
ldq $21,80($30)
ldq $22,88($30)
ldq $23,96($30)
ldq $24,104($30)
ldq $25,112($30)
ldq $26,120($30)
ldq $27,128($30)
ldq $28,136($30)
addq $30,144,$30
SAVE_ALL
bis $30,$30,$19
lda $27,do_entInt
jsr $26,($27),do_entInt
RESTORE_ALL
rti
.end entInt
.align 5
.globl entMM
.ent entMM
entMM:
SAVE_ALL
bis $30,$30,$19
lda $27,do_page_fault
jsr $26,($27),do_page_fault
RESTORE_ALL
rti
.end entInt
.end entMM
.align 5
.globl sys_call_table
sys_call_table:
.quad 0
/*
* alpha/boot/head.S
*
* initial boot stuff..
* initial boot stuff.. At this point, the bootloader has already
* switched into OSF/1 PAL-code, and loaded us at the correct address
* (START_ADDR). So there isn't much left for us to do: just set up
* the kernel global pointer and jump to the kernel entry-point.
*/
#define __ASSEMBLY__
......@@ -9,37 +12,15 @@
#define halt .long PAL_halt
/*
* NOTE! The console bootstrap will load us at 0x20000000, but this image
* is linked to run at START_ADDR, so the first thing we do is to move
* ourself up to the right address.. We'd better be position-independent
* at that stage :-)
*/
.globl swapper_pg_dir
swapper_pg_dir=SWAPPER_PGD
.set noreorder
.globl __start
.ent __start
__start:
bis $31,$31,$31
br $1,$200
.long START_ADDR, START_ADDR >> 32 /* strange bug in the assembler.. duh */
.long START_SIZE, START_SIZE >> 32
$200: ldq $30,0($1) /* new stack - below this */
lda $2,-8($1) /* __start */
bis $30,$30,$3 /* new address */
subq $3,$2,$6 /* difference */
ldq $4,8($1) /* size */
$201: subq $4,8,$4
ldq $5,0($2)
addq $2,8,$2
stq $5,0($3)
addq $3,8,$3
bne $4,$201
br $1,$202
$202: addq $1,$6,$1
addq $1,12,$1 /* $203 in the new address space */
jmp $31,($1),$203
$203: br $27,$100
$100: ldgp $29,0($27)
br $27,1f
1: ldgp $29,0($27)
lda $27,start_kernel
jsr $26,($27),start_kernel
halt
......@@ -62,51 +43,19 @@ wrkgp:
.end wrkgp
.align 5
.globl switch_to_osf_pal
.ent switch_to_osf_pal
switch_to_osf_pal:
subq $30,128,$30
stq $26,0($30)
stq $1,8($30)
stq $2,16($30)
stq $3,24($30)
stq $4,32($30)
stq $5,40($30)
stq $6,48($30)
stq $7,56($30)
stq $8,64($30)
stq $9,72($30)
stq $10,80($30)
stq $11,88($30)
stq $12,96($30)
stq $13,104($30)
stq $14,112($30)
stq $15,120($30)
stq $30,0($17) /* save KSP in PCB */
bis $30,$30,$20 /* a4 = KSP */
br $17,__do_swppal
.globl wrusp
.ent wrusp
wrusp:
.long PAL_wrusp
ret ($26)
.end wrusp
ldq $26,0($30)
ldq $1,8($30)
ldq $2,16($30)
ldq $3,24($30)
ldq $4,32($30)
ldq $5,40($30)
ldq $6,48($30)
ldq $7,56($30)
ldq $8,64($30)
ldq $9,72($30)
ldq $10,80($30)
ldq $11,88($30)
ldq $12,96($30)
ldq $13,104($30)
ldq $14,112($30)
ldq $15,120($30)
addq $30,128,$30
.align 5
.globl rdusp
.ent rdusp
rdusp:
.long PAL_rdusp
ret ($26)
.end rdusp
__do_swppal:
.long PAL_swppal
.end switch_to_osf_pal
/*
* linux/arch/alpha/kernel/irq.c
*
* Copyright (C) 1995 Linus Torvalds
*
* This file contains the code used by various IRQ handling routines:
* asking for different IRQ's should be done through these routines
* instead of just grabbing them. Thus setups with different IRQ numbers
* shouldn't result in any weird surprises, and installing new handlers
* should be easier.
*/
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/bitops.h>
static unsigned char cache_21 = 0xff;
static unsigned char cache_A1 = 0xff;
void disable_irq(unsigned int irq_nr)
{
unsigned long flags;
unsigned char mask;
mask = 1 << (irq_nr & 7);
save_flags(flags);
if (irq_nr < 8) {
cli();
cache_21 |= mask;
outb(cache_21,0x21);
restore_flags(flags);
return;
}
cli();
cache_A1 |= mask;
outb(cache_A1,0xA1);
restore_flags(flags);
}
void enable_irq(unsigned int irq_nr)
{
unsigned long flags;
unsigned char mask;
mask = ~(1 << (irq_nr & 7));
save_flags(flags);
if (irq_nr < 8) {
cli();
cache_21 &= mask;
outb(cache_21,0x21);
restore_flags(flags);
return;
}
cli();
cache_A1 &= mask;
outb(cache_A1,0xA1);
restore_flags(flags);
}
/*
* Initial irq handlers.
*/
struct irqaction {
void (*handler)(int, struct pt_regs *);
unsigned long flags;
unsigned long mask;
const char *name;
};
static struct irqaction irq_action[16] = {
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
};
int get_irq_list(char *buf)
{
int i, len = 0;
struct irqaction * action = irq_action;
for (i = 0 ; i < 16 ; i++, action++) {
if (!action->handler)
continue;
len += sprintf(buf+len, "%2d: %8d %c %s\n",
i, kstat.interrupts[i],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
}
return len;
}
int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
unsigned long irqflags, const char * devname)
{
struct irqaction * action;
unsigned long flags;
if (irq > 15)
return -EINVAL;
action = irq + irq_action;
if (action->handler)
return -EBUSY;
if (!handler)
return -EINVAL;
save_flags(flags);
cli();
action->handler = handler;
action->flags = irqflags;
action->mask = 0;
action->name = devname;
if (irq < 8) {
cache_21 &= ~(1<<irq);
outb(cache_21,0x21);
} else {
cache_21 &= ~(1<<2);
cache_A1 &= ~(1<<(irq-8));
outb(cache_21,0x21);
outb(cache_A1,0xA1);
}
restore_flags(flags);
return 0;
}
void free_irq(unsigned int irq)
{
halt();
}
static void handle_irq(int irq, struct pt_regs * regs)
{
struct irqaction * action = irq + irq_action;
kstat.interrupts[irq]++;
if (action->handler)
action->handler(irq, regs);
}
/*
* I don't have any good documentation on the EISA hardware interrupt
* stuff: I don't know the mapping between the interrupt vector and the
* EISA interrupt number.
*
* It *seems* to be 0x8X0 for EISA interrupt X, and 0x9X0 for the
* local motherboard interrupts..
*
* 0x660 - NMI?
*
* 0x800 - ??? I've gotten this, but EISA irq0 shouldn't happen
* as the timer is not on the EISA bus
*
* 0x860 - ??? floppy disk (EISA irq6)
*
* 0x900 - ??? I get this at autoprobing when the EISA serial
* lines com3/com4 don't exist. It keeps coming after
* that..
*
* 0x980 - keyboard
* 0x990 - mouse
*
* We'll see..
*/
static void device_interrupt(unsigned long vector, struct pt_regs * regs)
{
int i;
static int nr = 0;
if (vector == 0x980 && irq_action[1].handler) {
handle_irq(1, regs);
return;
}
if (nr > 3)
return;
nr++;
printk("IO device interrupt, vector = %lx\n", vector);
printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
printk("Expecting: ");
for (i = 0; i < 16; i++)
if (irq_action[i].handler)
printk("[%s:%d] ", irq_action[i].name, i);
printk("\n");
printk("64=%02x, 60=%02x, 3fa=%02x 2fa=%02x\n",
inb(0x64), inb(0x60), inb(0x3fa), inb(0x2fa));
printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
}
static void machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs)
{
printk("Machine check\n");
}
asmlinkage void do_entInt(unsigned long type, unsigned long vector,
unsigned long la_ptr, struct pt_regs *regs)
{
switch (type) {
case 0:
printk("Interprocessor interrupt? You must be kidding\n");
break;
case 1:
/* timer interrupt.. */
handle_irq(0, regs);
return;
case 2:
machine_check(vector, la_ptr, regs);
break;
case 3:
device_interrupt(vector, regs);
return;
case 4:
printk("Performance counter interrupt\n");
break;;
default:
printk("Hardware intr %ld %lx? Huh?\n", type, vector);
}
printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
}
extern asmlinkage void entInt(void);
void init_IRQ(void)
{
wrent(entInt, 0);
}
/*
* linux/arch/alpha/kernel/process.c
*
* Copyright (C) 1995 Linus Torvalds
*/
/*
* This file handles the architecture-dependent parts of process handling..
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
#include <linux/ldt.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/io.h>
asmlinkage int sys_idle(void)
{
if (current->pid != 0)
return -EPERM;
/* endless idle loop with no priority at all */
current->counter = -100;
for (;;) {
schedule();
}
}
void hard_reset_now(void)
{
halt();
}
/*
* Do necessary setup to start up a newly executed thread.
*/
void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
{
regs->pc = pc;
wrusp(sp);
}
/*
* Free current thread data structures etc..
*/
void exit_thread(void)
{
halt();
}
void flush_thread(void)
{
halt();
}
/*
* This needs lots of work still..
*/
unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
p->tss.usp = rdusp();
childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1;
*childregs = *regs;
p->tss.ksp = (unsigned long) childregs;
/* p->tss.pc = XXXX; */
halt();
return clone_flags;
}
/*
* fill in the user structure for a core dump..
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
}
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(struct pt_regs regs)
{
halt();
return 0;
}
/*
* linux/arch/alpha/kernel/setup.c
*
* Copyright (C) 1995 Linus Torvalds
*/
/*
* bootup setup stuff..
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
#include <linux/ldt.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/tty.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/hwrpb.h>
#include <asm/io.h>
unsigned char aux_device_present;
/*
* XXXXX!! Warning Will Robinson.
* Danger! Danger! This is bogus, I'll get it to link if it kills me
*/
unsigned char floppy_track_buffer[256];
/*
* The format of "screen_info" is strange, and due to early
* i386-setup code. This is just enough to make the console
* code think we're on a EGA+ colour display.
*/
struct screen_info screen_info = {
0, 0, /* orig-x, orig-y */
0, 0, /* unused */
0, /* orig-video-page */
0, /* orig-video-mode */
80, /* orig-video-cols */
0,0,0, /* ega_ax, ega_bx, ega_cx */
25 /* orig-video-lines */
};
unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
{
return memory_start;
}
static unsigned long find_end_memory(void)
{
int i;
unsigned long high = 0;
struct memclust_struct * cluster;
struct memdesc_struct * memdesc;
memdesc = (struct memdesc_struct *) (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
cluster = memdesc->cluster;
for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
unsigned long tmp;
if (cluster->usage & 1)
continue;
tmp = (cluster->start_pfn + cluster->numpages) << PAGE_SHIFT;
if (tmp > high)
high = tmp;
}
return PAGE_OFFSET + high;
}
void setup_arch(char **cmdline_p,
unsigned long * memory_start_p, unsigned long * memory_end_p)
{
static char cmdline[] = "";
extern int _end;
aux_device_present = 0xaa;
*cmdline_p = cmdline;
*memory_start_p = (unsigned long) &_end;
*memory_end_p = find_end_memory();
}
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
{
return -EIO;
}
/*
* linux/arch/alpha/kernel/signal.c
*
* Copyright (C) 1995 Linus Torvalds
*/
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <asm/segment.h>
#define _S(nr) (1<<((nr)-1))
#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
/*
* atomically swap in the new signal mask, and wait for a signal.
*/
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, unsigned long set)
{
unsigned long mask;
struct pt_regs * regs = (struct pt_regs *) &restart;
halt();
mask = current->blocked;
current->blocked = set & _BLOCKABLE;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
if (do_signal(mask,regs))
return -EINTR;
}
}
/*
* this should do a signal return with the info on the stack..
*/
asmlinkage int sys_sigreturn(unsigned long __unused)
{
halt();
return 0;
}
/*
* Set up a signal frame... I don't know what it should look like yet.
*/
void setup_frame(struct sigaction * sa, unsigned long ** fp, unsigned long pc,
struct pt_regs * regs, int signr, unsigned long oldmask)
{
halt();
}
/*
* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*
* Note that we go through the signals twice: once to check the signals that
* the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that.
*
* Not that any of this is actually implemented yet ;-)
*/
asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
{
halt();
return 1;
}
......@@ -10,42 +10,18 @@
#include <linux/sched.h>
#include <asm/system.h>
#include <asm/io.h>
extern asmlinkage void entInt(void);
void keyboard_interrupt(void);
void do_hw_interrupt(unsigned long type, unsigned long vector)
void die_if_kernel(char * str, struct pt_regs * regs, long err)
{
if (type == 1) {
jiffies++;
return;
}
/* keyboard or mouse */
if (type == 3) {
if (vector == 0x980) {
keyboard_interrupt();
return;
} else {
unsigned char c = inb_local(0x64);
printk("IO device interrupt, vector = %lx\n", vector);
if (!(c & 1)) {
int i;
printk("Hmm. Keyboard interrupt, status = %02x\n", c);
for (i = 0; i < 10000000 ; i++)
/* nothing */;
printk("Serial line interrupt status: %02x\n", inb_local(0x3fa));
} else {
c = inb_local(0x60);
printk("#%02x# ", c);
}
return;
}
}
printk("Hardware intr %ld %ld\n", type, vector);
unsigned long i;
printk("%s %ld\n", str, err);
for (i = 0 ; i++ ; i < 500000000)
/* pause */;
halt();
}
extern asmlinkage void entMM(void);
void trap_init(void)
{
unsigned long gptr;
......@@ -54,5 +30,5 @@ void trap_init(void)
"___tmp:\tldgp %0,0(%0)"
: "=r" (gptr));
wrkgp(gptr);
wrent(entInt, 0);
wrent(entMM, 2);
}
......@@ -11,7 +11,7 @@
* by hand. The compiler expects the functions
*
* __divqu: 64-bit unsigned long divide
* __remqu: 64-bit unsigned long reminder
* __remqu: 64-bit unsigned long remainder
* __divqs/__remqs: signed 64-bit
* __divlu/__remlu: unsigned 32-bit
* __divls/__remls: signed 32-bit
......
#
# Makefile for the linux alpha-specific parts of the memory manager.
#
# 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 definition is now in the main makefile...
.c.o:
$(CC) $(CFLAGS) -c $<
.s.o:
$(AS) -o $*.o $<
.c.s:
$(CC) $(CFLAGS) -S $<
OBJS = init.o fault.o
mm.o: $(OBJS)
$(LD) -r -o mm.o $(OBJS)
modules:
dep:
$(CPP) -M *.c > .depend
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif
/*
* linux/arch/alpha/mm/fault.c
*
* Copyright (C) 1995 Linus Torvalds
*/
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/head.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <asm/system.h>
#include <asm/segment.h>
extern void die_if_kernel(char *,struct pt_regs *,long);
/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
* routines.
*
* mmcsr:
* 0 = translation not valid (= do_no_page())
* 1 = access violation (= user tries to access kernel pages)
* 2 = fault-on-read
* 3 = fault-on-execute
* 4 = fault-on-write
*
* cause:
* -1 = instruction fetch
* 0 = load
* 1 = store
*/
asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr,
long cause, struct pt_regs * regs)
{
struct vm_area_struct * vma;
if (mmcsr == 1)
goto bad_area;
for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
if (!vma)
goto bad_area;
if (vma->vm_end > address)
break;
}
if (vma->vm_start <= address)
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
goto bad_area;
vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
vma->vm_start = (address & PAGE_MASK);
/*
* Ok, we have a good vm_area for this memory access, so
* we can handle it..
*/
good_area:
if (!(vma->vm_page_prot & PAGE_USER))
goto bad_area;
if (mmcsr) {
if (!(vma->vm_page_prot & (PAGE_RW | PAGE_COW)))
goto bad_area;
do_wp_page(vma, address, cause > 0);
return;
}
do_no_page(vma, address, cause > 0);
return;
/*
* Something tried to access memory that isn't in our memory map..
* Fix it, but check if it's kernel or user first..
*/
bad_area:
if (user_mode(regs)) {
send_sig(SIGSEGV, current, 1);
return;
}
/*
* Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice.
*/
printk(KERN_ALERT "Unable to handle kernel paging request at virtual address %08lx\n",address);
die_if_kernel("Oops", regs, cause);
do_exit(SIGKILL);
}
/*
* linux/arch/alpha/mm/init.c
*
* Copyright (C) 1995 Linus Torvalds
*/
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/head.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/hwrpb.h>
extern void scsi_mem_init(unsigned long);
extern void sound_mem_init(void);
extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
/*
* BAD_PAGE is the page that is used for page faults when linux
* is out-of-memory. Older versions of linux just did a
* do_exit(), but using this instead means there is less risk
* for a process dying in kernel mode, possibly leaving a inode
* unused etc..
*
* BAD_PAGETABLE is the accompanying page-table: it is initialized
* to point to BAD_PAGE entries.
*
* ZERO_PAGE is a special page that is used for zero-initialized
* data and COW.
*/
unsigned long __bad_pagetable(void)
{
memset((void *) EMPTY_PGT, 0, PAGE_SIZE);
return EMPTY_PGT;
}
unsigned long __bad_page(void)
{
memset((void *) EMPTY_PGE, 0, PAGE_SIZE);
return EMPTY_PGE;
}
unsigned long __zero_page(void)
{
memset((void *) ZERO_PGE, 0, PAGE_SIZE);
return ZERO_PGE;
}
void show_mem(void)
{
int i,free = 0,total = 0,reserved = 0;
int shared = 0;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = high_memory >> PAGE_SHIFT;
while (i-- > 0) {
total++;
if (mem_map[i] & MAP_PAGE_RESERVED)
reserved++;
else if (!mem_map[i])
free++;
else
shared += mem_map[i]-1;
}
printk("%d pages of RAM\n",total);
printk("%d free pages\n",free);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
show_buffers();
#ifdef CONFIG_NET
show_net_buffers();
#endif
}
extern unsigned long free_area_init(unsigned long, unsigned long);
/*
* paging_init() sets up the page tables: in the alpha version this actually
* unmaps the bootup page table (as we're now in KSEG, so we don't need it).
*
* The bootup sequence put the virtual page table into high memory: that
* means that we cah change the L1 page table by just using VL1p below.
*/
#define VL1p ((unsigned long *) 0xffffffffffffe000)
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
{
int i;
struct memclust_struct * cluster;
struct memdesc_struct * memdesc;
/* initialize mem_map[] */
start_mem = free_area_init(start_mem, end_mem);
/* find free clusters, update mem_map[] accordingly */
memdesc = (struct memdesc_struct *) (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
cluster = memdesc->cluster;
for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
unsigned long pfn, nr;
if (cluster->usage & 1)
continue;
pfn = cluster->start_pfn;
nr = cluster->numpages;
/* non-volatile memory. We might want to mark this for later */
if (cluster->usage & 2)
continue;
while (nr--)
mem_map[pfn++] = 0;
}
/* unmap the console stuff: we don't need it, and we don't want it */
for (i = 0; i < 1023; i++)
VL1p[i] = 0;
invalidate_all();
return start_mem;
}
void mem_init(unsigned long start_mem, unsigned long end_mem)
{
unsigned long tmp;
end_mem &= PAGE_MASK;
high_memory = end_mem;
start_mem = PAGE_ALIGN(start_mem);
/*
* Mark the pages used by the kernel as reserved,,
*/
tmp = KERNEL_START;
while (tmp < start_mem) {
mem_map[MAP_NR(tmp)] = MAP_PAGE_RESERVED;
tmp += PAGE_SIZE;
}
#ifdef CONFIG_SCSI
scsi_mem_init(high_memory);
#endif
#ifdef CONFIG_SOUND
sound_mem_init();
#endif
for (tmp = PAGE_OFFSET ; tmp < high_memory ; tmp += PAGE_SIZE) {
if (mem_map[MAP_NR(tmp)])
continue;
mem_map[MAP_NR(tmp)] = 1;
free_page(tmp);
}
tmp = nr_free_pages << PAGE_SHIFT;
printk("Memory: %luk available\n", tmp >> 10);
return;
}
void si_meminfo(struct sysinfo *val)
{
int i;
i = high_memory >> PAGE_SHIFT;
val->totalram = 0;
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = buffermem;
while (i-- > 0) {
if (mem_map[i] & MAP_PAGE_RESERVED)
continue;
val->totalram++;
if (!mem_map[i])
continue;
val->sharedram += mem_map[i]-1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;
return;
}
......@@ -24,6 +24,9 @@ bool 'XT harddisk support' CONFIG_BLK_DEV_XD n
bool 'Networking support' CONFIG_NET y
bool 'Limit memory to low 16MB' CONFIG_MAX_16M n
bool 'PCI bios support' CONFIG_PCI n
if [ "$CONFIG_PCI" = "y" ]; then
bool ' PCI bridge optimisation (experimental)' CONFIG_PCI_OPTIMIZE n
fi
bool 'System V IPC' CONFIG_SYSVIPC y
bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
#bool 'Use -mpentium flag for Pentium-specific optimizations' CONFIG_M586 n
......
......@@ -18,7 +18,7 @@
.S.o:
$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
OBJS = process.o signal.o entry.o traps.o irq.o vm86.o bios32.o ptrace.o ioport.o ldt.o
OBJS = process.o signal.o entry.o traps.o irq.o vm86.o bios32.o ptrace.o ioport.o ldt.o setup.o
all: kernel.o head.o
......
......@@ -12,10 +12,6 @@
* Drew@Colorado.EDU
* +1 (303) 786-7975
*
* Pciprobe added by Frederic Potter 1994
* Potter@Cao-Vlsi.Ibp.FR
*
*
* For more information, please consult
*
* PCI BIOS Specification Revision
......@@ -37,9 +33,15 @@
* Jun 17, 1994 : Modified to accommodate the broken pre-PCI BIOS SPECIFICATION
* Revision 2.0 present on <thys@dennis.ee.up.ac.za>'s ASUS mainboard.
*
* Jan 5, 1995 : Modified to probe PCI hardware at boot time by Frederic
* Potter, potter@cao-vlsi.ibp.fr
*
* Jan 10, 1995 : Modified to store the information about configured pci
* devices into a list, which can be accessed via /proc/pci by
* Curtis Varner, cvarner@cs.ucr.edu
*
* Jan 12, 1995 : CPU-PCI bridge optimization support by Frederic Potter.
* Alpha version. Intel & UMC chipset support only. See pci.h for more.
*/
#include <linux/config.h>
......@@ -485,7 +487,7 @@ int revision_decode(unsigned char bus,unsigned char dev_fn)
int class_decode(unsigned char bus,unsigned char dev_fn)
{
struct pci_class_type pci_class[PCI_CLASS_NUM+1] = PCI_CLASS_TYPE;
struct pci_class_type pci_class[PCI_CLASS_NUM] = PCI_CLASS_TYPE;
int i;
unsigned long class;
pcibios_read_config_dword(
......@@ -497,9 +499,10 @@ int class_decode(unsigned char bus,unsigned char dev_fn)
}
int device_decode(unsigned char bus,unsigned char dev_fn,unsigned short vendor)
int device_decode(unsigned char bus,unsigned char dev_fn,unsigned short vendor_num)
{
struct pci_device_type pci_device[PCI_DEVICE_NUM+1] = PCI_DEVICE_TYPE;
struct pci_device_type pci_device[PCI_DEVICE_NUM] = PCI_DEVICE_TYPE;
struct pci_vendor_type pci_vendor[PCI_VENDOR_NUM] = PCI_VENDOR_TYPE;
int i;
unsigned short device;
......@@ -507,26 +510,78 @@ int device_decode(unsigned char bus,unsigned char dev_fn,unsigned short vendor)
bus, dev_fn, (unsigned char) PCI_DEVICE_ID, &device);
for (i=0;i<PCI_DEVICE_NUM;i++)
if ((device==pci_device[i].device_id)
&& (vendor==pci_device[i].vendor_id)) return i;
printk("Device id=%x ",device);
return i;
&& (pci_vendor[vendor_num].vendor_id==pci_device[i].vendor_id)) return i;
return 0x10000 + (int) device;
}
int vendor_decode(unsigned char bus,unsigned char dev_fn)
{
struct pci_vendor_type pci_vendor[PCI_VENDOR_NUM+1] = PCI_VENDOR_TYPE;
struct pci_vendor_type pci_vendor[PCI_VENDOR_NUM] = PCI_VENDOR_TYPE;
int i;
unsigned short vendor;
pcibios_read_config_word(
bus, dev_fn, (unsigned char) PCI_VENDOR_ID, &vendor);
for (i=0;i<PCI_VENDOR_NUM;i++)
if (vendor==pci_vendor[i].vendor_id) return i;
printk("Vendor id=%x ",vendor);
return i;
pcibios_read_config_word(
bus, dev_fn, (unsigned char) PCI_VENDOR_ID, &vendor);
for (i=0;i<PCI_VENDOR_NUM;i++)
if (vendor==pci_vendor[i].vendor_id) return i;
return 0x10000 + (int) vendor;
}
#ifdef CONFIG_PCI_OPTIMIZE
unsigned char bridge_decode(int device)
{
struct pci_device_type pci_device[PCI_DEVICE_NUM] = PCI_DEVICE_TYPE;
return (pci_device[device].bridge_id);
}
/* Turn on/off PCI bridge optimisation. This should allow benchmarking. */
void burst_bridge(unsigned char bus,unsigned char dev_fn,unsigned char pos, int turn_on)
{
struct bridge_mapping_type bridge_mapping[5*BRIDGE_MAPPING_NUM] = BRIDGE_MAPPING_TYPE;
struct optimisation_type optimisation[OPTIMISATION_NUM] = OPTIMISATION_TYPE;
int i;
unsigned char val;
pos*=OPTIMISATION_NUM;
printk("PCI bridge optimisation.\n");
for (i=0;i<OPTIMISATION_NUM;i++)
{
printk(" %s : ",optimisation[i].type);
if (bridge_mapping[pos+i].adress==0) printk("Not supported.");
else {
pcibios_read_config_byte(
bus, dev_fn, bridge_mapping[pos+i].adress, &val);
if ((val & bridge_mapping[pos+i].mask)==bridge_mapping[pos+i].value)
{
printk("%s.",optimisation[i].on);
if (turn_on==0)
{
pcibios_write_config_byte(
bus, dev_fn, bridge_mapping[pos+i].adress,
(val | bridge_mapping[pos+i].mask) -
bridge_mapping[pos+i].value);
printk("Changed! now %s.",optimisation[i].off);
}
} else {
printk("%s.",optimisation[i].off);
if (turn_on==1)
{
pcibios_write_config_byte(
bus, dev_fn, bridge_mapping[pos+i].adress,
(val & (0xff-bridge_mapping[pos+i].mask)) +
bridge_mapping[pos+i].value);
printk("Changed! now %s.",optimisation[i].on);
}
}
}
printk("\n");
}
}
#endif
/* In future version in case we detect a PCI to PCi bridge, we will go
for a recursive device search*/
......@@ -575,11 +630,38 @@ void add_pci_resource(unsigned char bus, unsigned char dev_fn)
{
pci_resource_t* new_pci;
pci_resource_t* temp;
int vendor_id, device_id;
#ifdef CONFIG_PCI_OPTIMIZE
unsigned char bridge_id;
#endif
/*
* Verify if we know about this chip. If not, print Vendor & Device id
* + ask for report.
*/
vendor_id=vendor_decode(bus,dev_fn);
device_id=device_decode(bus,dev_fn,vendor_id);
if ((device_id & 0x10000)==0x10000)
{
printk("Unknown PCI device. PCI Vendor id=%x. PCI Device id=%x.\n",
vendor_id & 0xffff,device_id & 0xffff);
printk("PLEASE MAIL POTTER@CAO-VLSI.IBP.FR your harware description and /proc/pci.\n");
return;
}
/*
* If the PCI agent is a known bridge, then configure it.
*/
#ifdef CONFIG_PCI_OPTIMIZE
bridge_id=bridge_decode(device_id);
if (bridge_id != 0xff)
{
burst_bridge(bus,dev_fn,bridge_id,1); /* Burst bridge */
}
#endif
/*
* Request and verify allocation of kernel RAM
*/
if(pci_index > 31)
if(pci_index > PCI_LIST_SIZE-1)
{
printk("PCI resource list full.\n");
return;
......@@ -618,11 +700,12 @@ int get_pci_list(char* buf)
{
int pr, length;
pci_resource_t* temp = pci_list.next;
struct pci_class_type pci_class[PCI_CLASS_NUM+1] = PCI_CLASS_TYPE;
struct pci_vendor_type pci_vendor[PCI_VENDOR_NUM+1] = PCI_VENDOR_TYPE;
struct pci_device_type pci_device[PCI_DEVICE_NUM+1] = PCI_DEVICE_TYPE;
struct pci_class_type pci_class[PCI_CLASS_NUM] = PCI_CLASS_TYPE;
struct pci_vendor_type pci_vendor[PCI_VENDOR_NUM] = PCI_VENDOR_TYPE;
struct pci_device_type pci_device[PCI_DEVICE_NUM] = PCI_DEVICE_TYPE;
for (length = 0 ; (temp) && (length<4000); temp = temp->next)
pr = sprintf(buf, "PCI devices found :\n");
for (length = pr ; (temp) && (length<4000); temp = temp->next)
{
pr=vendor_decode(temp->bus,temp->dev_fn);
......@@ -634,7 +717,7 @@ int get_pci_list(char* buf)
length += sprintf(buf+length, " %s : %s %s (rev %d). ",
pci_class[class_decode(temp->bus, temp->dev_fn)].class_name,
pci_vendor[pr].vendor_name,
pci_device[device_decode(temp->bus, temp->dev_fn, pci_vendor[pr].vendor_id)].device_name,
pci_device[device_decode(temp->bus, temp->dev_fn, pr)].device_name,
revision_decode(temp->bus, temp->dev_fn));
if (bist_probe(temp->bus, temp->dev_fn))
......
/*
* linux/kernel/irq.c
* linux/arch/i386/kernel/irq.c
*
* Copyright (C) 1992 Linus Torvalds
*
......@@ -12,14 +12,7 @@
/*
* IRQ's are in fact implemented a bit like signal handlers for the kernel.
* The same sigaction struct is used, and with similar semantics (ie there
* is a SA_INTERRUPT flag etc). Naturally it's not a 1:1 relation, but there
* are similarities.
*
* sa_handler(int irq_NR) is the default function called (0 if no).
* sa_mask is horribly ugly (I won't even mention it)
* sa_flags contains various info: SA_INTERRUPT etc
* sa_restorer is the unused
* Naturally it's not a 1:1 relation, but there are similarities.
*/
#include <linux/ptrace.h>
......@@ -28,6 +21,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <asm/system.h>
#include <asm/io.h>
......@@ -147,7 +141,14 @@ static void (*bad_interrupt[16])(void) = {
/*
* Initial irq handlers.
*/
static struct sigaction irq_sigaction[16] = {
struct irqaction {
void (*handler)(int, struct pt_regs *);
unsigned long flags;
unsigned long mask;
const char *name;
};
static struct irqaction irq_action[16] = {
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
......@@ -161,15 +162,15 @@ static struct sigaction irq_sigaction[16] = {
int get_irq_list(char *buf)
{
int i, len = 0;
struct sigaction * sa = irq_sigaction;
struct irqaction * action = irq_action;
for (i = 0 ; i < 16 ; i++, sa++) {
if (!sa->sa_handler)
for (i = 0 ; i < 16 ; i++, action++) {
if (!action->handler)
continue;
len += sprintf(buf+len, "%2d: %8d %c %s\n",
i, kstat.interrupts[i],
(sa->sa_flags & SA_INTERRUPT) ? '+' : ' ',
(char *) sa->sa_mask);
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
}
return len;
}
......@@ -183,10 +184,10 @@ int get_irq_list(char *buf)
*/
asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
struct sigaction * sa = irq + irq_sigaction;
struct irqaction * action = irq + irq_action;
kstat.interrupts[irq]++;
sa->sa_handler((int) regs);
action->handler(irq, regs);
}
/*
......@@ -196,35 +197,35 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
*/
asmlinkage void do_fast_IRQ(int irq)
{
struct sigaction * sa = irq + irq_sigaction;
struct irqaction * action = irq + irq_action;
kstat.interrupts[irq]++;
sa->sa_handler(irq);
action->handler(irq, NULL);
}
#define SA_PROBE SA_ONESHOT
/*
* Using "struct sigaction" is slightly silly, but there
* are historical reasons and it works well, so..
*/
static int irqaction(unsigned int irq, struct sigaction * new_sa)
int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
unsigned long irqflags, const char * devname)
{
struct sigaction * sa;
struct irqaction * action;
unsigned long flags;
if (irq > 15)
return -EINVAL;
sa = irq + irq_sigaction;
if (sa->sa_handler)
action = irq + irq_action;
if (action->handler)
return -EBUSY;
if (!new_sa->sa_handler)
if (!handler)
return -EINVAL;
save_flags(flags);
cli();
*sa = *new_sa;
if (!(sa->sa_flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
if (sa->sa_flags & SA_INTERRUPT)
action->handler = handler;
action->flags = irqflags;
action->mask = 0;
action->name = devname;
if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
if (action->flags & SA_INTERRUPT)
set_intr_gate(0x20+irq,fast_interrupt[irq]);
else
set_intr_gate(0x20+irq,interrupt[irq]);
......@@ -242,28 +243,16 @@ static int irqaction(unsigned int irq, struct sigaction * new_sa)
return 0;
}
int request_irq(unsigned int irq, void (*handler)(int),
unsigned long flags, const char * devname)
{
struct sigaction sa;
sa.sa_handler = handler;
sa.sa_flags = flags;
sa.sa_mask = (unsigned long) devname;
sa.sa_restorer = NULL;
return irqaction(irq,&sa);
}
void free_irq(unsigned int irq)
{
struct sigaction * sa = irq + irq_sigaction;
struct irqaction * action = irq + irq_action;
unsigned long flags;
if (irq > 15) {
printk("Trying to free IRQ%d\n",irq);
return;
}
if (!sa->sa_handler) {
if (!action->handler) {
printk("Trying to free free IRQ%d\n",irq);
return;
}
......@@ -277,10 +266,10 @@ void free_irq(unsigned int irq)
outb(cache_A1,0xA1);
}
set_intr_gate(0x20+irq,bad_interrupt[irq]);
sa->sa_handler = NULL;
sa->sa_flags = 0;
sa->sa_mask = 0;
sa->sa_restorer = NULL;
action->handler = NULL;
action->flags = 0;
action->mask = 0;
action->name = NULL;
restore_flags(flags);
}
......@@ -295,7 +284,7 @@ void free_irq(unsigned int irq)
* leads to races. IBM designers who came up with it should
* be shot.
*/
static void math_error_irq(int cpl)
static void math_error_irq(int cpl, struct pt_regs *regs)
{
outb(0,0xF0);
if (ignore_irq13 || !hard_math)
......@@ -303,7 +292,7 @@ static void math_error_irq(int cpl)
math_error();
}
static void no_action(int cpl) { }
static void no_action(int cpl, struct pt_regs * regs) { }
unsigned int probe_irq_on (void)
{
......@@ -361,6 +350,10 @@ void init_IRQ(void)
{
int i;
/* set the clock to 100 Hz */
outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
outb_p(LATCH & 0xff , 0x40); /* LSB */
outb(LATCH >> 8 , 0x40); /* MSB */
for (i = 0; i < 16 ; i++)
set_intr_gate(0x20+i,bad_interrupt[i]);
if (request_irq(2, no_action, SA_INTERRUPT, "cascade"))
......
......@@ -23,27 +23,6 @@
#include <asm/segment.h>
#include <asm/system.h>
/*
* Tell us the machine setup..
*/
char hard_math = 0; /* set by boot/head.S */
char x86 = 0; /* set by boot/head.S to 3 or 4 */
char x86_model = 0; /* set by boot/head.S */
char x86_mask = 0; /* set by boot/head.S */
int x86_capability = 0; /* set by boot/head.S */
int fdiv_bug = 0; /* set if Pentium(TM) with FP bug */
char x86_vendor_id[13] = "Unknown";
char ignore_irq13 = 0; /* set if exception 16 works */
char wp_works_ok = 0; /* set if paging hardware honours WP */
char hlt_works_ok = 1; /* set if the "hlt" instruction works */
/*
* Bus types ..
*/
int EISA_bus = 0;
asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
/*
......
/*
* linux/arch/i386/kernel/setup.c
*
* Copyright (C) 1995 Linus Torvalds
*/
/*
* This file handles the architecture-dependent parts of process handling..
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
#include <linux/ldt.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/tty.h>
#include <asm/segment.h>
#include <asm/system.h>
/*
* Tell us the machine setup..
*/
char hard_math = 0; /* set by boot/head.S */
char x86 = 0; /* set by boot/head.S to 3 or 4 */
char x86_model = 0; /* set by boot/head.S */
char x86_mask = 0; /* set by boot/head.S */
int x86_capability = 0; /* set by boot/head.S */
int fdiv_bug = 0; /* set if Pentium(TM) with FP bug */
char x86_vendor_id[13] = "Unknown";
char ignore_irq13 = 0; /* set if exception 16 works */
char wp_works_ok = 0; /* set if paging hardware honours WP */
char hlt_works_ok = 1; /* set if the "hlt" instruction works */
/*
* Bus types ..
*/
int EISA_bus = 0;
/*
* Setup options
*/
struct drive_info_struct { char dummy[32]; } drive_info;
struct screen_info screen_info;
unsigned char aux_device_present;
extern int ramdisk_size;
extern int root_mountflags;
extern int end;
extern char empty_zero_page[PAGE_SIZE];
/*
* This is set up by the setup-routine at boot-time
*/
#define PARAM empty_zero_page
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
#define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
#define RAMDISK_SIZE (*(unsigned short *) (PARAM+0x1F8))
#define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
#define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
#define COMMAND_LINE ((char *) (PARAM+2048))
#define COMMAND_LINE_SIZE 256
static char command_line[COMMAND_LINE_SIZE] = { 0, };
void setup_arch(char **cmdline_p,
unsigned long * memory_start_p, unsigned long * memory_end_p)
{
unsigned long memory_start, memory_end;
char c = ' ', *to = command_line, *from = COMMAND_LINE;
int len = 0;
ROOT_DEV = ORIG_ROOT_DEV;
drive_info = DRIVE_INFO;
screen_info = SCREEN_INFO;
aux_device_present = AUX_DEVICE_INFO;
memory_end = (1<<20) + (EXT_MEM_K<<10);
memory_end &= PAGE_MASK;
ramdisk_size = RAMDISK_SIZE;
#ifdef CONFIG_MAX_16M
if (memory_end > 16*1024*1024)
memory_end = 16*1024*1024;
#endif
if (MOUNT_ROOT_RDONLY)
root_mountflags |= MS_RDONLY;
memory_start = (unsigned long) &end;
for (;;) {
if (c == ' ' && *(unsigned long *)from == *(unsigned long *)"mem=") {
memory_end = simple_strtoul(from+4, &from, 0);
if ( *from == 'K' || *from == 'k' ) {
memory_end = memory_end << 10;
from++;
} else if ( *from == 'M' || *from == 'm' ) {
memory_end = memory_end << 20;
from++;
}
}
c = *(from++);
if (!c)
break;
if (COMMAND_LINE_SIZE <= ++len)
break;
*(to++) = c;
}
*to = '\0';
*cmdline_p = command_line;
*memory_start_p = memory_start;
*memory_end_p = memory_end;
}
......@@ -14,7 +14,7 @@
.c.s:
$(CC) $(CFLAGS) -S $<
OBJS = fault.o
OBJS = init.o fault.o
mm.o: $(OBJS)
$(LD) -r -o mm.o $(OBJS)
......
......@@ -18,19 +18,7 @@
#include <asm/system.h>
#include <asm/segment.h>
extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */
extern void scsi_mem_init(unsigned long);
extern void sound_mem_init(void);
extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
/*
* Define this if things work differently on a i386 and a i486:
* it will (on a i486) warn about kernel memory accesses that are
* done without a 'verify_area(VERIFY_WRITE,..)'
*/
#undef CONFIG_TEST_VERIFY_AREA
/*
* This routine handles page faults. It determines the address,
......@@ -78,10 +66,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
if (regs->cs == KERNEL_CS)
printk("WP fault at %08x\n", regs->eip);
#endif
do_wp_page(vma, address, error_code);
do_wp_page(vma, address, error_code & PAGE_RW);
return;
}
do_no_page(vma, address, error_code);
do_no_page(vma, address, error_code & PAGE_RW);
return;
/*
......@@ -127,223 +115,3 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
die_if_kernel("Oops", regs, error_code);
do_exit(SIGKILL);
}
/*
* BAD_PAGE is the page that is used for page faults when linux
* is out-of-memory. Older versions of linux just did a
* do_exit(), but using this instead means there is less risk
* for a process dying in kernel mode, possibly leaving a inode
* unused etc..
*
* BAD_PAGETABLE is the accompanying page-table: it is initialized
* to point to BAD_PAGE entries.
*
* ZERO_PAGE is a special page that is used for zero-initialized
* data and COW.
*/
unsigned long __bad_pagetable(void)
{
extern char empty_bad_page_table[PAGE_SIZE];
__asm__ __volatile__("cld ; rep ; stosl":
:"a" (BAD_PAGE + PAGE_TABLE),
"D" ((long) empty_bad_page_table),
"c" (PTRS_PER_PAGE)
:"di","cx");
return (unsigned long) empty_bad_page_table;
}
unsigned long __bad_page(void)
{
extern char empty_bad_page[PAGE_SIZE];
__asm__ __volatile__("cld ; rep ; stosl":
:"a" (0),
"D" ((long) empty_bad_page),
"c" (PTRS_PER_PAGE)
:"di","cx");
return (unsigned long) empty_bad_page;
}
unsigned long __zero_page(void)
{
extern char empty_zero_page[PAGE_SIZE];
__asm__ __volatile__("cld ; rep ; stosl":
:"a" (0),
"D" ((long) empty_zero_page),
"c" (PTRS_PER_PAGE)
:"di","cx");
return (unsigned long) empty_zero_page;
}
void show_mem(void)
{
int i,free = 0,total = 0,reserved = 0;
int shared = 0;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = high_memory >> PAGE_SHIFT;
while (i-- > 0) {
total++;
if (mem_map[i] & MAP_PAGE_RESERVED)
reserved++;
else if (!mem_map[i])
free++;
else
shared += mem_map[i]-1;
}
printk("%d pages of RAM\n",total);
printk("%d free pages\n",free);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
show_buffers();
#ifdef CONFIG_NET
show_net_buffers();
#endif
}
extern unsigned long free_area_init(unsigned long, unsigned long);
/*
* paging_init() sets up the page tables - note that the first 4MB are
* already mapped by head.S.
*
* This routines also unmaps the page at virtual kernel address 0, so
* that we can trap those pesky NULL-reference errors in the kernel.
*/
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
{
unsigned long * pg_dir;
unsigned long * pg_table;
unsigned long tmp;
unsigned long address;
/*
* Physical page 0 is special; it's not touched by Linux since BIOS
* and SMM (for laptops with [34]86/SL chips) may need it. It is read
* and write protected to detect null pointer references in the
* kernel.
*/
#if 0
memset((void *) 0, 0, PAGE_SIZE);
#endif
start_mem = PAGE_ALIGN(start_mem);
address = 0;
pg_dir = swapper_pg_dir;
while (address < end_mem) {
tmp = *(pg_dir + 768); /* at virtual addr 0xC0000000 */
if (!tmp) {
tmp = start_mem | PAGE_TABLE;
*(pg_dir + 768) = tmp;
start_mem += PAGE_SIZE;
}
*pg_dir = tmp; /* also map it in at 0x0000000 for init */
pg_dir++;
pg_table = (unsigned long *) (tmp & PAGE_MASK);
for (tmp = 0 ; tmp < PTRS_PER_PAGE ; tmp++,pg_table++) {
if (address < end_mem)
*pg_table = address | PAGE_SHARED;
else
*pg_table = 0;
address += PAGE_SIZE;
}
}
invalidate();
return free_area_init(start_mem, end_mem);
}
void mem_init(unsigned long start_low_mem,
unsigned long start_mem, unsigned long end_mem)
{
int codepages = 0;
int reservedpages = 0;
int datapages = 0;
unsigned long tmp;
extern int etext;
end_mem &= PAGE_MASK;
high_memory = end_mem;
/* mark usable pages in the mem_map[] */
start_low_mem = PAGE_ALIGN(start_low_mem);
start_mem = PAGE_ALIGN(start_mem);
/*
* IBM messed up *AGAIN* in their thinkpad: 0xA0000 -> 0x9F000.
* They seem to have done something stupid with the floppy
* controller as well..
*/
while (start_low_mem < 0x9f000) {
mem_map[MAP_NR(start_low_mem)] = 0;
start_low_mem += PAGE_SIZE;
}
while (start_mem < high_memory) {
mem_map[MAP_NR(start_mem)] = 0;
start_mem += PAGE_SIZE;
}
#ifdef CONFIG_SCSI
scsi_mem_init(high_memory);
#endif
#ifdef CONFIG_SOUND
sound_mem_init();
#endif
for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
if (mem_map[MAP_NR(tmp)]) {
if (tmp >= 0xA0000 && tmp < 0x100000)
reservedpages++;
else if (tmp < (unsigned long) &etext)
codepages++;
else
datapages++;
continue;
}
mem_map[MAP_NR(tmp)] = 1;
free_page(tmp);
}
tmp = nr_free_pages << PAGE_SHIFT;
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
tmp >> 10,
high_memory >> 10,
codepages << (PAGE_SHIFT-10),
reservedpages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10));
/* test if the WP bit is honoured in supervisor mode */
wp_works_ok = -1;
pg0[0] = PAGE_READONLY;
invalidate();
__asm__ __volatile__("movb 0,%%al ; movb %%al,0": : :"ax", "memory");
pg0[0] = 0;
invalidate();
if (wp_works_ok < 0)
wp_works_ok = 0;
#ifdef CONFIG_TEST_VERIFY_AREA
wp_works_ok = 0;
#endif
return;
}
void si_meminfo(struct sysinfo *val)
{
int i;
i = high_memory >> PAGE_SHIFT;
val->totalram = 0;
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = buffermem;
while (i-- > 0) {
if (mem_map[i] & MAP_PAGE_RESERVED)
continue;
val->totalram++;
if (!mem_map[i])
continue;
val->sharedram += mem_map[i]-1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;
return;
}
/*
* linux/arch/i386/mm/init.c
*
* Copyright (C) 1995 Linus Torvalds
*/
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/head.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <asm/system.h>
#include <asm/segment.h>
extern void scsi_mem_init(unsigned long);
extern void sound_mem_init(void);
extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
/*
* BAD_PAGE is the page that is used for page faults when linux
* is out-of-memory. Older versions of linux just did a
* do_exit(), but using this instead means there is less risk
* for a process dying in kernel mode, possibly leaving a inode
* unused etc..
*
* BAD_PAGETABLE is the accompanying page-table: it is initialized
* to point to BAD_PAGE entries.
*
* ZERO_PAGE is a special page that is used for zero-initialized
* data and COW.
*/
unsigned long __bad_pagetable(void)
{
extern char empty_bad_page_table[PAGE_SIZE];
__asm__ __volatile__("cld ; rep ; stosl":
:"a" (BAD_PAGE + PAGE_TABLE),
"D" ((long) empty_bad_page_table),
"c" (PTRS_PER_PAGE)
:"di","cx");
return (unsigned long) empty_bad_page_table;
}
unsigned long __bad_page(void)
{
extern char empty_bad_page[PAGE_SIZE];
__asm__ __volatile__("cld ; rep ; stosl":
:"a" (0),
"D" ((long) empty_bad_page),
"c" (PTRS_PER_PAGE)
:"di","cx");
return (unsigned long) empty_bad_page;
}
unsigned long __zero_page(void)
{
extern char empty_zero_page[PAGE_SIZE];
__asm__ __volatile__("cld ; rep ; stosl":
:"a" (0),
"D" ((long) empty_zero_page),
"c" (PTRS_PER_PAGE)
:"di","cx");
return (unsigned long) empty_zero_page;
}
void show_mem(void)
{
int i,free = 0,total = 0,reserved = 0;
int shared = 0;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = high_memory >> PAGE_SHIFT;
while (i-- > 0) {
total++;
if (mem_map[i] & MAP_PAGE_RESERVED)
reserved++;
else if (!mem_map[i])
free++;
else
shared += mem_map[i]-1;
}
printk("%d pages of RAM\n",total);
printk("%d free pages\n",free);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
show_buffers();
#ifdef CONFIG_NET
show_net_buffers();
#endif
}
extern unsigned long free_area_init(unsigned long, unsigned long);
/*
* paging_init() sets up the page tables - note that the first 4MB are
* already mapped by head.S.
*
* This routines also unmaps the page at virtual kernel address 0, so
* that we can trap those pesky NULL-reference errors in the kernel.
*/
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
{
unsigned long * pg_dir;
unsigned long * pg_table;
unsigned long tmp;
unsigned long address;
/*
* Physical page 0 is special; it's not touched by Linux since BIOS
* and SMM (for laptops with [34]86/SL chips) may need it. It is read
* and write protected to detect null pointer references in the
* kernel.
*/
#if 0
memset((void *) 0, 0, PAGE_SIZE);
#endif
start_mem = PAGE_ALIGN(start_mem);
address = 0;
pg_dir = swapper_pg_dir;
while (address < end_mem) {
tmp = *(pg_dir + 768); /* at virtual addr 0xC0000000 */
if (!tmp) {
tmp = start_mem | PAGE_TABLE;
*(pg_dir + 768) = tmp;
start_mem += PAGE_SIZE;
}
*pg_dir = tmp; /* also map it in at 0x0000000 for init */
pg_dir++;
pg_table = (unsigned long *) (tmp & PAGE_MASK);
for (tmp = 0 ; tmp < PTRS_PER_PAGE ; tmp++,pg_table++) {
if (address < end_mem)
*pg_table = address | PAGE_SHARED;
else
*pg_table = 0;
address += PAGE_SIZE;
}
}
invalidate();
return free_area_init(start_mem, end_mem);
}
void mem_init(unsigned long start_mem, unsigned long end_mem)
{
unsigned long start_low_mem = PAGE_SIZE;
int codepages = 0;
int reservedpages = 0;
int datapages = 0;
unsigned long tmp;
extern int etext;
end_mem &= PAGE_MASK;
high_memory = end_mem;
/* mark usable pages in the mem_map[] */
start_low_mem = PAGE_ALIGN(start_low_mem);
start_mem = PAGE_ALIGN(start_mem);
/*
* IBM messed up *AGAIN* in their thinkpad: 0xA0000 -> 0x9F000.
* They seem to have done something stupid with the floppy
* controller as well..
*/
while (start_low_mem < 0x9f000) {
mem_map[MAP_NR(start_low_mem)] = 0;
start_low_mem += PAGE_SIZE;
}
while (start_mem < high_memory) {
mem_map[MAP_NR(start_mem)] = 0;
start_mem += PAGE_SIZE;
}
#ifdef CONFIG_SCSI
scsi_mem_init(high_memory);
#endif
#ifdef CONFIG_SOUND
sound_mem_init();
#endif
for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
if (mem_map[MAP_NR(tmp)]) {
if (tmp >= 0xA0000 && tmp < 0x100000)
reservedpages++;
else if (tmp < (unsigned long) &etext)
codepages++;
else
datapages++;
continue;
}
mem_map[MAP_NR(tmp)] = 1;
free_page(tmp);
}
tmp = nr_free_pages << PAGE_SHIFT;
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
tmp >> 10,
high_memory >> 10,
codepages << (PAGE_SHIFT-10),
reservedpages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10));
/* test if the WP bit is honoured in supervisor mode */
wp_works_ok = -1;
pg0[0] = PAGE_READONLY;
invalidate();
__asm__ __volatile__("movb 0,%%al ; movb %%al,0": : :"ax", "memory");
pg0[0] = 0;
invalidate();
if (wp_works_ok < 0)
wp_works_ok = 0;
#ifdef CONFIG_TEST_VERIFY_AREA
wp_works_ok = 0;
#endif
return;
}
void si_meminfo(struct sysinfo *val)
{
int i;
i = high_memory >> PAGE_SHIFT;
val->totalram = 0;
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = buffermem;
while (i-- > 0) {
if (mem_map[i] & MAP_PAGE_RESERVED)
continue;
val->totalram++;
if (!mem_map[i])
continue;
val->sharedram += mem_map[i]-1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;
return;
}
#
# mips/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# 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) 1994, 1995 by Waldorf Electronics,
# written by Ralf Baechle
#
AS = mips-linux-as
ASFLAGS = -mips3 -mcpu=r4000
LD = mips-linux-ld
LINKFLAGS = -Ttext 0xa0000000
#HOSTCC = gcc
#
# KERNELBASE isn't quite useless, but I need it to work
# around a hardware bug in my Wreckstation board. Other people
# would burn that @#!%# thing...
#
CC = mips-linux-gcc -V 2.5.8 -D__KERNEL__ -I$(TOPDIR)/include
AR = mips-linux-ar
RANLIB = mips-linux-ranlib
STRIP = mips-linux-strip
CFLAGS := $(CFLAGS) #-pipe
CFLAGS := $(CFLAGS) -Wa,-mips3 -mcpu=r4000 -D__R4000__ -DKERNELBASE=0xa0000000
HEAD := arch/mips/kernel/head.o
SUBDIRS := $(SUBDIRS) arch/mips/kernel arch/mips/mm
ARCHIVES := arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(ARCHIVES)
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
zImage: vmlinux
@$(MAKEBOOT) zImage
compressed: zImage
zdisk: vmlinux
@$(MAKEBOOT) zdisk
archclean:
@$(MAKEBOOT) clean
archdep:
@$(MAKEBOOT) dep
#
# arch/mips/boot/Makefile
#
# 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 Waldorf Electronics,
# written by Ralf Baechle
#
#
# Fake compessed boot
#
zImage: $(CONFIGURE) $(TOPDIR)/vmlinux
ln -fs $(TOPDIR)/vmlinux zImage
zdisk: zImage
mcopy -n $(TOPDIR)/vmlinux a:vmlinux
dep:
clean:
rm -f zImage
#
# For a description of the syntax of this configuration file,
# see the Configure script.
#
comment 'General setup'
bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD n
bool 'Normal harddisk support' CONFIG_BLK_DEV_HD n
bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 y
if [ "$CONFIG_ST506" = "y" ]; then
bool ' Use old (reliable) disk-only driver for primary i/f' CONFIG_BLK_DEV_HD y
if [ "$CONFIG_BLK_DEV_HD" = "y" ]; then
bool ' Include new IDE driver for secondary i/f support' CONFIG_BLK_DEV_IDE n
else
bool ' Use new IDE driver for primary/secondary i/f' CONFIG_BLK_DEV_IDE n
fi
if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then
bool ' Include support for IDE CDROM (ATAPI)' CONFIG_BLK_DEV_IDECD n
fi
fi
bool 'XT harddisk support' CONFIG_BLK_DEV_XD n
bool 'Networking support' CONFIG_NET y
bool 'System V IPC' CONFIG_SYSVIPC n
bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF n
if [ "$CONFIG_NET" = "y" ]; then
comment 'Networking options'
bool 'TCP/IP networking' CONFIG_INET n
if [ "$CONFIG_INET" "=" "y" ]; then
bool 'IP forwarding/gatewaying' CONFIG_IP_FORWARD y
bool 'IP multicasting (ALPHA)' CONFIG_IP_MULTICAST n
bool 'IP firewalling' CONFIG_IP_FIREWALL n
bool 'IP accounting' CONFIG_IP_ACCT n
comment '(it is safe to leave these untouched)'
bool 'PC/TCP compatibility mode' CONFIG_INET_PCTCP n
bool 'Reverse ARP' CONFIG_INET_RARP n
bool 'Assume subnets are local' CONFIG_INET_SNARL y
bool 'Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
fi
bool 'The IPX protocol' CONFIG_IPX n
#bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n
fi
comment 'SCSI support'
bool 'SCSI support?' CONFIG_SCSI n
if [ "$CONFIG_SCSI" = "n" ]; then
comment 'Skipping SCSI configuration options...'
else
comment 'SCSI support type (disk, tape, CDrom)'
bool 'Scsi disk support' CONFIG_BLK_DEV_SD y
bool 'Scsi tape support' CONFIG_CHR_DEV_ST y
bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR y
bool 'Scsi generic support' CONFIG_CHR_DEV_SG y
comment 'SCSI low-level drivers'
bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n
bool 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 y
bool 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n
bool 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n
bool 'EATA-DMA (DPT,NEC&ATT for ISA,EISA,PCI) support' CONFIG_SCSI_EATA_DMA n
bool 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F n
bool 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n
bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n
if [ "$CONFIG_PCI" = "y" ]; then
bool 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx n
fi
bool 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 n
bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n
bool 'QLOGIC SCSI support' CONFIG_SCSI_QLOGIC n
bool 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n
bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n
bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n
bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST n
#bool 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA n
#bool 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n
fi
if [ "$CONFIG_NET" = "y" ]; then
comment 'Network device support'
bool 'Network device support?' CONFIG_NETDEVICES y
if [ "$CONFIG_NETDEVICES" = "n" ]; then
comment 'Skipping network driver configuration options...'
else
bool 'Dummy net driver support' CONFIG_DUMMY n
bool 'SLIP (serial line) support' CONFIG_SLIP n
if [ "$CONFIG_SLIP" = "y" ]; then
bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED y
bool ' 16 channels instead of 4' SL_SLIP_LOTS n
# bool ' SLIP debugging on' SL_DUMP y
fi
bool 'PPP (point-to-point) support' CONFIG_PPP n
bool 'PLIP (parallel port) support' CONFIG_PLIP n
bool 'Load balancing support (experimental)' CONFIG_SLAVE_BALANCING n
bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA n
bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC y
if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
bool 'WD80*3 support' CONFIG_WD80x3 y
bool 'SMC Ultra support' CONFIG_ULTRA n
fi
bool 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE n
bool '3COM cards' CONFIG_NET_VENDOR_3COM y
if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
bool '3c501 support' CONFIG_EL1 n
bool '3c503 support' CONFIG_EL2 n
if [ "$CONFIG_NET_ALPHA" = "y" ]; then
bool '3c505 support' CONFIG_ELPLUS n
bool '3c507 support' CONFIG_EL16 n
fi
bool '3c509/3c579 support' CONFIG_EL3 n
fi
bool 'Other ISA cards' CONFIG_NET_ISA n
if [ "$CONFIG_NET_ISA" = "y" ]; then
bool 'Cabletron E21xx support' CONFIG_E2100 n
bool 'DEPCA support' CONFIG_DEPCA n
bool 'EtherWorks 3 support' CONFIG_EWRK3 n
if [ "$CONFIG_NET_ALPHA" = "y" ]; then
bool 'Arcnet support' CONFIG_ARCNET n
bool 'AT1700 support' CONFIG_AT1700 n
# bool 'EtherExpressPro support' CONFIG_EEXPRESS_PRO n
bool 'EtherExpress support' CONFIG_EEXPRESS n
bool 'NI5210 support' CONFIG_NI52 n
bool 'NI6510 support' CONFIG_NI65 n
fi
bool 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS n
bool 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN n
bool 'NE2000/NE1000 support' CONFIG_NE2000 y
bool 'SK_G16 support' CONFIG_SK_G16 n
fi
bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA n
if [ "$CONFIG_NET_EISA" = "y" ]; then
if [ "$CONFIG_NET_ALPHA" = "y" ]; then
bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
fi
bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n
# bool 'DEC 21040 PCI support' CONFIG_DEC_ELCP n
# bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100 n
# bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32 n
bool 'Zenith Z-Note support' CONFIG_ZNET y
fi
bool 'Pocket and portable adaptors' CONFIG_NET_POCKET n
if [ "$CONFIG_NET_POCKET" = "y" ]; then
bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n
bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
bool 'D-Link DE620 pocket adaptor support' CONFIG_DE620 n
# bool 'Silicom pocket adaptor support' CONFIG_SILICOM_PEA n
# bool 'WaveLAN PCMCIA support' CONFIG_WaveLAN n
# bool '3 Com 3c589 PCMCIA support' CONFIG_3C589 n
fi
fi
fi
comment 'CD-ROM drivers'
bool 'Sony CDU31A/CDU33A CDROM driver support' CONFIG_CDU31A n
bool 'Mitsumi CDROM driver support' CONFIG_MCD n
bool 'Matsushita/Panasonic CDROM driver support' CONFIG_SBPCD n
if [ "$CONFIG_SBPCD" = "y" ]; then
bool 'Matsushita/Panasonic second CDROM controller support' CONFIG_SBPCD2 n
if [ "$CONFIG_SBPCD2" = "y" ]; then
bool 'Matsushita/Panasonic third CDROM controller support' CONFIG_SBPCD3 n
if [ "$CONFIG_SBPCD3" = "y" ]; then
bool 'Matsushita/Panasonic fourth CDROM controller support' CONFIG_SBPCD4 n
fi
fi
fi
comment 'Filesystems'
bool 'Standard (minix) fs support' CONFIG_MINIX_FS y
bool 'Extended fs support' CONFIG_EXT_FS n
bool 'Second extended fs support' CONFIG_EXT2_FS n
bool 'xiafs filesystem support' CONFIG_XIA_FS n
bool 'msdos fs support' CONFIG_MSDOS_FS n
if [ "$CONFIG_MSDOS_FS" = "y" ]; then
bool 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS n
fi
bool '/proc filesystem support' CONFIG_PROC_FS n
if [ "$CONFIG_INET" = "y" ]; then
bool 'NFS filesystem support' CONFIG_NFS_FS y
fi
if [ "$CONFIG_BLK_DEV_SR" = "y" -o "$CONFIG_CDU31A" = "y" -o "$CONFIG_MCD" = "y" -o "$CONFIG_SBPCD" = "y" -o "$CONFIG_BLK_DEV_IDECD" = "y" ]; then
bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y
else
bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS n
fi
bool 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS n
bool 'System V and Coherent filesystem support' CONFIG_SYSV_FS n
comment 'character devices'
bool 'Cyclades async mux support' CONFIG_CYCLADES n
bool 'Parallel printer support' CONFIG_PRINTER n
bool 'Logitech busmouse support' CONFIG_BUSMOUSE n
bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n
if [ "$CONFIG_PSMOUSE" = "y" ]; then
bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE n
fi
bool 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n
bool 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n
bool 'Selection (cut and paste for virtual consoles)' CONFIG_SELECTION n
bool 'QIC-02 tape support' CONFIG_QIC02_TAPE n
if [ "$CONFIG_QIC02_TAPE" = "y" ]; then
bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF n
if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then
comment '>>> Edit configuration parameters in ./include/linux/tpqic02.h!'
else
comment '>>> Setting runtime QIC-02 configuration is done with qic02conf'
comment '>>> Which is available from ftp://ftp.funet.fi/pub/OS/Linux/BETA/QIC-02/'
fi
fi
bool 'QIC-117 tape support' CONFIG_FTAPE n
if [ "$CONFIG_FTAPE" = "y" ]; then
int ' number of ftape buffers' NR_FTAPE_BUFFERS 3
fi
comment 'Sound'
bool 'Sound card support' CONFIG_SOUND n
comment 'Kernel hacking'
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC n
bool 'Kernel profiling support' CONFIG_PROFILE n
if [ "$CONFIG_PROFILE" = "y" ]; then
int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
fi
if [ "$CONFIG_SCSI" = "y" ]; then
bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS y
fi
#
# Makefile for the linux 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).
#
# Note 2! The CFLAGS definitions are now in the main makefile...
.c.s:
$(CC) $(CFLAGS) -S $<
.s.o:
$(AS) $(ASFLAGS) -o $*.o $<
.c.o:
$(CC) $(CFLAGS) -c $<
.S.s:
$(CPP) $(CFLAGS) -D__ASSEMBLY__ -traditional $< -o $*.s
.S.o:
$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
OBJS = process.o signal.o entry.o traps.o irq.o ptrace.o cache.o resume.o \
ioport.o bootinfo.o
all: kernel.o head.o
head.o: head.s
head.s: head.S $(TOPDIR)/include/linux/tasks.h
cache.o: cache.s
cache.s: cache.S $(TOPDIR)/include/asm/mipsconfig.h \
$(TOPDIR)/include/asm/regdef.h $(TOPDIR)/include/asm/segment.h
resume.o: resume.s
resume.s: resume.S $(TOPDIR)/include/asm/regdef.h \
$(TOPDIR)/include/asm/processor.h $(TOPDIR)/include/asm/mipsregs.h \
$(TOPDIR)/include/asm/mipsconfig.h
tlb.o: tlb.s
tlb.s: tlb.S $(TOPDIR)/include/asm/regdef.h $(TOPDIR)/include/asm/mipsregs.h \
$(TOPDIR)/include/asm/bootinfo.h
kernel.o: $(OBJS)
$(LD) -r -o kernel.o $(OBJS)
sync
dep:
$(CPP) $(CFLAGS) -M *.c > .depend
modules:
dummy:
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif
/*
* arch/mips/kernel/bootinfo.c
*
* Copyright (C) 1995 Ralf Baechle
*
* Kernel data passed by the loader
*/
#include <asm/bootinfo.h>
/*
* Initialise this structure so that it will be placed in the
* .data section of the object file
*/
struct bootinfo boot_info = BOOT_INFO;
/*
* arch/mips/kernel/cache.S
*
* Copyright (C) 1994, 1995 Waldorf Electronics
* Written by Ralf Baechle
*
* Flush instruction/data caches
*
* Parameters: a0 - starting address to flush
* a1 - size of area to be flushed
* a2 - which caches to be flushed
*
* FIXME: - ignores parameters
* - doesn't know about second level caches
* - only knows how to handle the R4600
*/
#include <asm/mipsconfig.h>
#include <asm/regdef.h>
#include <asm/segment.h>
#define PAGE_SIZE 0x1000
#define CACHELINES 512 /* number of cachelines */
.set noreorder
.globl _sys_cacheflush
.text
_sys_cacheflush:
/*
* Writeback/invalidate the data cache
*/
li t0,KSEG0
li t1,CACHELINES
1: cache 1,0(t0)
cache 1,32(t0)
cache 1,64(t0)
cache 1,96(t0)
cache 1,128(t0)
cache 1,160(t0)
cache 1,192(t0)
cache 1,224(t0)
cache 1,256(t0)
cache 1,288(t0)
cache 1,320(t0)
cache 1,352(t0)
cache 1,384(t0)
cache 1,416(t0)
cache 1,448(t0)
cache 1,480(t0)
subu t1,t1,1
bnez t1,1b
addiu t0,t0,512 # delay slot
/*
* Flush the instruction cache
*/
lui t0,0x8000
li t1,CACHELINES
1: cache 0,0(t0)
cache 0,32(t0)
cache 0,64(t0)
cache 0,96(t0)
cache 0,128(t0)
cache 0,160(t0)
cache 0,192(t0)
cache 0,224(t0)
cache 0,256(t0)
cache 0,288(t0)
cache 0,320(t0)
cache 0,352(t0)
cache 0,384(t0)
cache 0,416(t0)
cache 0,448(t0)
cache 0,480(t0)
subu t1,t1,1
bnez t1,1b
addiu t0,t0,512 # delay slot
j ra
nop
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* arch/mips/kernel/head.S
*
* Copyright (C) 1994 Waldorf Electronics
* Written by Ralf Baechle and Andreas Busse
*
* Head.S contains the MIPS exception handler and startup code.
* Flush the TLB
*
* FIXME: knows only how to handle R4x00
* Read appendix f of the R4000 manual before you change something!
*/
#include <asm/mipsregs.h>
#include <asm/regdef.h>
#include <asm/bootinfo.h>
.globl _tlbflush
_tlbflush: li t0,PM_4K
mtc0 t0,CP0_PAGEMASK
lw t0,_boot_info+OFFSET_BOOTINFO_TLB_ENTRIES(t0)
li t0,48
dmtc0 zero,CP0_ENTRYLO0
dmtc0 zero,CP0_ENTRYLO1
mfc0 t2,CP0_WIRED
1: subu t0,t0,1
mtc0 t0,CP0_INDEX
lui t1,0x0008
or t1,t0,t1
dsll t1,t1,13
dmtc0 t1,CP0_ENTRYHI
bne t2,t0,1b
tlbwi # delay slot
jr ra
nop
This diff is collapsed.
/*
* arch/mips/vm86.c
*
* Copyright (C) 1994 Waldorf GMBH,
* written by Ralf Baechle
*/
#include <linux/linkage.h>
#include <linux/errno.h>
#include <linux/vm86.h>
asmlinkage int sys_vm86(struct vm86_struct * v86)
{
return -ENOSYS;
}
#
# Makefile for the linux i386-specific parts of the memory manager.
#
# 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 definition is now in the main makefile...
.c.o:
$(CC) $(CFLAGS) -c $<
.s.o:
$(AS) -o $*.o $<
.c.s:
$(CC) $(CFLAGS) -S $<
OBJS = fault.o
mm.o: $(OBJS)
$(LD) -r -o mm.o $(OBJS)
modules:
dep:
$(CPP) $(CFLAGS) -M *.c > .depend
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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