diff -u --recursive --new-file v1.1.81/linux/Makefile linux/Makefile --- v1.1.81/linux/Makefile Fri Jan 13 16:57:03 1995 +++ linux/Makefile Mon Jan 16 07:18:23 1995 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 81 +SUBLEVEL = 82 ARCH = i386 @@ -18,6 +18,7 @@ MAKE =make CPP =$(CC) -E AR =ar +NM =nm STRIP =strip all: do-it-all @@ -88,7 +89,7 @@ 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 @@ $(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 diff -u --recursive --new-file v1.1.81/linux/arch/alpha/Makefile linux/arch/alpha/Makefile --- v1.1.81/linux/arch/alpha/Makefile Mon Jan 9 11:24:19 1995 +++ linux/arch/alpha/Makefile Mon Jan 16 07:17:34 1995 @@ -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 diff -u --recursive --new-file v1.1.81/linux/arch/alpha/boot/Makefile linux/arch/alpha/boot/Makefile --- v1.1.81/linux/arch/alpha/boot/Makefile Thu Dec 29 19:58:40 1994 +++ linux/arch/alpha/boot/Makefile Mon Jan 16 13:41:14 1995 @@ -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: diff -u --recursive --new-file v1.1.81/linux/arch/alpha/boot/head.S linux/arch/alpha/boot/head.S --- v1.1.81/linux/arch/alpha/boot/head.S Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/boot/head.S Mon Jan 16 07:17:34 1995 @@ -0,0 +1,131 @@ +/* + * arch/alpha/boot/head.S + * + * initial bootloader stuff.. + */ + +#include + +#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 + diff -u --recursive --new-file v1.1.81/linux/arch/alpha/boot/main.c linux/arch/alpha/boot/main.c --- v1.1.81/linux/arch/alpha/boot/main.c Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/boot/main.c Mon Jan 16 07:17:34 1995 @@ -0,0 +1,204 @@ +/* + * arch/alpha/boot/main.c + * + * Copyright (C) 1994, 1995 Linus Torvalds + * + * This file is the bootloader for the Linux/AXP kernel + */ +#include +#include +#include + +#include +#include +#include +#include + +#include + +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(); +} diff -u --recursive --new-file v1.1.81/linux/arch/alpha/boot/tools/build.c linux/arch/alpha/boot/tools/build.c --- v1.1.81/linux/arch/alpha/boot/tools/build.c Thu Dec 29 19:58:40 1994 +++ linux/arch/alpha/boot/tools/build.c Mon Jan 16 07:17:34 1995 @@ -12,12 +12,11 @@ #include -#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 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 @@ 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 @@ 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 @@ } 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 @@ } } 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 @@ 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; } diff -u --recursive --new-file v1.1.81/linux/arch/alpha/config.in linux/arch/alpha/config.in --- v1.1.81/linux/arch/alpha/config.in Wed Jan 11 21:14:25 1995 +++ linux/arch/alpha/config.in Mon Jan 16 07:17:34 1995 @@ -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 diff -u --recursive --new-file v1.1.81/linux/arch/alpha/kernel/Makefile linux/arch/alpha/kernel/Makefile --- v1.1.81/linux/arch/alpha/kernel/Makefile Mon Jan 9 07:21:55 1995 +++ linux/arch/alpha/kernel/Makefile Mon Jan 16 07:17:34 1995 @@ -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 diff -u --recursive --new-file v1.1.81/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S --- v1.1.81/linux/arch/alpha/kernel/entry.S Mon Jan 9 11:24:19 1995 +++ linux/arch/alpha/kernel/entry.S Mon Jan 16 13:41:14 1995 @@ -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 +.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 entMM + + .align 5 + .globl sys_call_table +sys_call_table: + .quad 0 diff -u --recursive --new-file v1.1.81/linux/arch/alpha/kernel/head.S linux/arch/alpha/kernel/head.S --- v1.1.81/linux/arch/alpha/kernel/head.S Mon Jan 9 07:21:55 1995 +++ linux/arch/alpha/kernel/head.S Mon Jan 16 07:17:34 1995 @@ -1,7 +1,10 @@ /* * 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 @@ .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 + .globl wrusp + .ent wrusp +wrusp: + .long PAL_wrusp + ret ($26) + .end wrusp + + .align 5 + .globl rdusp + .ent rdusp +rdusp: + .long PAL_rdusp ret ($26) + .end rdusp + -__do_swppal: - .long PAL_swppal - .end switch_to_osf_pal diff -u --recursive --new-file v1.1.81/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c --- v1.1.81/linux/arch/alpha/kernel/irq.c Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/kernel/irq.c Mon Jan 16 13:41:14 1995 @@ -0,0 +1,236 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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<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); +} diff -u --recursive --new-file v1.1.81/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v1.1.81/linux/arch/alpha/kernel/process.c Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/kernel/process.c Mon Jan 16 07:17:34 1995 @@ -0,0 +1,96 @@ +/* + * linux/arch/alpha/kernel/process.c + * + * Copyright (C) 1995 Linus Torvalds + */ + +/* + * This file handles the architecture-dependent parts of process handling.. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +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; +} diff -u --recursive --new-file v1.1.81/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c --- v1.1.81/linux/arch/alpha/kernel/setup.c Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/kernel/setup.c Mon Jan 16 13:41:14 1995 @@ -0,0 +1,92 @@ +/* + * linux/arch/alpha/kernel/setup.c + * + * Copyright (C) 1995 Linus Torvalds + */ + +/* + * bootup setup stuff.. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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; +} diff -u --recursive --new-file v1.1.81/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c --- v1.1.81/linux/arch/alpha/kernel/signal.c Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/kernel/signal.c Mon Jan 16 07:17:34 1995 @@ -0,0 +1,75 @@ +/* + * linux/arch/alpha/kernel/signal.c + * + * Copyright (C) 1995 Linus Torvalds + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#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; +} diff -u --recursive --new-file v1.1.81/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c --- v1.1.81/linux/arch/alpha/kernel/traps.c Mon Jan 9 07:21:55 1995 +++ linux/arch/alpha/kernel/traps.c Mon Jan 16 13:41:14 1995 @@ -10,42 +10,18 @@ #include -#include -#include - -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 @@ "___tmp:\tldgp %0,0(%0)" : "=r" (gptr)); wrkgp(gptr); - wrent(entInt, 0); + wrent(entMM, 2); } diff -u --recursive --new-file v1.1.81/linux/arch/alpha/lib/divide.S linux/arch/alpha/lib/divide.S --- v1.1.81/linux/arch/alpha/lib/divide.S Fri Jan 13 10:12:22 1995 +++ linux/arch/alpha/lib/divide.S Sun Jan 15 21:36:08 1995 @@ -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 diff -u --recursive --new-file v1.1.81/linux/arch/alpha/mm/Makefile linux/arch/alpha/mm/Makefile --- v1.1.81/linux/arch/alpha/mm/Makefile Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/mm/Makefile Mon Jan 16 07:17:34 1995 @@ -0,0 +1,32 @@ +# +# 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 diff -u --recursive --new-file v1.1.81/linux/arch/alpha/mm/fault.c linux/arch/alpha/mm/fault.c --- v1.1.81/linux/arch/alpha/mm/fault.c Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/mm/fault.c Mon Jan 16 07:17:34 1995 @@ -0,0 +1,93 @@ +/* + * linux/arch/alpha/mm/fault.c + * + * Copyright (C) 1995 Linus Torvalds + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +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); +} diff -u --recursive --new-file v1.1.81/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c --- v1.1.81/linux/arch/alpha/mm/init.c Thu Jan 1 02:00:00 1970 +++ linux/arch/alpha/mm/init.c Mon Jan 16 13:41:14 1995 @@ -0,0 +1,187 @@ +/* + * linux/arch/alpha/mm/init.c + * + * Copyright (C) 1995 Linus Torvalds + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +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; +} diff -u --recursive --new-file v1.1.81/linux/arch/i386/config.in linux/arch/i386/config.in --- v1.1.81/linux/arch/i386/config.in Fri Jan 13 16:57:03 1995 +++ linux/arch/i386/config.in Sun Jan 15 21:56:52 1995 @@ -24,6 +24,9 @@ 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 diff -u --recursive --new-file v1.1.81/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile --- v1.1.81/linux/arch/i386/kernel/Makefile Mon Jan 9 11:24:19 1995 +++ linux/arch/i386/kernel/Makefile Mon Jan 16 07:17:34 1995 @@ -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 diff -u --recursive --new-file v1.1.81/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c --- v1.1.81/linux/arch/i386/kernel/bios32.c Wed Jan 11 21:14:25 1995 +++ linux/arch/i386/kernel/bios32.c Sun Jan 15 21:55:55 1995 @@ -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 '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 @@ -485,7 +487,7 @@ 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 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 @@ bus, dev_fn, (unsigned char) PCI_DEVICE_ID, &device); for (i=0;i 31) + if(pci_index > PCI_LIST_SIZE-1) { printk("PCI resource list full.\n"); return; @@ -618,11 +700,12 @@ { 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 @@ 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)) diff -u --recursive --new-file v1.1.81/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v1.1.81/linux/arch/i386/kernel/irq.c Mon Jan 9 07:21:56 1995 +++ linux/arch/i386/kernel/irq.c Mon Jan 16 07:17:35 1995 @@ -1,5 +1,5 @@ /* - * 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 @@ -28,6 +21,7 @@ #include #include #include +#include #include #include @@ -147,7 +141,14 @@ /* * 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 @@ 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 @@ */ 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_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 @@ 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 @@ 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 @@ * 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 @@ 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 @@ { 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")) diff -u --recursive --new-file v1.1.81/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v1.1.81/linux/arch/i386/kernel/process.c Fri Jan 13 10:12:22 1995 +++ linux/arch/i386/kernel/process.c Mon Jan 16 07:17:35 1995 @@ -23,27 +23,6 @@ #include #include -/* - * 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"); /* diff -u --recursive --new-file v1.1.81/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- v1.1.81/linux/arch/i386/kernel/setup.c Thu Jan 1 02:00:00 1970 +++ linux/arch/i386/kernel/setup.c Mon Jan 16 07:17:35 1995 @@ -0,0 +1,121 @@ +/* + * linux/arch/i386/kernel/setup.c + * + * Copyright (C) 1995 Linus Torvalds + */ + +/* + * This file handles the architecture-dependent parts of process handling.. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + * 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; +} diff -u --recursive --new-file v1.1.81/linux/arch/i386/mm/Makefile linux/arch/i386/mm/Makefile --- v1.1.81/linux/arch/i386/mm/Makefile Fri Jan 13 10:12:22 1995 +++ linux/arch/i386/mm/Makefile Mon Jan 16 07:17:35 1995 @@ -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) diff -u --recursive --new-file v1.1.81/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c --- v1.1.81/linux/arch/i386/mm/fault.c Fri Jan 13 10:12:22 1995 +++ linux/arch/i386/mm/fault.c Mon Jan 16 07:17:35 1995 @@ -18,19 +18,7 @@ #include #include -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 @@ 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; /* @@ -126,224 +114,4 @@ } 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; } diff -u --recursive --new-file v1.1.81/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c --- v1.1.81/linux/arch/i386/mm/init.c Thu Jan 1 02:00:00 1970 +++ linux/arch/i386/mm/init.c Mon Jan 16 07:17:35 1995 @@ -0,0 +1,244 @@ +/* + * linux/arch/i386/mm/init.c + * + * Copyright (C) 1995 Linus Torvalds + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +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; +} diff -u --recursive --new-file v1.1.81/linux/arch/mips/Makefile linux/arch/mips/Makefile --- v1.1.81/linux/arch/mips/Makefile Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/Makefile Sun Jan 15 21:10:38 1995 @@ -0,0 +1,55 @@ +# +# 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 diff -u --recursive --new-file v1.1.81/linux/arch/mips/boot/Makefile linux/arch/mips/boot/Makefile --- v1.1.81/linux/arch/mips/boot/Makefile Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/boot/Makefile Sun Jan 15 01:05:09 1995 @@ -0,0 +1,24 @@ +# +# 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 diff -u --recursive --new-file v1.1.81/linux/arch/mips/config.in linux/arch/mips/config.in --- v1.1.81/linux/arch/mips/config.in Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/config.in Mon Jan 16 00:08:08 1995 @@ -0,0 +1,249 @@ +# +# 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 diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/Makefile linux/arch/mips/kernel/Makefile --- v1.1.81/linux/arch/mips/kernel/Makefile Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/Makefile Mon Jan 16 02:41:19 1995 @@ -0,0 +1,62 @@ +# +# 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 diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/bootinfo.c linux/arch/mips/kernel/bootinfo.c --- v1.1.81/linux/arch/mips/kernel/bootinfo.c Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/bootinfo.c Mon Jan 16 00:59:46 1995 @@ -0,0 +1,14 @@ +/* + * arch/mips/kernel/bootinfo.c + * + * Copyright (C) 1995 Ralf Baechle + * + * Kernel data passed by the loader + */ +#include + +/* + * Initialise this structure so that it will be placed in the + * .data section of the object file + */ +struct bootinfo boot_info = BOOT_INFO; diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/cache.S linux/arch/mips/kernel/cache.S --- v1.1.81/linux/arch/mips/kernel/cache.S Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/cache.S Fri Jan 13 20:27:37 1995 @@ -0,0 +1,81 @@ +/* + * 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 +#include +#include + +#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 diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/entry.S linux/arch/mips/kernel/entry.S --- v1.1.81/linux/arch/mips/kernel/entry.S Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/entry.S Sun Jan 15 21:52:36 1995 @@ -0,0 +1,945 @@ +/* + * arch/mips/kernel/entry.S + * + * Copyright (C) 1994, 1995 Waldorf Electronics + * written by Ralf Baechle + */ + +/* + * entry.S contains the system-call and fault low-level handling routines. + * This also contains the timer-interrupt handler, as well as all interrupts + * and faults that can result in a task-switch. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * These are offsets into the task-struct. + */ +state = 0 +counter = 4 +priority = 8 +signal = 12 +blocked = 16 +flags = 20 +errno = 24 #/* MIPS OK */ +exec_domain = 60 #/* ??? */ + +ENOSYS = 38 + + .globl ret_from_sys_call + .globl _sys_call_table + + .text + .set noreorder + .align 4 +handle_bottom_half: + lui s0,%hi(_intr_count) + lw s1,%lo(_intr_count)(s0) + mfc0 s3,CP0_STATUS # Enable IRQs + addiu s2,s1,1 + sw s2,%lo(_intr_count)(s0) + ori t0,s3,0x1f + xori t0,t0,0x1e + jal _do_bottom_half + mtc0 t0,CP0_STATUS # delay slot + mtc0 s3,CP0_STATUS # Restore old IRQ state + j 9f + sw s1,%lo(_intr_count)(s0) # delay slot + + .set reorder +reschedule: + la ra,ret_from_sys_call + j _schedule + nop + + .align 5 + .globl _handle_sys +_handle_sys: + .set noreorder + .set noat + SAVE_ALL + .set at + STI + /* + * Compute return address. For now we assume that syscalls never + * appear in branch delay slots. For the Linux/MIPS standard + * libraries this assumption is always try. + */ + lw t3,FR_EPC(sp) + lw s1,FR_REG2(sp) + li t0,-ENOSYS + addiu t3,t3,4 + sw t3,FR_EPC(sp) + li t2,NR_syscalls + bge s1,t2,ret_from_sys_call + sw t0,FR_REG2(sp) # delay slot + sll s1,s1,2 + lw s1,_sys_call_table(s1) + lw s0,_current + + beqz s1,ret_from_sys_call + lw t0,flags(s0) + sll t0,t0,2 # PF_TRACESYS + bltz t0,1f + sw zero,errno(s0) # delay slot + + lw a0,FR_REG4(sp) + lw a1,FR_REG5(sp) + lw a2,FR_REG6(sp) + lw a3,FR_REG7(sp) + lw t0,FR_REG3(sp) + jalr s1 # do the real work + sw t0,16(sp) # delay slot + + lw t0,errno(s0) + sw v0,FR_REG2(sp) # save the return value + subu t0,zero,t0 # t0 = -t0 + beqz t0,ret_from_sys_call + nop + /* + * Fixme: should set error flag + */ + j ret_from_sys_call + sw t0,FR_REG2(sp) # delay slot + + .align 4 +1: jal _syscall_trace + nop # delay slot + + lw a0,FR_REG4(sp) + lw a1,FR_REG5(sp) + lw a2,FR_REG6(sp) + lw a3,FR_REG7(sp) + lw t0,FR_REG3(sp) + jalr s1 # do the real work + sw t0,16(sp) # delay slot + + lw t0,errno(s0) + sw v0,FR_REG2(sp) # save the return value + subu t0,zero,t0 + beqz t0,1f + nop # delay slot + sw t1,FR_REG2(sp) + /* + * Fixme: should set error flag + */ +1: jal _syscall_trace + nop + + .align 4 +ret_from_sys_call: + lw t0,_intr_count # bottom half + bnez t0,2f +9: + lw t0,_bh_mask # delay slot + lw t1,_bh_active # unused delay slot + and t0,t1 + bnez t0,handle_bottom_half + + lw t0,FR_STATUS(sp) # returning to supervisor ? + andi t1,t0,0x10 + beqz t1,2f + + mfc0 t0,CP0_STATUS # delay slot + lw t1,_need_resched + ori t0,0x1f # enable irqs + xori t0,0x1e + bnez t1,reschedule + mtc0 t0,CP0_STATUS # delay slot + + lw s0,_current + lw t0,_task + lw t1,state(s0) # state + beq s0,t0,2f # task[0] cannot have signals + lw t0,counter(s0) # counter + bnez t1,reschedule # state == 0 ? + lw a0,blocked(s0) + # save blocked in a0 for + # signal handling + beqz t0,reschedule # counter == 0 ? + lw t0,signal(s0) + nor t1,zero,a0 + and t1,t0,t1 + beqz t1,skip_signal_return + nop + + jal _do_signal + move a1,sp # delay slot + +skip_signal_return: + .set noreorder + .set noat +2: +return: RESTORE_ALL + .set at + +/* + * Assumptions for _handle_int: + * - only bank a or b are possible interrupt sources + */ + .text + .set noreorder + .set noat + .globl _handle_int + .align 5 +_handle_int: SAVE_ALL + .set at + CLI + lui s0,%hi(PORT_BASE) + li t1,0x0f + sb t1,%lo(PORT_BASE+0x20)(s0) # poll command + lb t1,%lo(PORT_BASE+0x20)(s0) # read result + li s1,1 + bgtz t1,poll_second + andi t1,t1,7 + /* + * Acknowledge first pic + */ + lb t2,%lo(PORT_BASE+0x21)(s0) + lui s4,%hi(_cache_21) + lb t0,%lo(_cache_21)(s4) + sllv s1,s1,t1 + or t0,t0,s1 + sb t0,%lo(_cache_21)(s4) + sb t0,%lo(PORT_BASE+0x21)(s0) + lui s3,%hi(_intr_count) + lw t0,%lo(_intr_count)(s3) + li t2,0x20 + sb t2,%lo(PORT_BASE+0x20)(s0) + /* + * Now call the real handler + */ + la t3,_IRQ_vectors + sll t2,t1,2 + addu t3,t3,t2 + lw t3,(t3) + addiu t0,t0,1 + jalr t3 + sw t0,%lo(_intr_count)(s3) # delay slot + lw t0,%lo(_intr_count)(s3) + /* + * Unblock first pic + */ + lbu t1,%lo(PORT_BASE+0x21)(s0) + lb t1,%lo(_cache_21)(s4) + subu t0,t0,1 + sw t0,%lo(_intr_count)(s3) + nor s1,zero,s1 + and t1,t1,s1 + sb t1,%lo(_cache_21)(s4) + jr v0 + sb t1,%lo(PORT_BASE+0x21)(s0) # delay slot + + .align 5 +poll_second: li t1,0x0f + sb t1,%lo(PORT_BASE+0xa0)(s0) # poll command + lb t1,%lo(PORT_BASE+0xa0)(s0) # read result + lui s4,%hi(_cache_A1) + bgtz t1,spurious_interrupt + andi t1,t1,7 + /* + * Acknowledge second pic + */ + lbu t2,%lo(PORT_BASE+0xa1)(s0) + lb t3,%lo(_cache_A1)(s4) + sllv s1,s1,t1 + or t3,t3,s1 + sb t3,%lo(_cache_A1)(s4) + sb t3,%lo(PORT_BASE+0xa1)(s0) + li t3,0x20 + sb t3,%lo(PORT_BASE+0xa0)(s0) + lui s3,%hi(_intr_count) + lw t0,%lo(_intr_count)(s3) + sb t3,%lo(PORT_BASE+0x20)(s0) + /* + * Now call the real handler + */ + la t0,_IRQ_vectors + sll t2,t1,2 + addu t0,t0,t2 + lw t0,32(t0) + addiu t0,t0,1 + jalr t0 + sw t0,%lo(_intr_count)(s3) # delay slot + lw t0,%lo(_intr_count)(s3) + /* + * Unblock second pic + */ + lb t1,%lo(PORT_BASE+0xa1)(s0) + lb t1,%lo(_cache_A1)(s4) + subu t0,t0,1 + lw t0,%lo(_intr_count)(s3) + nor s1,zero,s1 + and t1,t1,s1 + sb t1,%lo(_cache_A1)(s4) + jr v0 + sb t1,%lo(PORT_BASE+0xa1)(s0) # delay slot + + .align 5 +spurious_interrupt: + /* + * Nothing happend... (whistle) + */ + lui t1,%hi(_spurious_count) + lw t0,%lo(_spurious_count)(t1) + la v0,return + addiu t0,t0,1 + jr ra + sw t0,%lo(_spurious_count)(t1) + + .globl _interrupt + .align 5 +_interrupt: move s2,ra + mfc0 t0,CP0_STATUS + ori t0,t0,0x1f + xori t0,t0,0x1e + mtc0 t0,CP0_STATUS + move a0,t1 + jal _do_IRQ + move a1,sp # delay slot + mfc0 t0,CP0_STATUS + ori t0,t0,1 + xori t0,t0,1 + la v0,ret_from_sys_call + jr s2 + mtc0 t0,CP0_STATUS # delay slot + + .globl _fast_interrupt + .align 5 +_fast_interrupt: + move s2,ra + move a0,t1 + jal _do_fast_IRQ + move a1,sp # delay slot + la v0,return + jr s2 + nop # delay slot + + .globl _bad_interrupt +_bad_interrupt: + /* + * Don't return & unblock the pic + */ + j return + nop + + .globl _handle_tlbl + .align 5 +_handle_tlbl: + .set noreorder + .set noat + /* + * Check whether this is a refill or an invalid exception + * + * NOTE: Some MIPS manuals say that the R4x00 sets the + * BadVAddr only when EXL == 0. This is wrong - BadVaddr + * is being set for all Reload, Invalid and Modified + * exceptions. + */ + mfc0 k0,CP0_BADVADDR + mfc0 k1,CP0_ENTRYHI + ori k0,k0,0x1fff + xori k0,k0,0x1fff + andi k1,k1,0xff + or k0,k0,k1 + mfc0 k1,CP0_ENTRYHI + mtc0 k0,CP0_ENTRYHI + nop # for R4[04]00 pipeline + nop + nop + tlbp + nop # for R4[04]00 pipeline + nop + mfc0 k0,CP0_INDEX + srl k0,k0,31 + beqz k0,invalid_tlbl + mtc0 k1,CP0_ENTRYHI # delay slot + /* + * Not in tlb -> nested refill exception + * Load the missing entry and return. This is the most + * efficient way to regain the faulting address. + */ + dmfc0 k1,CP0_CONTEXT + dsra k1,k1,1 + lwu k0,(k1) # Never causes another exception + lwu k1,4(k1) + dsrl k0,k0,6 # Convert to EntryLo format + dsrl k1,k1,6 # Convert to EntryLo format + dmtc0 k0,CP0_ENTRYLO0 + dmtc0 k1,CP0_ENTRYLO1 + nop # for R4[04]00 pipeline + tlbwr + eret + + /* + * Handle invalid exception + * + * There are two possible causes for an invalid (tlbl) + * exception: + * 1) pages that have the present bit set but the valid bit + * unset. + * 2) pages that don't exist + * Case one needs fast handling, therefore don't save + * registers yet. + * + * k0 now contains the bad virtual address. + */ +invalid_tlbl: + /* + * Remove entry so we don't need to care later + */ + mfc0 k0,CP0_INDEX + lui k1,0x0008 + or k0,k0,k1 + dsll k0,k0,13 + dmtc0 k0,CP0_ENTRYHI + dmtc0 zero,CP0_ENTRYLO0 + dmtc0 zero,CP0_ENTRYLO1 + /* + * Test whether present bit in entry is set + */ + dmfc0 k0,CP0_BADVADDR + tlbwi # delayed, for R4[04]00 pipeline + srl k0,k0,10 + lui k1,%HI(TLBMAP) + addu k0,k0,k1 + ori k0,k0,3 + xori k0,k0,3 + lw k1,(k0) + andi k1,k1,PAGE_PRESENT + beqz k1,nopage_tlbl + /* + * Present bit is set -> set valid and accessed bits + */ + lw k1,(k0) # delay slot + ori k1,k1,PAGE_ACCESSED + sw k1,(k0) + eret + + /* + * Page doesn't exist. Lots of work which is less important + * for speed needs to be done, so hand it all over to the + * kernel memory management routines. + */ +nopage_tlbl: + SAVE_ALL + .set at + STI + /* + * Create a Intel-style errorcode + * Bit 0: P Present + * 0 == Page not in memory + * 1 == privilege violation + * Bit 1: R/W Read/Write + * 0 == ReadAccess + * 1 == WriteAccess + * Bit 2: U/S User/Supervisor + * 0 == User mode + * 1 == Kernel mode + * + * a0 (struct pt_regs *) regs + * a1 (unsigned long) error_code + */ + lw a1,FR_STATUS(sp) + move a0,sp + srl a1,a1,4 + andi a1,a1,1 + jal _do_page_fault + xori a1,a1,1 # delay slot + j ret_from_sys_call + nop # delay slot + + .text + .globl _handle_tlbs + .align 5 +_handle_tlbs: + .set noreorder + .set noat + /* + * It is impossible that is a nested reload exception. + * Therefore this must be a invalid exception. + * Two possible cases: + * 1) Page not used yet + * 2) Page doesn't exist yet. Let the kernel handle the trouble. + * + * Test whether present bit in entry is set + */ + dmfc0 k0,CP0_BADVADDR + srl k0,k0,10 + lui k1,%HI(TLBMAP) + addu k0,k0,k1 + ori k0,k0,3 + xori k0,k0,3 + lw k1,(k0) + andi k1,k1,(PAGE_PRESENT|PAGE_RW) + beqz k1,nopage_tlbs + /* + * Present and writable bits set -> set accessed and dirty bits. + */ + lw k1,(k0) # delay slot + ori k1,k1,PAGE_ACCESSED|PAGE_DIRTY + sw k1,(k0) + /* + * Now reload the entry into the tlb + */ + ori k0,k0,0x1000 + xori k0,k0,0x1000 + lw k1,4(k0) + lw k0,(k0) + srl k0,k0,6 + srl k1,k1,6 + dmtc0 k0,CP0_ENTRYLO0 + dmtc0 k1,CP0_ENTRYLO1 + tlbwi + eret + + /* + * Page doesn't exist. Lots of work which is less important + * for speed needs to be done, so hand it all over to the + * kernel memory management routines. + */ +nopage_tlbs: +nowrite_mod: + /* + * Remove entry so we don't need to care later + */ + mfc0 k0,CP0_INDEX + lui k1,0x0008 + or k0,k0,k1 + dsll k0,k0,13 + dmtc0 k0,CP0_ENTRYHI + dmtc0 zero,CP0_ENTRYLO0 + dmtc0 zero,CP0_ENTRYLO1 + tlbwi + SAVE_ALL + .set at + STI + /* + * Create a Intel-style errorcode + * Bit 0: P Present + * 0 == Page not in memory + * 1 == privilege violation + * Bit 1: R/W Read/Write + * 0 == ReadAccess + * 1 == WriteAccess + * Bit 2: U/S User/Supervisor + * 0 == User mode + * 1 == Kernel mode + * + * a0 (struct pt_regs *) regs + * a1 (unsigned long) error_code + */ + lw a1,FR_STATUS(sp) + move a0,sp + srl a1,a1,4 + andi a1,a1,1 + jal _do_page_fault + xori a1,a1,3 # branch delay slot + j ret_from_sys_call + nop # branch delay slot + + .globl _handle_mod + .align 5 +_handle_mod: + .set noreorder + .set noat + /* + * Two possible cases: + * 1) Page is rw but not dirty -> set dirty and return + * 2) Page is not rw -> call C handler + */ + dmfc0 k0,CP0_BADVADDR + srl k0,k0,10 + lui k1,%HI(TLBMAP) + addu k0,k0,k1 + ori k0,k0,3 + xori k0,k0,3 + lw k1,(k0) + andi k1,k1,PAGE_RW + beqz k1,nopage_tlbs + /* + * Present and writable bits set -> set accessed and dirty bits. + */ + lw k1,(k0) # delay slot + ori k1,k1,(PAGE_ACCESSED|PAGE_DIRTY) + sw k1,(k0) + /* + * Now reload the entry into the tlb + */ + ori k0,k0,0x1000 + xori k0,k0,0x1000 + lw k1,4(k0) + lw k0,(k0) + srl k0,k0,6 + srl k1,k1,6 + dmtc0 k0,CP0_ENTRYLO0 + dmtc0 k1,CP0_ENTRYLO1 + tlbwi + eret + + .globl _handle_adel + .align 5 +_handle_adel: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_adel + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_ades + .align 5 +_handle_ades: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_ades + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_ibe + .align 5 +_handle_ibe: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_ibe + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_dbe + .align 5 +_handle_dbe: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_dbe + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_ov + .align 5 +_handle_ov: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_ov + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_fpe + .align 5 +_handle_fpe: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_fpe + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_bp + .align 5 +_handle_bp: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_bp + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_tr + .align 5 +_handle_tr: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_tr + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_ri + .align 5 +_handle_ri: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_ri + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_cpu + .align 5 +_handle_cpu: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_cpu + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_vcei + .align 5 +_handle_vcei: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_vcei + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_vced + .align 5 +_handle_vced: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_vced + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_watch + .align 5 +_handle_watch: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_watch + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + + .globl _handle_reserved + .align 5 +_handle_reserved: + .set noreorder + .set noat + SAVE_ALL + STI + li t0,-1 + sw t0,FR_ORIG_REG2(sp) + jal _do_reserved + move a0,sp # delay slot + j ret_from_sys_call + nop # delay slot + +/* + * Exception handler table with 32 entries. + * This might be extended to handle software exceptions + */ + .bss + .globl _exception_handlers + .align 2 +_exception_handlers: + .fill 32,4,0 + +/* + * Table of syscalls + */ + .data +_sys_call_table: + .word _sys_setup /* 0 */ + .word _sys_exit + .word _sys_fork + .word _sys_read + .word _sys_write + .word _sys_open /* 5 */ + .word _sys_close + .word _sys_waitpid + .word _sys_creat + .word _sys_link + .word _sys_unlink /* 10 */ + .word _sys_execve + .word _sys_chdir + .word _sys_time + .word _sys_mknod + .word _sys_chmod /* 15 */ + .word _sys_chown + .word _sys_break + .word _sys_stat + .word _sys_lseek + .word _sys_getpid /* 20 */ + .word _sys_mount + .word _sys_umount + .word _sys_setuid + .word _sys_getuid + .word _sys_stime /* 25 */ + .word _sys_ptrace + .word _sys_alarm + .word _sys_fstat + .word _sys_pause + .word _sys_utime /* 30 */ + .word _sys_stty + .word _sys_gtty + .word _sys_access + .word _sys_nice + .word _sys_ftime /* 35 */ + .word _sys_sync + .word _sys_kill + .word _sys_rename + .word _sys_mkdir + .word _sys_rmdir /* 40 */ + .word _sys_dup + .word _sys_pipe + .word _sys_times + .word _sys_prof + .word _sys_brk /* 45 */ + .word _sys_setgid + .word _sys_getgid + .word _sys_signal + .word _sys_geteuid + .word _sys_getegid /* 50 */ + .word _sys_acct + .word _sys_phys + .word _sys_lock + .word _sys_ioctl + .word _sys_fcntl /* 55 */ + .word _sys_mpx + .word _sys_setpgid + .word _sys_ulimit + .word _sys_olduname + .word _sys_umask /* 60 */ + .word _sys_chroot + .word _sys_ustat + .word _sys_dup2 + .word _sys_getppid + .word _sys_getpgrp /* 65 */ + .word _sys_setsid + .word _sys_sigaction + .word _sys_sgetmask + .word _sys_ssetmask + .word _sys_setreuid /* 70 */ + .word _sys_setregid + .word _sys_sigsuspend + .word _sys_sigpending + .word _sys_sethostname + .word _sys_setrlimit /* 75 */ + .word _sys_getrlimit + .word _sys_getrusage + .word _sys_gettimeofday + .word _sys_settimeofday + .word _sys_getgroups /* 80 */ + .word _sys_setgroups + .word _sys_select + .word _sys_symlink + .word _sys_lstat + .word _sys_readlink /* 85 */ + .word _sys_uselib + .word _sys_swapon + .word _sys_reboot + .word _sys_readdir + .word _sys_mmap /* 90 */ + .word _sys_munmap + .word _sys_truncate + .word _sys_ftruncate + .word _sys_fchmod + .word _sys_fchown /* 95 */ + .word _sys_getpriority + .word _sys_setpriority + .word _sys_profil + .word _sys_statfs + .word _sys_fstatfs /* 100 */ + .word _sys_ioperm + .word _sys_socketcall + .word _sys_syslog + .word _sys_setitimer + .word _sys_getitimer /* 105 */ + .word _sys_newstat + .word _sys_newlstat + .word _sys_newfstat + .word _sys_uname + .word _sys_iopl /* 110 */ + .word _sys_vhangup + .word _sys_idle + .word 0 #_sys_vm86 + .word _sys_wait4 + .word _sys_swapoff /* 115 */ + .word _sys_sysinfo + .word _sys_ipc + .word _sys_fsync + .word _sys_sigreturn + .word _sys_clone /* 120 */ + .word _sys_setdomainname + .word _sys_newuname + .word 0 #_sys_modify_ldt + .word _sys_adjtimex + .word _sys_mprotect /* 125 */ + .word _sys_sigprocmask + .word _sys_create_module + .word _sys_init_module + .word _sys_delete_module + .word _sys_get_kernel_syms /* 130 */ + .word _sys_quotactl + .word _sys_getpgid + .word _sys_fchdir + .word _sys_bdflush + .word _sys_sysfs /* 135 */ + .word _sys_personality + .word 0 /* for afs_syscall */ + .word _sys_setfsuid + .word _sys_setfsgid + .word _sys_llseek /* 140 */ + .space (NR_syscalls-140)*4 + + .bss + .globl _IRQ_vectors +_IRQ_vectors: .fill 16,4,0 + diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/head.S linux/arch/mips/kernel/head.S --- v1.1.81/linux/arch/mips/kernel/head.S Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/head.S Sun Jan 15 23:43:48 1995 @@ -0,0 +1,740 @@ +/* + * mips/head.S + * + * Copyright (C) 1994 Waldorf Electronics + * Written by Ralf Baechle and Andreas Busse + * + * Head.S contains the MIPS exception handler and startup code. + */ + +#undef DEBUGPICA /* undef this if you have a different system */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PAGE_SIZE 0x1000 + +/* + * For now we can't enable write caching. This would cause trouble + * with the page aliases used by the memory management. + * The page table's aliases even have to be uncachable, but that + * doesn't hurt much anyway. + */ +#define PAGE_TABLE 0x0580 /* uncachable */ +#define PAGE_SHARED 0x0580 /* cachable, writethrough, no write allocate */ +#define MODE_ALIAS 0x0016 /* uncachable */ + + .globl _empty_bad_page + .globl _empty_bad_page_table + .globl _pg0 + .globl _empty_zero_page + .globl _tmp_floppy_area + .globl _floppy_track_buffer + .globl _swapper_pg_dir + + .text + .globl _kernelbase +_kernelbase: + +/* + * This is space for the interrupt handlers. + * They are located at virtual address KSEG[01] (physical 0x0) + */ + /* + * TLB refill, EXL == 0 + */ + .set noreorder + .set noat +except_vec0: +#if KERNELBASE == KSEG1 + la k0,1f + jr k0 + nop +1: +#endif + dmfc0 k1,CP0_CONTEXT + dsra k1,k1,1 + lwu k0,(k1) # May cause another exception + lwu k1,4(k1) + dsrl k0,k0,6 # Convert to EntryLo format + dsrl k1,k1,6 # Convert to EntryLo format + dmtc0 k0,CP0_ENTRYLO0 + dmtc0 k1,CP0_ENTRYLO1 + tlbwr + eret + + /* + * XTLB refill, EXL == 0 + * Should never be reached + */ + .org except_vec0+0x80 +except_vec1: +#if KERNELBASE == KSEG1 + la k0,1f + jr k0 + nop +1: +#endif + la a0,xtlb_text + jal _panic + nop +1: j 1b + nop +xtlb_text: .asciz "XTLB Refill exception.\n" + + /* + * Cache Error + */ + .org except_vec1+0x80 +except_vec2: +#if KERNELBASE == KSEG1 + la k0,1f + jr k0 + nop +1: +#endif + /* + * Should never be reached + */ + la a0,xtlb_text + jal _panic + nop +1: j 1b + nop +cache_text: .asciz "Cache error exception\n" + + /* + * General exception vector. + */ + .org except_vec2+0x80 +except_vec3: /* + * Register saving is delayed as long as we don't know + * which registers really need to be saved. + */ +#if KERNELBASE == KSEG1 + la k0,1f + jr k0 + nop +1: +#endif + .set noat + mfc0 k1,CP0_CAUSE + la k0,_exception_handlers + /* + * Next lines assumes that the used CPU type has max. + * 32 different types of exceptions. We might use this + * to implement software exceptions in the future. + */ + andi k1,k1,0x7c + addu k0,k0,k1 + lw k0,(k0) + FILL_LDS + jr k0 + nop + +/******************************************************************************/ + +/* + * Kernel entry + */ + .set noreorder + .set at +kernel_entry: + jal refill + nop + + /* + * Clear BSS first so that there are no surprises... + */ + la t0,__edata + la t1,__end + sw zero,(t0) +1: addiu t0,t0,4 + bnel t0,t1,1b + sw zero,(t0) + +#ifdef DEBUGPICA + la t0,_boot_info + lw t0,OFFSET_BOOTINFO_VRAM_BASE(t0) + li t1,0x0f00 + '3' + sh t1,4(t0) +#endif + + .set noreorder + jal _tlbflush + mtc0 zero,CP0_WIRED + /* + * Spread some mines... + */ + la t0,_end + la t1,0x003ffffc + la t2,KERNELBASE + or t1,t2 + li t2,0xdeadbeef +1: sw t2,(t0) + bne t0,t1,1b + addiu t0,t0,4 + /* + * Initialize memory management, map lowest 4MB + */ + .set reorder + jal setup_paging +#if KERNELBASE == KSEG0 + jal _sys_cacheflush +#endif + +#ifdef DEBUGPICA + la t0,_boot_info + lw t0,OFFSET_BOOTINFO_VRAM_BASE(t0) + li t1,0x0f00 + '4' + sh t1,6(t0) +#endif + /* + * Stack for kernel and init + */ + la sp,_init_user_stack+PAGE_SIZE-24 + sw sp,_kernelsp + +1: jal _start_kernel + /* + * Main should never return here, but + * just in case, we know what happens. + */ + j 1b + +/* + * Setup_paging + * + * Wire mappings for page_tables. + * The page tables are set up, identity-mapping + * the first 4MB. The rest are initialized later. + */ + .set noreorder +setup_paging: + /* + * get base address of map0 table for the + * the board we're running on + */ + la t0,_boot_info + lw t1,OFFSET_BOOTINFO_MACHTYPE(t0) + sll t1,t1,2 # machtype used as index + la t0,map0table + addu t0,t0,t1 + lw t0,(t0) # get base address + + /* + * Get number of wired TLB entries and + * loop over selected map0 table. + */ + lw t1,(t0) # number of wired TLB entries + move t2,zero # TLB entry counter + addiu t3,t1,1 # wire one additional entry + beqz t1,2f # null, exit + mtc0 t3,CP0_WIRED # delay slot + addiu t0,t0,8 +1: lw t4,24(t0) # PageMask + ld t5,0(t0) # entryHi + ld t6,8(t0) # entryLo0 + ld t7,16(t0) # entryLo1 + addiu t2,t2,1 # increment ctr + mtc0 t2,CP0_INDEX # set TLB entry + mtc0 t4,CP0_PAGEMASK + dmtc0 t5,CP0_ENTRYHI + dmtc0 t6,CP0_ENTRYLO0 + dmtc0 t7,CP0_ENTRYLO1 + tlbwi + bne t1,t2,1b # next TLB entry + addiu t0,t0,32 # delay slot + + /* + * We use only 4k pages. Therefore the PageMask register + * is expected to be setup for 4k pages. + */ +2: li t0,PM_4K + mtc0 t0,CP0_PAGEMASK + + la t1,_swapper_pg_dir # swapper_pg_dir is at 0x1000 + la t2,_swapper_pg_dir+(PAGE_SIZE-4) +1: sw zero,(t1) + bne t1,t2,1b + addiu t1,t1,4 # delay slot + + /* + * Setup invalid_pg_table and + * clear page table for the first 4MB + */ + la t0,_pg0 # swapper_pg_dir is at 0x1000 + la t1,_pg0+PAGE_SIZE + li t2,KERNELBASE + addu t0,t2 + addu t1,t2 +1: sw zero,(t0) + addiu t0,t0,4 + bne t0,t1,1b + addiu t2,t2,4 # delay slot + + /* + * Identity-map the kernel in low 4MB memory for ease + * of transition. Unlike the Intel version the kernel + * code/data is automagically being mapped by kseg0. + */ + la t0,_pg0+PAGE_TABLE # set valid bit/user r/w + sw t0,_swapper_pg_dir + + li t0,PAGE_SHARED # set valid bit/user r/w + la t1,_pg0 + la t2,_pg0+PAGE_SIZE + li t3,KERNELBASE + addu t1,t3 + addu t2,t3 +1: sw t0,(t1) + addiu t1,t1,4 + bne t1,t2,1b + addiu t0,t0,PAGE_SIZE # delay slot + + /* + * Now map the pagetables + */ + mtc0 zero,CP0_INDEX + la t0,TLB_ROOT + dmtc0 t0,CP0_ENTRYHI + li t0,_swapper_pg_dir + srl t0,t0,6 + ori t0,t0,MODE_ALIAS # uncachable, dirty, valid + dmtc0 t0,CP0_ENTRYLO0 + dmtc0 zero,CP0_ENTRYLO1 + tlbwi + /* + * Make page zero unaccessible to catch zero references + */ + li t0,KERNELBASE + addiu t0,_pg0 + sw zero,(t0) + /* + * Load the context register with a value that allows + * it to be used as fast as possible in tlb exceptions. + * It is expected that this register's content never + * will be changed. + */ + li t0,TLBMAP + dsll t0,t0,1 + jr ra + dmtc0 t0,CP0_CONTEXT # delay slot + + /* + * Flush the TLB + * + * FIXME: knows only how to handle R4x00 + * Read appendix f of the R4000 manual before you change + * something! + */ + .globl _tlbflush +_tlbflush: li t0,PM_4K + mtc0 t0,CP0_PAGEMASK + lw t0,_boot_info+OFFSET_BOOTINFO_TLB_ENTRIES(t0) + 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 + +/* + * Refill icache + */ +#include +#include +#include + +#define PAGE_SIZE 0x1000 + +#define CACHELINES 512 /* number of cachelines */ + + .set noreorder + .text +refill: + /* + * Refill icache with cache fill command + */ + li t0,KSEG0 + li t1,CACHELINES +1: cache 21,0(t0) + cache 21,32(t0) + cache 21,64(t0) + cache 21,96(t0) + cache 21,128(t0) + cache 21,160(t0) + cache 21,192(t0) + cache 21,224(t0) + cache 21,256(t0) + cache 21,288(t0) + cache 21,320(t0) + cache 21,352(t0) + cache 21,384(t0) + cache 21,416(t0) + cache 21,448(t0) + cache 21,480(t0) + subu t1,t1,1 + bnez t1,1b + addiu t0,t0,512 # delay slot + + jr ra + nop + +/* + * Just for debugging... + */ + .globl _beep +_beep: lw t0,beepflag + nop + bnez t0,1f + lbu t0,0xe0000061 + xori t0,t0,3 + sb t0,0xe0000061 + li t0,1 + sw t0,beepflag +1: jr ra + nop + +/* + * Compute kernel code checksum to check kernel code against corruption + */ + .globl _csum +#if 0 +_csum: jal _sys_cacheflush + move t8,ra # delay slot +#else +_csum: move t8,ra +#endif + li t0,KSEG1 + la t1,final + li t2,KSEG1 + or t0,t2 + or t1,t2 + move v0,zero +1: lw t2,(t0) + addiu t0,t0,4 + bne t0,t1,1b + xor v0,v0,t2 + jr t8 + nop +final: + + .data +/* + * Instead of Intel's strage and unportable segment descriptor magic + * we difference user and kernel space by their address. + * Kernel space (== physical memory) is mapped at KSEG[01], + * User space is mapped at 0x0. + */ + .globl _segment_fs +_segment_fs: .word KERNEL_DS + +/* + * Inital mapping tables for supported Mips boards. + * First item is always the number of wired TLB entries, + * following by EntryHi/EntryLo pairs and page mask. + * Since everything must be quad-aligned (8) we insert + * some dummy zeros. + */ + +/* + * Address table of mapping tables for supported Mips boards. + * Add your own stuff here but don't forget to define your + * target system in bootinfo.h + */ + +map0table: .word map0_dummy # machtype = unknown + .word map0_tyne # Deskstation Tyne + .word map0_pica61 # Acer Pica-61 + +map0_dummy: .word 0 # 0 entries + +/* + * Initial mappings for Deskstation Tyne boards. + */ + .align 8 + +map0_tyne: .word 3 # no. of wired TLB entries + .word 0 # pad for alignment + +# TLB entry 1: ISA I/O + + .quad 0xffffffffe0000000 # TLB #0 EntryHi + .quad 0x24000017 # TLB #0 EntryLo0 + .quad 0 # TLB #0 EntryLo1 + .word PM_64K # page mask + .word 0 # pad for alignment + +# TLB entry 2: ISA memory space + + .quad 0xffffffffe1000000 # TLB #1 EntryHi + .quad 0x04000017 # TLB #1 EntryLo0 + .quad 0 # TLB #1 EntryLo1 + .word PM_1M + .word 0 # pad for alignment + +# TLB entry 3: ISA DMA cache + + .quad 0xffffffffe2000000 # TLB #2 EntryHi + .quad 0x04020017 # TLB #2 EntryLo0 + .quad 0 # TLB #2 EntryLo1 + .word PM_1M + .word 0 # pad for alignment + +/* + * Initial mapping for ACER PICA-61 boards. + * FIXME: These are rather preliminary since many drivers, + * such as serial, parallel, scsi and ethernet need some + * changes to distuingish between "local" (built-in) and + * "optional" (ISA/PCI) I/O hardware. + * Local video ram is mapped to the same location as the + * bios maps it to. Console driver has been changed + * accordingly (new video type: VIDEO_TYPE_PICA_S3). + */ + +map0_pica61: .word 9 # no. wired TLB entries + .word 0 # dummy + +# TLB entry 1: PROM + +# .quad 0xffffffffe1000000 # BIOS mapping + .quad 0xffffffffe4000000 # new mapping + .quad 0x03ffc013 + .quad 0x00000001 # global, not valid + .word PM_256K + .word 0 + +# TLB entry 2: local I/O space + + .quad 0xffffffffe0000000 + .quad 0x02000017 + .quad 0x00000001 # global, not valid + .word PM_64K + .word 0 + +# TLB entry 3: DRAM config register + + .quad 0xffffffffe00e0000 + .quad 0x02003817 + .quad 0x02003c17 + .word PM_64K + .word 0 + +# TLB entry 4: Interrupt source register + + .quad 0xffffffffe0100000 + .quad 0x03c00017 + .quad 0x00000001 # global, not valid + .word PM_4K + .word 0 + +# TLB entry 5: Local video control + + .quad 0xffffffffe0200000 + .quad 0x01800017 + .quad 0x01804017 + .word PM_1M + .word 0 + +# TLB entry 6: Extended video control + + .quad 0xffffffffe0400000 + .quad 0x01808017 + .quad 0x0180c017 + .word PM_1M + .word 0 + +# TLB entry 7: Local video memory (BIOS mapping) + + .quad 0xffffffffe0800000 + .quad 0x01000017 + .quad 0x01010017 + .word PM_4M + .word 0 + +# TLB entry 8: Local video memory (mapped to where Linux expects it) +# not needed anymore +# .quad 0xffffffffe1000000 +# .quad 0x01000017 +# .quad 0x01010017 +# .word PM_4M +# .word 0 + +# TLB entry 9: ISA I/O and ISA memory space (both 16M) + + .quad 0xffffffffe2000000 + .quad 0x02400017 + .quad 0x02440017 + .word PM_16M + .word 0 + +# TLB entry 10: PCR (???) + + .quad 0xffffffffffffe000 + .quad 0x00000001 # nonsense... + .quad 0x0001ffd7 + .word PM_4K + .word 0 + + +/* ------------------------------------------------ + * Mapping as presented by the PICA BIOS. + * This table works. Please leave unmodified! + * ------------------------------------------------ */ +#if 0 +map0_pica61: .word 11 # no. wired TLB entries + .word 0 # dummy + +# TLB entry 0: Don't know what this is good for... + + .quad 0xfffffffffffe2000 + .quad 0x0000029e + .quad 0x00000000 + .word PM_4K + .word 0 + +# TLB entry 1: PROM + + .quad 0xffffffffe1000000 + .quad 0x03ffc013 + .quad 0x00000001 # nonsense ... + .word PM_256K + .word 0 + +# TLB entry 2: local I/O space + + .quad 0xffffffffe0000000 + .quad 0x02000017 + .quad 0x00000001 # nonsense ... + .word PM_64K + .word 0 + +# TLB entry 3: DRAM config register + + .quad 0xffffffffe00e0000 + .quad 0x02003817 + .quad 0x02003c17 + .word PM_64K + .word 0 + +# TLB entry 4: Interrupt source register + + .quad 0xffffffffe0100000 + .quad 0x03c00017 + .quad 0x00000001 # nonsense ... + .word PM_4K + .word 0 + +# TLB entry 5: Local video control + + .quad 0xffffffffe0200000 + .quad 0x01800017 + .quad 0x01804017 + .word PM_1M + .word 0 + +# TLB entry 6: Extended video control + + .quad 0xffffffffe0400000 + .quad 0x01808017 + .quad 0x0180c017 + .word PM_1M + .word 0 + +# TLB entry 7: Local video memory + + .quad 0xffffffffe0800000 + .quad 0x01000017 + .quad 0x01010017 + .word PM_4M + .word 0 + +# TLB entry 8: ISA I/O space + + .quad 0xffffffffe2000000 + .quad 0x02400017 + .quad 0x02440017 + .word PM_16M + .word 0 + +# TLB entry 9: PCR (???) + + .quad 0xffffffffffffe000 + .quad 0x00000001 # nonsense... + .quad 0x0001ffd7 + .word PM_4K + .word 0 + +# TLB entry 10: Extended video prom + + .quad 0xffffffff10000000 + .quad 0x0000141f + .quad 0x00000001 # nonsense + .word PM_64K + .word 0 +#endif + +/* + * page 0 is made non-existent, so that kernel NULL pointer references get + * caught. Thus the swapper page directory has been moved to 0x1000 + * + * XXX Actually, the swapper page directory is at 0x1000 plus 1 megabyte, + * with the introduction of the compressed boot code. Theoretically, + * the original design of overlaying the startup code with the swapper + * page directory is still possible --- it would reduce the size of the kernel + * by 2-3k. This would be a good thing to do at some point..... + */ + .text + + .org 0x1000 +_swapper_pg_dir = 0x1000 +/* + * The page tables are initialized to only 4MB here - the final page + * tables are set up later depending on memory size. + */ + .org 0x2000 +_pg0 = 0x2000 + + .org 0x3000 +_empty_bad_page = 0x3000 + + .org 0x4000 +_empty_bad_page_table = 0x4000 + + .org 0x5000 +_empty_zero_page = 0x5000 + + .org 0x6000 + +/* + * tmp_floppy_area is used by the floppy-driver when DMA cannot + * reach to a buffer-block. It needs to be aligned, so that it isn't + * on a 64kB border. + */ +_tmp_floppy_area: .fill 1024,1,0 +/* + * floppy_track_buffer is used to buffer one track of floppy data: it + * has to be separate from the tmp_floppy area, as otherwise a single- + * sector read/write can mess it up. It can contain one full cylinder (sic) of + * data (36*2*512 bytes). + */ +_floppy_track_buffer: .fill 512*2*36,1,0 + .globl _kernelsp +_kernelsp: .word 0 +beepflag: .word 0 diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/ioport.c linux/arch/mips/kernel/ioport.c --- v1.1.81/linux/arch/mips/kernel/ioport.c Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/ioport.c Sun Jan 15 23:47:42 1995 @@ -0,0 +1,107 @@ +/* + * linux/arch/mips/kernel/ioport.c + */ +#include +#include +#include +#include +#include + +#define IOTABLE_SIZE 32 + +typedef struct resource_entry_t { + u_long from, num; + const char *name; + struct resource_entry_t *next; +} resource_entry_t; + +static resource_entry_t iolist = { 0, 0, "", NULL }; + +static resource_entry_t iotable[IOTABLE_SIZE]; + +/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ +static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value) +{ + int mask; + unsigned long *bitmap_base = bitmap + (base >> 5); + unsigned short low_index = base & 0x1f; + int length = low_index + extent; + + if (low_index != 0) { + mask = (~0 << low_index); + if (length < 32) + mask &= ~(~0 << length); + if (new_value) + *bitmap_base++ |= mask; + else + *bitmap_base++ &= ~mask; + length -= 32; + } + + mask = (new_value ? ~0 : 0); + while (length >= 32) { + *bitmap_base++ = mask; + length -= 32; + } + + if (length > 0) { + mask = ~(~0 << length); + if (new_value) + *bitmap_base++ |= mask; + else + *bitmap_base++ &= ~mask; + } +} + +/* + * this changes the io permissions bitmap in the current task. + */ +asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on) +{ + return -ENOSYS; +} + +unsigned int *stack; + +/* + * sys_iopl has to be used when you want to access the IO ports + * beyond the 0x3ff range: to get the full 65536 ports bitmapped + * you'd need 8kB of bitmaps/process, which is a bit excessive. + * + * Here we just change the eflags value on the stack: we allow + * only the super-user to do it. This depends on the stack-layout + * on system-call entry - see also fork() and the signal handling + * code. + */ +asmlinkage int sys_iopl(long ebx,long ecx,long edx, + long esi, long edi, long ebp, long eax, long ds, + long es, long fs, long gs, long orig_eax, + long eip,long cs,long eflags,long esp,long ss) +{ + return -ENOSYS; +} + +/* + * The workhorse function: find where to put a new entry + */ +static resource_entry_t *find_gap(resource_entry_t *root, + u_long from, u_long num) +{ + unsigned long flags; + resource_entry_t *p; + + if (from > from+num-1) + return NULL; + save_flags(flags); + cli(); + for (p = root; ; p = p->next) { + if ((p != root) && (p->from+p->num-1 >= from)) { + p = NULL; + break; + } + if ((p->next == NULL) || (p->next->from > from+num-1)) + break; + } + restore_flags(flags); + return p; +} diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c --- v1.1.81/linux/arch/mips/kernel/irq.c Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/irq.c Fri Jan 13 19:32:02 1995 @@ -0,0 +1,315 @@ +/* + * linux/kernel/irq.c + * + * Copyright (C) 1992 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. + */ + +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +unsigned char cache_21 = 0xff; +unsigned char cache_A1 = 0xff; + +unsigned long spurious_count = 0; + +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); +} + +/* + * Pointers to the low-level handlers: first the general ones, then the + * fast ones, then the bad ones. + */ +extern void interrupt(void); +extern void fast_interrupt(void); +extern void bad_interrupt(void); + +/* + * Initial irq handlers. + */ +static struct sigaction irq_sigaction[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 sigaction * sa = irq_sigaction; + + for (i = 0 ; i < 16 ; i++, sa++) { + if (!sa->sa_handler) + continue; + len += sprintf(buf+len, "%2d: %8d %c %s\n", + i, kstat.interrupts[i], + (sa->sa_flags & SA_INTERRUPT) ? '+' : ' ', + (char *) sa->sa_mask); + } + return len; +} + +/* + * 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 sigaction * sa = irq + irq_sigaction; + + kstat.interrupts[irq]++; + sa->sa_handler((int) regs); +} + +/* + * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return + * stuff - the handler is also running with interrupts disabled unless + * it explicitly enables them later. + */ +asmlinkage void do_fast_IRQ(int irq) +{ + struct sigaction * sa = irq + irq_sigaction; + + kstat.interrupts[irq]++; + sa->sa_handler(irq); +} + +#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) +{ + struct sigaction * sa; + unsigned long flags; + + if (irq > 15) + return -EINVAL; + sa = irq + irq_sigaction; + if (sa->sa_handler) + return -EBUSY; + if (!new_sa->sa_handler) + return -EINVAL; + save_flags(flags); + cli(); + *sa = *new_sa; + /* + * FIXME: Does the SA_INTERRUPT flag make any sense on the MIPS??? + */ + if (!(sa->sa_flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */ + if (sa->sa_flags & SA_INTERRUPT) + set_intr_gate(irq,fast_interrupt); + else + set_intr_gate(irq,interrupt); + } + if (irq < 8) { + cache_21 &= ~(1< 15) { + printk("Trying to free IRQ%d\n",irq); + return; + } + if (!sa->sa_handler) { + printk("Trying to free free IRQ%d\n",irq); + return; + } + save_flags(flags); + cli(); + if (irq < 8) { + cache_21 |= 1 << irq; + outb(cache_21,0x21); + } else { + cache_A1 |= 1 << (irq-8); + outb(cache_A1,0xA1); + } + set_intr_gate(irq,bad_interrupt); + sa->sa_handler = NULL; + sa->sa_flags = 0; + sa->sa_mask = 0; + sa->sa_restorer = NULL; + restore_flags(flags); +} + +#if 0 +/* + * handle fpu errors + */ +static void math_error_irq(int cpl) +{ + if (!hard_math) + return; + handle_fpe(); +} +#endif + +static void no_action(int cpl) { } + +unsigned int probe_irq_on (void) +{ + unsigned int i, irqs = 0, irqmask; + unsigned long delay; + + /* first, snaffle up any unassigned irqs */ + for (i = 15; i > 0; i--) { + if (!request_irq(i, no_action, SA_PROBE, "probe")) { + enable_irq(i); + irqs |= (1 << i); + } + } + + /* wait for spurious interrupts to mask themselves out again */ + for (delay = jiffies + 2; delay > jiffies; ); /* min 10ms delay */ + + /* now filter out any obviously spurious interrupts */ + irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21; + for (i = 15; i > 0; i--) { + if (irqs & (1 << i) & irqmask) { + irqs ^= (1 << i); + free_irq(i); + } + } +#ifdef DEBUG + printk("probe_irq_on: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask); +#endif + return irqs; +} + +int probe_irq_off (unsigned int irqs) +{ + unsigned int i, irqmask; + + irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21; + for (i = 15; i > 0; i--) { + if (irqs & (1 << i)) { + free_irq(i); + } + } +#ifdef DEBUG + printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask); +#endif + irqs &= irqmask; + if (!irqs) + return 0; + i = ffz(~irqs); + if (irqs != (irqs & (1 << i))) + i = -i; + return i; +} + +void init_IRQ(void) +{ + int i; + + for (i = 0; i < 16 ; i++) + set_intr_gate(i, bad_interrupt); + if (request_irq(2, no_action, SA_INTERRUPT, "cascade")) + printk("Unable to get IRQ2 for cascade\n"); + + /* initialize the bottom half routines. */ + for (i = 0; i < 32; i++) { + bh_base[i].routine = NULL; + bh_base[i].data = NULL; + } + bh_active = 0; + intr_count = 0; +} diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c --- v1.1.81/linux/arch/mips/kernel/process.c Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/process.c Sun Jan 15 23:38:27 1995 @@ -0,0 +1,193 @@ +/* + * linux/arch/mips/kernel/process.c + * + * Copyright (C) 1995 Waldorf Electronics, + * written by Ralf Baechle + */ + +/* + * This file handles the architecture-dependent parts of process handling.. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Tell us the machine setup.. + */ +#pragma char wp_works_ok = 0; /* set if paging hardware honours WP */ +char wait_available; /* set if the "wait" instruction available */ + +/* + * Bus types .. + */ +int EISA_bus = 0; + +asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call"); + +/* + * The idle loop on a MIPS.. + */ +asmlinkage int sys_idle(void) +{ +#if 0 + int i; +#endif + + if (current->pid != 0) + return -EPERM; + +#if 0 + /* Map out the low memory: it's no longer needed */ + for (i = 0 ; i < 512 ; i++) + swapper_pg_dir[i] = 0; +#endif + + /* endless idle loop with no priority at all */ + current->counter = -100; + for (;;) { + /* + * R4[26]00 have wait, R4[04]00 don't. + */ + if (wait_available && !need_resched) + __asm__("wait"); + schedule(); + } +} + +/* + * Do necessary setup to start up a newly executed thread. + */ +void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp) +{ + regs->cp0_epc = eip; + regs->reg29 = esp; +} + +/* + * Free current thread data structures etc.. + */ +void exit_thread(void) +{ + /* + * Nothing to do + */ +} + +void flush_thread(void) +{ + /* + * Nothing to do + */ +} + +#define IS_CLONE (regs->orig_reg2 == __NR_clone) + +unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct * p, struct pt_regs * regs) +{ + struct pt_regs * childregs; + + /* + * set up new TSS + */ + p->tss.fs = KERNEL_DS; + p->tss.ksp = (p->kernel_stack_page + PAGE_SIZE - 4) | KSEG0; + childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1; + p->tss.reg29 = ((unsigned long) childregs) | KSEG0; /* new sp */ + p->tss.reg31 = (unsigned long) ret_from_sys_call; + *childregs = *regs; + childregs->reg2 = 0; + + /* + * New tasks loose permission to use the fpu. This accelerates context + * switching for non fp programms, which true for the most programms. + */ + p->tss.cp0_status = regs->cp0_status & + ~(ST0_CU1|ST0_CU0|ST0_KSU|ST0_ERL|ST0_EXL); + childregs->cp0_status &= ~(ST0_CU1|ST0_CU0); + + if (IS_CLONE) { + if (regs->reg4) + childregs->reg29 = regs->reg4; + clone_flags = regs->reg5; + if (childregs->reg29 == regs->reg29) + clone_flags |= COPYVM; + } + + return clone_flags; +} + +/* + * fill in the user structure for a core dump.. + */ +void dump_thread(struct pt_regs * regs, struct user * dump) +{ + /* + * Not ready yet + */ +#if 0 + int i; + +/* changed the size calculations - should hopefully work better. lbt */ + dump->magic = CMAGIC; + dump->start_code = 0; + dump->start_stack = regs->esp & ~(PAGE_SIZE - 1); + dump->u_tsize = ((unsigned long) current->mm->end_code) >> 12; + dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> 12; + dump->u_dsize -= dump->u_tsize; + dump->u_ssize = 0; + for (i = 0; i < 8; i++) + dump->u_debugreg[i] = current->debugreg[i]; + + if (dump->start_stack < TASK_SIZE) + dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> 12; + + dump->regs = *regs; + +/* Flag indicating the math stuff is valid. We don't support this for the + soft-float routines yet */ + if (hard_math) { + if ((dump->u_fpvalid = current->used_math) != 0) { + if (last_task_used_math == current) + __asm__("clts ; fnsave %0": :"m" (dump->i387)); + else + memcpy(&dump->i387,¤t->tss.i387.hard,sizeof(dump->i387)); + } + } else { + /* we should dump the emulator state here, but we need to + convert it into standard 387 format first.. */ + dump->u_fpvalid = 0; + } +#endif +} + +/* + * sys_execve() executes a new program. + */ +asmlinkage int sys_execve(struct pt_regs regs) +{ + int error; + char * filename; + + error = getname((char *) regs.reg4, &filename); + if (error) + return error; + error = do_execve(filename, (char **) regs.reg5, (char **) regs.reg6, ®s); + putname(filename); + return error; +} diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c --- v1.1.81/linux/arch/mips/kernel/ptrace.c Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/ptrace.c Sun Jan 15 20:56:32 1995 @@ -0,0 +1,523 @@ +/* ptrace.c */ +/* By Ross Biro 1/23/92 */ +/* edited by Linus Torvalds */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#if 0 +/* + * does not yet catch signals sent when the child dies. + * in exit.c or in signal.c. + */ + +/* determines which flags the user has access to. */ +/* 1 = access 0 = no access */ +#define FLAG_MASK 0x00044dd5 + +/* set's the trap flag. */ +#define TRAP_FLAG 0x100 + +/* + * this is the number to subtract from the top of the stack. To find + * the local frame. + */ +#define MAGICNUMBER 68 + +/* change a pid into a task struct. */ +static inline struct task_struct * get_task(int pid) +{ + int i; + + for (i = 1; i < NR_TASKS; i++) { + if (task[i] != NULL && (task[i]->pid == pid)) + return task[i]; + } + return NULL; +} + +/* + * this routine will get a word off of the processes privileged stack. + * the offset is how far from the base addr as stored in the TSS. + * this routine assumes that all the privileged stacks are in our + * data space. + */ +static inline int get_stack_long(struct task_struct *task, int offset) +{ + unsigned char *stack; + + stack = (unsigned char *)task->tss.esp0; + stack += offset; + return (*((int *)stack)); +} + +/* + * this routine will put a word on the processes privileged stack. + * the offset is how far from the base addr as stored in the TSS. + * this routine assumes that all the privileged stacks are in our + * data space. + */ +static inline int put_stack_long(struct task_struct *task, int offset, + unsigned long data) +{ + unsigned char * stack; + + stack = (unsigned char *) task->tss.esp0; + stack += offset; + *(unsigned long *) stack = data; + return 0; +} + +/* + * This routine gets a long from any process space by following the page + * tables. NOTE! You should check that the long isn't on a page boundary, + * and that it is in the task area before calling this: this routine does + * no checking. + */ +static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr) +{ + unsigned long page; + +repeat: + page = *PAGE_DIR_OFFSET(vma->vm_task, addr); + if (page & PAGE_PRESENT) { + page &= PAGE_MASK; + page += PAGE_PTR(addr); + page = *((unsigned long *) page); + } + if (!(page & PAGE_PRESENT)) { + do_no_page(vma, addr, 0); + goto repeat; + } +/* this is a hack for non-kernel-mapped video buffers and similar */ + if (page >= high_memory) + return 0; + page &= PAGE_MASK; + page += addr & ~PAGE_MASK; + return *(unsigned long *) page; +} + +/* + * This routine puts a long into any process space by following the page + * tables. NOTE! You should check that the long isn't on a page boundary, + * and that it is in the task area before calling this: this routine does + * no checking. + * + * Now keeps R/W state of page so that a text page stays readonly + * even if a debugger scribbles breakpoints into it. -M.U- + */ +static void put_long(struct vm_area_struct * vma, unsigned long addr, + unsigned long data) +{ + unsigned long page, pte = 0; + int readonly = 0; + +repeat: + page = *PAGE_DIR_OFFSET(vma->vm_task, addr); + if (page & PAGE_PRESENT) { + page &= PAGE_MASK; + page += PAGE_PTR(addr); + pte = page; + page = *((unsigned long *) page); + } + if (!(page & PAGE_PRESENT)) { + do_no_page(vma, addr, 0 /* PAGE_RW */); + goto repeat; + } + if (!(page & PAGE_RW)) { + if (!(page & PAGE_COW)) + readonly = 1; + do_wp_page(vma, addr, PAGE_RW | PAGE_PRESENT); + goto repeat; + } +/* this is a hack for non-kernel-mapped video buffers and similar */ + if (page >= high_memory) + return; +/* we're bypassing pagetables, so we have to set the dirty bit ourselves */ + *(unsigned long *) pte |= (PAGE_DIRTY|PAGE_COW); + page &= PAGE_MASK; + page += addr & ~PAGE_MASK; + *(unsigned long *) page = data; + if (readonly) { + *(unsigned long *) pte &=~ (PAGE_RW|PAGE_COW); + invalidate(); + } +} + +static struct vm_area_struct * find_vma(struct task_struct * tsk, unsigned long addr) +{ + struct vm_area_struct * vma; + + addr &= PAGE_MASK; + for (vma = tsk->mm->mmap ; ; vma = vma->vm_next) { + if (!vma) + return NULL; + if (vma->vm_end > addr) + break; + } + if (vma->vm_start <= addr) + return vma; + if (!(vma->vm_flags & VM_GROWSDOWN)) + return NULL; + if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur) + return NULL; + vma->vm_offset -= vma->vm_start - addr; + vma->vm_start = addr; + return vma; +} + +/* + * This routine checks the page boundaries, and that the offset is + * within the task area. It then calls get_long() to read a long. + */ +static int read_long(struct task_struct * tsk, unsigned long addr, + unsigned long * result) +{ + struct vm_area_struct * vma = find_vma(tsk, addr); + + if (!vma) + return -EIO; + if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) { + unsigned long low,high; + struct vm_area_struct * vma_high = vma; + + if (addr + sizeof(long) >= vma->vm_end) { + vma_high = vma->vm_next; + if (!vma_high || vma_high->vm_start != vma->vm_end) + return -EIO; + } + low = get_long(vma, addr & ~(sizeof(long)-1)); + high = get_long(vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1)); + switch (addr & (sizeof(long)-1)) { + case 1: + low >>= 8; + low |= high << 24; + break; + case 2: + low >>= 16; + low |= high << 16; + break; + case 3: + low >>= 24; + low |= high << 8; + break; + } + *result = low; + } else + *result = get_long(vma, addr); + return 0; +} + +/* + * This routine checks the page boundaries, and that the offset is + * within the task area. It then calls put_long() to write a long. + */ +static int write_long(struct task_struct * tsk, unsigned long addr, + unsigned long data) +{ + struct vm_area_struct * vma = find_vma(tsk, addr); + + if (!vma) + return -EIO; + if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) { + unsigned long low,high; + struct vm_area_struct * vma_high = vma; + + if (addr + sizeof(long) >= vma->vm_end) { + vma_high = vma->vm_next; + if (!vma_high || vma_high->vm_start != vma->vm_end) + return -EIO; + } + low = get_long(vma, addr & ~(sizeof(long)-1)); + high = get_long(vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1)); + switch (addr & (sizeof(long)-1)) { + case 0: /* shouldn't happen, but safety first */ + low = data; + break; + case 1: + low &= 0x000000ff; + low |= data << 8; + high &= ~0xff; + high |= data >> 24; + break; + case 2: + low &= 0x0000ffff; + low |= data << 16; + high &= ~0xffff; + high |= data >> 16; + break; + case 3: + low &= 0x00ffffff; + low |= data << 24; + high &= ~0xffffff; + high |= data >> 8; + break; + } + put_long(vma, addr & ~(sizeof(long)-1),low); + put_long(vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1),high); + } else + put_long(vma, addr, data); + return 0; +} +#endif + +asmlinkage int sys_ptrace(long request, long pid, long addr, long data) +{ +#if 1 + return -ENOSYS; +#else + struct task_struct *child; + struct user * dummy; + int i; + + + dummy = NULL; + + if (request == PTRACE_TRACEME) { + /* are we already being traced? */ + if (current->flags & PF_PTRACED) + return -EPERM; + /* set the ptrace bit in the process flags. */ + current->flags |= PF_PTRACED; + return 0; + } + if (pid == 1) /* you may not mess with init */ + return -EPERM; + if (!(child = get_task(pid))) + return -ESRCH; + if (request == PTRACE_ATTACH) { + if (child == current) + return -EPERM; + if ((!child->dumpable || + (current->uid != child->euid) || + (current->uid != child->uid) || + (current->gid != child->egid) || + (current->gid != child->gid)) && !suser()) + return -EPERM; + /* the same process cannot be attached many times */ + if (child->flags & PF_PTRACED) + return -EPERM; + child->flags |= PF_PTRACED; + if (child->p_pptr != current) { + REMOVE_LINKS(child); + child->p_pptr = current; + SET_LINKS(child); + } + send_sig(SIGSTOP, child, 1); + return 0; + } + if (!(child->flags & PF_PTRACED)) + return -ESRCH; + if (child->state != TASK_STOPPED) { + if (request != PTRACE_KILL) + return -ESRCH; + } + if (child->p_pptr != current) + return -ESRCH; + + switch (request) { + /* when I and D space are separate, these will need to be fixed. */ + case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKDATA: { + unsigned long tmp; + int res; + + res = read_long(child, addr, &tmp); + if (res < 0) + return res; + res = verify_area(VERIFY_WRITE, (void *) data, sizeof(long)); + if (!res) + put_fs_long(tmp,(unsigned long *) data); + return res; + } + + /* read the word at location addr in the USER area. */ + case PTRACE_PEEKUSR: { + unsigned long tmp; + int res; + + if ((addr & 3) || addr < 0 || + addr > sizeof(struct user) - 3) + return -EIO; + + res = verify_area(VERIFY_WRITE, (void *) data, sizeof(long)); + if (res) + return res; + tmp = 0; /* Default return condition */ + if(addr < 17*sizeof(long)) { + addr = addr >> 2; /* temporary hack. */ + + tmp = get_stack_long(child, sizeof(long)*addr - MAGICNUMBER); + if (addr == DS || addr == ES || + addr == FS || addr == GS || + addr == CS || addr == SS) + tmp &= 0xffff; + }; + if(addr >= (long) &dummy->u_debugreg[0] && + addr <= (long) &dummy->u_debugreg[7]){ + addr -= (long) &dummy->u_debugreg[0]; + addr = addr >> 2; + tmp = child->debugreg[addr]; + }; + put_fs_long(tmp,(unsigned long *) data); + return 0; + } + + /* when I and D space are separate, this will have to be fixed. */ + case PTRACE_POKETEXT: /* write the word at location addr. */ + case PTRACE_POKEDATA: + return write_long(child,addr,data); + + case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ + if ((addr & 3) || addr < 0 || + addr > sizeof(struct user) - 3) + return -EIO; + + addr = addr >> 2; /* temporary hack. */ + + if (addr == ORIG_EAX) + return -EIO; + if (addr == DS || addr == ES || + addr == FS || addr == GS || + addr == CS || addr == SS) { + data &= 0xffff; + if (data && (data & 3) != 3) + return -EIO; + } + if (addr == EFL) { /* flags. */ + data &= FLAG_MASK; + data |= get_stack_long(child, EFL*sizeof(long)-MAGICNUMBER) & ~FLAG_MASK; + } + /* Do not allow the user to set the debug register for kernel + address space */ + if(addr < 17){ + if (put_stack_long(child, sizeof(long)*addr-MAGICNUMBER, data)) + return -EIO; + return 0; + }; + + /* We need to be very careful here. We implicitly + want to modify a portion of the task_struct, and we + have to be selective about what portions we allow someone + to modify. */ + + addr = addr << 2; /* Convert back again */ + if(addr >= (long) &dummy->u_debugreg[0] && + addr <= (long) &dummy->u_debugreg[7]){ + + if(addr == (long) &dummy->u_debugreg[4]) return -EIO; + if(addr == (long) &dummy->u_debugreg[5]) return -EIO; + if(addr < (long) &dummy->u_debugreg[4] && + ((unsigned long) data) >= 0xbffffffd) return -EIO; + + if(addr == (long) &dummy->u_debugreg[7]) { + data &= ~DR_CONTROL_RESERVED; + for(i=0; i<4; i++) + if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1) + return -EIO; + }; + + addr -= (long) &dummy->u_debugreg; + addr = addr >> 2; + child->debugreg[addr] = data; + return 0; + }; + return -EIO; + + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ + case PTRACE_CONT: { /* restart after signal. */ + long tmp; + + if ((unsigned long) data > NSIG) + return -EIO; + if (request == PTRACE_SYSCALL) + child->flags |= PF_TRACESYS; + else + child->flags &= ~PF_TRACESYS; + child->exit_code = data; + child->state = TASK_RUNNING; + /* make sure the single step bit is not set. */ + tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; + put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); + return 0; + } + +/* + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to + * exit. + */ + case PTRACE_KILL: { + long tmp; + + child->state = TASK_RUNNING; + child->exit_code = SIGKILL; + /* make sure the single step bit is not set. */ + tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; + put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); + return 0; + } + + case PTRACE_SINGLESTEP: { /* set the trap flag. */ + long tmp; + + if ((unsigned long) data > NSIG) + return -EIO; + child->flags &= ~PF_TRACESYS; + tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) | TRAP_FLAG; + put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); + child->state = TASK_RUNNING; + child->exit_code = data; + /* give it a chance to run. */ + return 0; + } + + case PTRACE_DETACH: { /* detach a process that was attached. */ + long tmp; + + if ((unsigned long) data > NSIG) + return -EIO; + child->flags &= ~(PF_PTRACED|PF_TRACESYS); + child->state = TASK_RUNNING; + child->exit_code = data; + REMOVE_LINKS(child); + child->p_pptr = child->p_opptr; + SET_LINKS(child); + /* make sure the single step bit is not set. */ + tmp = get_stack_long(child, sizeof(long)*EFL-MAGICNUMBER) & ~TRAP_FLAG; + put_stack_long(child, sizeof(long)*EFL-MAGICNUMBER,tmp); + return 0; + } + + default: + return -EIO; + } +#endif +} + +asmlinkage void syscall_trace(void) +{ + if ((current->flags & (PF_PTRACED|PF_TRACESYS)) + != (PF_PTRACED|PF_TRACESYS)) + return; + current->exit_code = SIGTRAP; + current->state = TASK_STOPPED; + notify_parent(current); + schedule(); + /* + * this isn't the same as continuing with a signal, but it will do + * for normal use. strace only continues with a signal if the + * stopping signal is not SIGTRAP. -brl + */ + if (current->exit_code) + current->signal |= (1 << (current->exit_code - 1)); + current->exit_code = 0; +} diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/resume.S linux/arch/mips/kernel/resume.S --- v1.1.81/linux/arch/mips/kernel/resume.S Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/resume.S Fri Jan 13 19:25:56 1995 @@ -0,0 +1,261 @@ +/* + * linux/kernel/mips/sys_call.S + * + * Copyright (C) 1994, 1995 Waldorf Electronics + * written by Ralf Baechle + */ + +/* + * sys_call.S contains the system-call and fault low-level handling routines. + * This also contains the timer-interrupt handler, as well as all interrupts + * and faults that can result in a task-switch. + */ + +#include +#include +#include +#include + +/* + * These are offsets into the task-struct. + */ +state = 0 +counter = 4 +priority = 8 +signal = 12 +blocked = 16 +flags = 20 +errno = 24 #/* MIPS OK */ +exec_domain = 60 #/* ??? */ + +ENOSYS = 38 + +/* + * Code necessary to switch tasks on an Linux/MIPS machine. + */ +MODE_ALIAS = 0x0016 # uncachable + + .text + .set noreorder + .set at + + .globl _resume +_resume: + /* + * current task's task_struct + */ + lui t5,%hi(_current) + lw t0,%lo(_current)(t5) + + /* + * Save status register + */ + mfc0 t1,CP0_STATUS + addu t0,a1 # Add tss offset + sw t1,TOFF_CP0_STATUS(t0) + + /* + * Disable interrupts + */ + ori t2,t1,0x1f + xori t2,0x1e + + /* + * Save fs (may be pointing to kernel memory) + */ + lui t4,%hi(_segment_fs) + lw t3,%lo(_segment_fs)(t4) + mtc0 t2,CP0_STATUS + sw t3,TOFF_FS(t0) + + /* + * Save non-scratch registers + * All other registers have been saved on the kernel stack + */ + sw s0,TOFF_REG16(t0) + sw s1,TOFF_REG17(t0) + sw s2,TOFF_REG18(t0) + sw s3,TOFF_REG19(t0) + sw s4,TOFF_REG20(t0) + sw s5,TOFF_REG21(t0) + sw s6,TOFF_REG22(t0) + sw s7,TOFF_REG23(t0) + sw gp,TOFF_REG28(t0) + sw sp,TOFF_REG29(t0) + sw fp,TOFF_REG30(t0) + sw ra,TOFF_REG31(t0) + + /* + * Save floating point state + */ + srl t2,t1,29 + andi t2,1 + beqz t2,2f + srl t2,t1,26 + andi t2,1 + beqz t2,1f + sdc1 $f0,(TOFF_FPU+0)(t0) # delay slot + /* + * Store the 16 odd double precision registers + */ + sdc1 $f1,(TOFF_FPU+8)(t0) + sdc1 $f3,(TOFF_FPU+24)(t0) + sdc1 $f5,(TOFF_FPU+40)(t0) + sdc1 $f7,(TOFF_FPU+56)(t0) + sdc1 $f9,(TOFF_FPU+72)(t0) + sdc1 $f11,(TOFF_FPU+88)(t0) + sdc1 $f13,(TOFF_FPU+104)(t0) + sdc1 $f15,(TOFF_FPU+120)(t0) + sdc1 $f17,(TOFF_FPU+136)(t0) + sdc1 $f19,(TOFF_FPU+152)(t0) + sdc1 $f21,(TOFF_FPU+168)(t0) + sdc1 $f23,(TOFF_FPU+184)(t0) + sdc1 $f25,(TOFF_FPU+200)(t0) + sdc1 $f27,(TOFF_FPU+216)(t0) + sdc1 $f29,(TOFF_FPU+232)(t0) + sdc1 $f31,(TOFF_FPU+248)(t0) + + /* + * Store the 16 even double precision registers + */ +1: cfc1 t1,$31 + sdc1 $f2,(TOFF_FPU+16)(t0) + sdc1 $f4,(TOFF_FPU+32)(t0) + sdc1 $f6,(TOFF_FPU+48)(t0) + sdc1 $f8,(TOFF_FPU+64)(t0) + sdc1 $f10,(TOFF_FPU+80)(t0) + sdc1 $f12,(TOFF_FPU+96)(t0) + sdc1 $f14,(TOFF_FPU+112)(t0) + sdc1 $f16,(TOFF_FPU+128)(t0) + sdc1 $f18,(TOFF_FPU+144)(t0) + sdc1 $f20,(TOFF_FPU+160)(t0) + sdc1 $f22,(TOFF_FPU+176)(t0) + sdc1 $f24,(TOFF_FPU+192)(t0) + sdc1 $f26,(TOFF_FPU+208)(t0) + sdc1 $f28,(TOFF_FPU+224)(t0) + sdc1 $f30,(TOFF_FPU+240)(t0) + sw t1,(TOFF_FPU+256)(t0) + + /* + * Switch current task + */ +2: sw a0,%lo(_current)(t5) + addu a0,a1 # Add tss offset + + /* + * Switch address space + */ + + /* + * (Choose new ASID for process) + */ + + /* + * Switch the root pointer + */ + lw t0,TOFF_PG_DIR(a0) + la t1,TLB_ROOT + mtc0 t1,CP0_ENTRYHI + mtc0 zero,CP0_INDEX + srl t0,6 + ori t0,MODE_ALIAS + mtc0 t0,CP0_ENTRYLO0 + mtc0 zero,CP0_ENTRYLO1 + tlbwi + + /* + * Flush tlb (probably not needed) + * (Doesn't clobber a0-a3) + */ + jal _tlbflush + nop # delay slot + + lw a2,TOFF_CP0_STATUS(a0) + + /* + * Restore fpu state: + * - cp0 status register bits + * - fp gp registers + * - cp1 status/control register + */ + ori t1,a2,1 # pipeline magic + xori t1,1 + mtc0 t1,CP0_STATUS + srl t0,a2,29 + andi t0,1 + beqz t0,2f + srl t0,a2,26 + andi t0,1 + beqz t0,1f + ldc1 $f0,(TOFF_FPU+0)(a0) # delay slot + /* + * Restore the 16 odd double precision registers only + * when enabled in the cp0 status register. + */ + ldc1 $f1,(TOFF_FPU+8)(a0) + ldc1 $f3,(TOFF_FPU+24)(a0) + ldc1 $f5,(TOFF_FPU+40)(a0) + ldc1 $f7,(TOFF_FPU+56)(a0) + ldc1 $f9,(TOFF_FPU+72)(a0) + ldc1 $f11,(TOFF_FPU+88)(a0) + ldc1 $f13,(TOFF_FPU+104)(a0) + ldc1 $f15,(TOFF_FPU+120)(a0) + ldc1 $f17,(TOFF_FPU+136)(a0) + ldc1 $f19,(TOFF_FPU+152)(a0) + ldc1 $f21,(TOFF_FPU+168)(a0) + ldc1 $f23,(TOFF_FPU+184)(a0) + ldc1 $f25,(TOFF_FPU+200)(a0) + ldc1 $f27,(TOFF_FPU+216)(a0) + ldc1 $f29,(TOFF_FPU+232)(a0) + ldc1 $f31,(TOFF_FPU+248)(a0) + + /* + * Restore the 16 even double precision registers always + * when cp1 was enabled in the cp0 status register. + */ +1: lw t0,(TOFF_FPU+256)(a0) + ldc1 $f2,(TOFF_FPU+16)(a0) + ldc1 $f4,(TOFF_FPU+32)(a0) + ldc1 $f6,(TOFF_FPU+48)(a0) + ldc1 $f8,(TOFF_FPU+64)(a0) + ldc1 $f10,(TOFF_FPU+80)(a0) + ldc1 $f12,(TOFF_FPU+96)(a0) + ldc1 $f14,(TOFF_FPU+112)(a0) + ldc1 $f16,(TOFF_FPU+128)(a0) + ldc1 $f18,(TOFF_FPU+144)(a0) + ldc1 $f20,(TOFF_FPU+160)(a0) + ldc1 $f22,(TOFF_FPU+176)(a0) + ldc1 $f24,(TOFF_FPU+192)(a0) + ldc1 $f26,(TOFF_FPU+208)(a0) + ldc1 $f28,(TOFF_FPU+224)(a0) + ldc1 $f30,(TOFF_FPU+240)(a0) + ctc1 t0,$31 + + /* + * Restore non-scratch registers + */ +2: lw s0,TOFF_REG16(a0) + lw s1,TOFF_REG17(a0) + lw s2,TOFF_REG18(a0) + lw s3,TOFF_REG19(a0) + lw s4,TOFF_REG20(a0) + lw s5,TOFF_REG21(a0) + lw s6,TOFF_REG22(a0) + lw s7,TOFF_REG23(a0) + lw gp,TOFF_REG28(a0) + lw sp,TOFF_REG29(a0) + lw fp,TOFF_REG30(a0) + lw ra,TOFF_REG31(a0) + + /* + * Restore fs segment pointer + * Restore status register + */ + lw t0,TOFF_FS(a0) + lw t1,TOFF_KSP(a0) + sw t0,%lo(_segment_fs)(t4) + sw t1,_kernelsp + + jr ra + mtc0 a2,CP0_STATUS # delay slot + diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/signal.c linux/arch/mips/kernel/signal.c --- v1.1.81/linux/arch/mips/kernel/signal.c Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/signal.c Fri Jan 13 20:30:57 1995 @@ -0,0 +1,311 @@ +/* + * linux/arch/mips/kernel/signal.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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; + + mask = current->blocked; + current->blocked = set & _BLOCKABLE; + regs->reg2 = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(mask,regs)) + return -EINTR; + } +} + +/* + * This sets regs->reg29 even though we don't actually use sigstacks yet.. + */ +asmlinkage int sys_sigreturn(unsigned long __unused) +{ + struct sigcontext_struct context; + struct pt_regs * regs; + + regs = (struct pt_regs *) &__unused; + if (verify_area(VERIFY_READ, (void *) regs->reg29, sizeof(context))) + goto badframe; + memcpy_fromfs(&context,(void *) regs->reg29, sizeof(context)); + current->blocked = context.oldmask & _BLOCKABLE; + regs->reg1 = context.sc_at; + regs->reg2 = context.sc_v0; + regs->reg3 = context.sc_v1; + regs->reg4 = context.sc_a0; + regs->reg5 = context.sc_a1; + regs->reg6 = context.sc_a2; + regs->reg7 = context.sc_a3; + regs->reg8 = context.sc_t0; + regs->reg9 = context.sc_t1; + regs->reg10 = context.sc_t2; + regs->reg11 = context.sc_t3; + regs->reg12 = context.sc_t4; + regs->reg13 = context.sc_t5; + regs->reg14 = context.sc_t6; + regs->reg15 = context.sc_t7; + regs->reg16 = context.sc_s0; + regs->reg17 = context.sc_s1; + regs->reg18 = context.sc_s2; + regs->reg19 = context.sc_s3; + regs->reg20 = context.sc_s4; + regs->reg21 = context.sc_s5; + regs->reg22 = context.sc_s6; + regs->reg23 = context.sc_s7; + regs->reg24 = context.sc_t8; + regs->reg25 = context.sc_t9; + /* + * Skip k0/k1 + */ + regs->reg28 = context.sc_gp; + regs->reg29 = context.sc_sp; + regs->reg30 = context.sc_fp; + regs->reg31 = context.sc_ra; + regs->cp0_epc = context.sc_epc; + regs->cp0_cause = context.sc_cause; + + /* + * disable syscall checks + */ + regs->orig_reg2 = -1; + return regs->orig_reg2; +badframe: + do_exit(SIGSEGV); +} + +/* + * Set up a signal frame... + */ +static void setup_frame(struct sigaction * sa, unsigned long ** fp, + unsigned long pc, struct pt_regs *regs, + int signr, unsigned long oldmask) +{ + unsigned long * frame; + + frame = *fp; + frame -= 32; + if (verify_area(VERIFY_WRITE,frame,21*4)) + do_exit(SIGSEGV); + /* + * set up the "normal" stack seen by the signal handler + */ + put_fs_long(regs->reg1 , frame ); + put_fs_long(regs->reg2 , frame+ 1); + put_fs_long(regs->reg3 , frame+ 2); + put_fs_long(regs->reg4 , frame+ 3); + put_fs_long(regs->reg5 , frame+ 4); + put_fs_long(regs->reg6 , frame+ 5); + put_fs_long(regs->reg7 , frame+ 6); + put_fs_long(regs->reg8 , frame+ 7); + put_fs_long(regs->reg9 , frame+ 8); + put_fs_long(regs->reg10, frame+ 9); + put_fs_long(regs->reg11, frame+10); + put_fs_long(regs->reg12, frame+11); + put_fs_long(regs->reg13, frame+12); + put_fs_long(regs->reg14, frame+13); + put_fs_long(regs->reg15, frame+14); + put_fs_long(regs->reg16, frame+15); + put_fs_long(regs->reg17, frame+16); + put_fs_long(regs->reg18, frame+17); + put_fs_long(regs->reg19, frame+18); + put_fs_long(regs->reg20, frame+19); + put_fs_long(regs->reg21, frame+20); + put_fs_long(regs->reg22, frame+21); + put_fs_long(regs->reg23, frame+22); + put_fs_long(regs->reg24, frame+23); + put_fs_long(regs->reg25, frame+24); + /* + * Don't copy k0/k1 + */ + put_fs_long(regs->reg28, frame+25); + put_fs_long(regs->reg29, frame+26); + put_fs_long(regs->reg30, frame+27); + put_fs_long(regs->reg31, frame+28); + put_fs_long(pc , frame+29); + put_fs_long(oldmask , frame+30); + /* + * set up the return code... + * + * .set noreorder + * .set noat + * syscall + * li $1,__NR_sigreturn + * .set at + * .set reorder + */ + put_fs_long(0x24010077, frame+31); /* li $1,119 */ + put_fs_long(0x000000c0, frame+32); /* syscall */ + *fp = frame; + /* + * Flush caches so the instructions will be correctly executed. + */ + sys_cacheflush(frame, 32*4, BCACHE); +} + +/* + * 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. + */ +asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs) +{ + unsigned long mask = ~current->blocked; + unsigned long handler_signal = 0; + unsigned long *frame = NULL; + unsigned long pc = 0; + unsigned long signr; + struct sigaction * sa; + + while ((signr = current->signal & mask)) { + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "li\t%0,31\n" + "1:\tsllv\t$1,%1,%0\n\t" + "bgezl\t$1,1b\n\t" + "subu\t$8,1\n\t" + "subu\t%0,31\n\t" + "subu\t%0,$0,%0\n\t" + "li\t$1,1\n\t" + "sllv\t$1,$1,%0\n\t" + "nor\t$1,$0\n\t" + "xor\t%1,$1\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (signr),"=r" (current->signal) + :"0" (signr),"1" (current->signal) + :"$1"); + sa = current->sigaction + signr; + signr++; + if ((current->flags & PF_PTRACED) && signr != SIGKILL) { + current->exit_code = signr; + current->state = TASK_STOPPED; + notify_parent(current); + schedule(); + if (!(signr = current->exit_code)) + continue; + current->exit_code = 0; + if (signr == SIGSTOP) + continue; + if (_S(signr) & current->blocked) { + current->signal |= _S(signr); + continue; + } + sa = current->sigaction + signr - 1; + } + if (sa->sa_handler == SIG_IGN) { + if (signr != SIGCHLD) + continue; + /* check for SIGCHLD: it's special */ + while (sys_waitpid(-1,NULL,WNOHANG) > 0) + /* nothing */; + continue; + } + if (sa->sa_handler == SIG_DFL) { + if (current->pid == 1) + continue; + switch (signr) { + case SIGCONT: case SIGCHLD: case SIGWINCH: + continue; + + case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU: + if (current->flags & PF_PTRACED) + continue; + current->state = TASK_STOPPED; + current->exit_code = signr; + if (!(current->p_pptr->sigaction[SIGCHLD-1].sa_flags & + SA_NOCLDSTOP)) + notify_parent(current); + schedule(); + continue; + + case SIGQUIT: case SIGILL: case SIGTRAP: + case SIGIOT: case SIGFPE: case SIGSEGV: + if (current->binfmt && current->binfmt->core_dump) { + if (current->binfmt->core_dump(signr, regs)) + signr |= 0x80; + } + /* fall through */ + default: + current->signal |= _S(signr & 0x7f); + do_exit(signr); + } + } + /* + * OK, we're invoking a handler + */ + if (regs->orig_reg2 >= 0) { + if (regs->reg2 == -ERESTARTNOHAND || + (regs->reg2 == -ERESTARTSYS && + !(sa->sa_flags & SA_RESTART))) + regs->reg2 = -EINTR; + } + handler_signal |= 1 << (signr-1); + mask &= ~sa->sa_mask; + } + if (regs->orig_reg2 >= 0 && + (regs->reg2 == -ERESTARTNOHAND || + regs->reg2 == -ERESTARTSYS || + regs->reg2 == -ERESTARTNOINTR)) { + regs->reg2 = regs->orig_reg2; + regs->cp0_epc -= 4; + } + if (!handler_signal) /* no handler will be called - return 0 */ + return 0; + pc = regs->cp0_epc; + frame = (unsigned long *) regs->reg29; + signr = 1; + sa = current->sigaction; + for (mask = 1 ; mask ; sa++,signr++,mask += mask) { + if (mask > handler_signal) + break; + if (!(mask & handler_signal)) + continue; + setup_frame(sa,&frame,pc,regs,signr,oldmask); + pc = (unsigned long) sa->sa_handler; + if (sa->sa_flags & SA_ONESHOT) + sa->sa_handler = NULL; + /* + * force a kernel-mode page-in of the signal + * handler to reduce races + */ + __asm__(".set\tnoat\n\t" + "lwu\t$1,(%0)\n\t" + ".set\tat\n\t" + : + :"r" ((char *) pc) + :"$1"); + current->blocked |= sa->sa_mask; + oldmask |= sa->sa_mask; + } + regs->reg29 = (unsigned long) frame; + regs->cp0_epc = pc; /* "return" to the first handler */ + return 1; +} diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/tlb.S linux/arch/mips/kernel/tlb.S --- v1.1.81/linux/arch/mips/kernel/tlb.S Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/tlb.S Fri Jan 13 23:49:20 1995 @@ -0,0 +1,35 @@ +/* + * 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 +#include +#include + + .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 diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/traps.c linux/arch/mips/kernel/traps.c --- v1.1.81/linux/arch/mips/kernel/traps.c Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/traps.c Sun Jan 15 21:04:53 1995 @@ -0,0 +1,378 @@ +/* + * arch/mips/kernel/traps.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* + * 'traps.c' handles hardware traps and faults after we have saved some + * state in 'asm.s'. Currently mostly a debugging-aid, will be extended + * to mainly kill the offending process (probably by giving it a signal, + * but possibly by killing it outright if necessary). + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static inline void console_verbose(void) +{ + extern int console_loglevel; + console_loglevel = 15; +} + +#define get_seg_byte(seg,addr) ({ \ +register unsigned char __res; \ +int unsigned long save; \ +save = segment_fs; \ +__res = get_user_byte(addr); \ +segment_fs = save; \ +__res;}) + +#define get_seg_long(seg,addr) ({ \ +register unsigned long __res; \ +int unsigned long save; \ +save = segment_fs; \ +__res = get_user_word(addr); \ +segment_fs = save; \ +__res;}) + +extern asmlinkage void handle_int(void); +extern asmlinkage void handle_mod(void); +extern asmlinkage void handle_tlbl(void); +extern asmlinkage void handle_tlbs(void); +extern asmlinkage void handle_adel(void); +extern asmlinkage void handle_ades(void); +extern asmlinkage void handle_ibe(void); +extern asmlinkage void handle_dbe(void); +extern asmlinkage void handle_sys(void); +extern asmlinkage void handle_bp(void); +extern asmlinkage void handle_ri(void); +extern asmlinkage void handle_cpu(void); +extern asmlinkage void handle_ov(void); +extern asmlinkage void handle_tr(void); +extern asmlinkage void handle_vcei(void); +extern asmlinkage void handle_fpe(void); +extern asmlinkage void handle_vced(void); +extern asmlinkage void handle_watch(void); +extern asmlinkage void handle_reserved(void); + +char *cpu_names[] = CPU_NAMES; + +int kstack_depth_to_print = 24; + +/* + * These constants are for searching for possible module text + * segments. VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is + * a guess of how much space is likely to be vmalloced. + */ +#define VMALLOC_OFFSET (8*1024*1024) +#define MODULE_RANGE (8*1024*1024) + +void die_if_kernel(char * str, struct pt_regs * regs, long err) +{ + int i; + unsigned long *sp, *pc; + unsigned long *stack, addr, module_start, module_end; + extern char start_kernel, etext; + + if (regs->cp0_status & (ST0_ERL|ST0_EXL) == 0) + return; + + sp = (unsigned long *)regs->reg29; + pc = (unsigned long *)regs->cp0_epc; + + console_verbose(); + printk("%s: %08lx\n", str, err ); + + /* + * Saved main processor registers + */ + printk("at : %08lx\n", regs->reg1); + printk("v0 : %08lx %08lx\n", regs->reg2, regs->reg3); + printk("a0 : %08lx %08lx %08lx %08lx\n", + regs->reg4, regs->reg5, regs->reg6, regs->reg7); + printk("t0 : %08lx %08lx %08lx %08lx %08lx\n", + regs->reg8, regs->reg9, regs->reg10, regs->reg11, regs->reg12); + printk("t5 : %08lx %08lx %08lx %08lx %08lx\n", + regs->reg13, regs->reg14, regs->reg15, regs->reg24, regs->reg25); + printk("s0 : %08lx %08lx %08lx %08lx\n", + regs->reg16, regs->reg17, regs->reg18, regs->reg19); + printk("s4 : %08lx %08lx %08lx %08lx\n", + regs->reg20, regs->reg21, regs->reg22, regs->reg23); + printk("gp : %08lx\n", regs->reg28); + printk("sp : %08lx\n", regs->reg29); + printk("fp/s8: %08lx\n", regs->reg30); + printk("ra : %08lx\n", regs->reg31); + + /* + * Saved cp0 registers + */ + printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n", + regs->cp0_epc, regs->cp0_status, regs->cp0_cause); + + /* + * Some goodies... + */ + printk("Int : %ld\n", regs->interrupt); + + /* + * Dump the stack + */ + if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page) + printk("Corrupted stack page\n"); + printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)\nStack: ", + current->comm, current->pid, 0xffff & i, + current->kernel_stack_page); + for(i=0;i<5;i++) + printk("%08lx ", *sp++); + stack = (unsigned long *) sp; + for(i=0; i < kstack_depth_to_print; i++) { + if (((long) stack & 4095) == 0) + break; + if (i && ((i % 8) == 0)) + printk("\n "); + printk("%08lx ", get_seg_long(ss,stack++)); + } + printk("\nCall Trace: "); + stack = (unsigned long *) sp; + i = 1; + module_start = ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)); + module_end = module_start + MODULE_RANGE; + while (((long) stack & 4095) != 0) { + addr = get_seg_long(ss, stack++); + /* + * If the address is either in the text segment of the + * kernel, or in the region which contains vmalloc'ed + * memory, it *may* be the address of a calling + * routine; if so, print it so that someone tracing + * down the cause of the crash will be able to figure + * out the call path that was taken. + */ + if (((addr >= (unsigned long) &start_kernel) && + (addr <= (unsigned long) &etext)) || + ((addr >= module_start) && (addr <= module_end))) { + if (i && ((i % 8) == 0)) + printk("\n "); + printk("%08lx ", addr); + i++; + } + } + + printk("\nCode : "); + for(i=0;i<5;i++) + printk("%08lx ", *pc++); + printk("\n"); + do_exit(SIGSEGV); +} + +void do_adel(struct pt_regs *regs) +{ + send_sig(SIGSEGV, current, 1); +} + +void do_ades(struct pt_regs *regs) +{ + send_sig(SIGSEGV, current, 1); +} + +void do_ibe(struct pt_regs *regs) +{ + send_sig(SIGSEGV, current, 1); +} + +void do_dbe(struct pt_regs *regs) +{ + send_sig(SIGSEGV, current, 1); +} + +void do_ov(struct pt_regs *regs) +{ + send_sig(SIGFPE, current, 1); +} + +void do_fpe(struct pt_regs *regs) +{ + /* + * FIXME: This is the place for a fpu emulator. Not written + * yet and the demand seems to be quite low. + */ + printk("Caught FPE exception at %lx.\n", regs->cp0_epc); + send_sig(SIGFPE, current, 1); +} + +void do_bp(struct pt_regs *regs) +{ + send_sig(SIGILL, current, 1); +} + +void do_tr(struct pt_regs *regs) +{ + send_sig(SIGILL, current, 1); +} + +void do_ri(struct pt_regs *regs) +{ + send_sig(SIGILL, current, 1); +} + +void do_cpu(struct pt_regs *regs) +{ + unsigned long pc; + unsigned int insn; + + /* + * Check whether this was a cp1 instruction + */ + pc = regs->cp0_epc; + if (regs->cp0_cause & (1<<31)) + pc += 4; + insn = *(unsigned int *)pc; + insn &= 0xfc000000; + switch(insn) { + case 0x44000000: + case 0xc4000000: + case 0xe4000000: + printk("CP1 instruction - enabeling cp1.\n"); + regs->cp0_status |= ST0_CU1; + /* + * No need to handle branch delay slots + */ + break; + default: + /* + * This wasn't a cp1 instruction and therfore illegal. + * Default is to kill the process. + */ + send_sig(SIGILL, current, 1); + } +} + +void do_vcei(struct pt_regs *regs) +{ + /* + * Only possible on R4[04]00[SM]C. No handler because + * I don't have such a cpu. + */ + panic("Caught VCEI exception - can't handle yet\n"); +} + +void do_vced(struct pt_regs *regs) +{ + /* + * Only possible on R4[04]00[SM]C. No handler because + * I don't have such a cpu. + */ + panic("Caught VCED exception - can't handle yet\n"); +} + +void do_watch(struct pt_regs *regs) +{ + /* + * Only possible on R4[04]00. No way to handle this because + * I don't have such a cpu. + */ + panic("Caught WATCH exception - can't handle yet\n"); +} + +void do_reserved(struct pt_regs *regs) +{ + /* + * Game over - no way to handle this if it ever occours. + * Most probably caused by a new unknown cpu type or a + * after another deadly hard/software error. + */ + panic("Caught reserved exception - can't handle.\n"); +} + +void trap_init(void) +{ + int i; + + /* + * FIXME: Mips Magnum R4000 has an EISA bus! + */ + EISA_bus = 0; + + /* + * Setup default vectors + */ + for (i=0;i<=31;i++) + set_except_vector(i, handle_reserved); + + /* + * Handling the following exceptions depends mostly of the cpu type + */ + switch(boot_info.cputype) { + case CPU_R4000MC: + case CPU_R4400MC: + case CPU_R4000SC: + case CPU_R4400SC: + /* + * Handlers not implemented yet + */ + set_except_vector(14, handle_vcei); + set_except_vector(31, handle_vced); + case CPU_R4000PC: + case CPU_R4400PC: + /* + * Handler not implemented yet + */ + set_except_vector(23, handle_watch); + case CPU_R4200: + case CPU_R4600: + set_except_vector(1, handle_mod); + set_except_vector(2, handle_tlbl); + set_except_vector(3, handle_tlbs); + set_except_vector(4, handle_adel); + set_except_vector(5, handle_ades); + set_except_vector(6, handle_ibe); + set_except_vector(7, handle_dbe); + set_except_vector(8, handle_sys); + set_except_vector(9, handle_bp); + set_except_vector(10, handle_ri); + set_except_vector(11, handle_cpu); + set_except_vector(12, handle_ov); + set_except_vector(13, handle_tr); + set_except_vector(15, handle_fpe); + break; + case CPU_R2000: + case CPU_R3000: + case CPU_R3000A: + case CPU_R3041: + case CPU_R3051: + case CPU_R3052: + case CPU_R3081: + case CPU_R3081E: + case CPU_R6000: + case CPU_R6000A: + case CPU_R8000: + case CPU_R10000: + printk("Detected unsupported CPU type %s.\n", + cpu_names[boot_info.cputype]); + panic("Can't handle CPU\n"); + break; + case CPU_UNKNOWN: + default: + panic("Unknown type of CPU"); + } + + /* + * The interrupt handler depends of both type of the board and cpu + */ + switch(boot_info.machtype) { + case MACH_DESKSTATION_TYNE: + set_except_vector(0, handle_int); + } +} diff -u --recursive --new-file v1.1.81/linux/arch/mips/kernel/vm86.c linux/arch/mips/kernel/vm86.c --- v1.1.81/linux/arch/mips/kernel/vm86.c Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/kernel/vm86.c Fri Jan 13 18:21:20 1995 @@ -0,0 +1,14 @@ +/* + * arch/mips/vm86.c + * + * Copyright (C) 1994 Waldorf GMBH, + * written by Ralf Baechle + */ +#include +#include +#include + +asmlinkage int sys_vm86(struct vm86_struct * v86) +{ + return -ENOSYS; +} diff -u --recursive --new-file v1.1.81/linux/arch/mips/mm/Makefile linux/arch/mips/mm/Makefile --- v1.1.81/linux/arch/mips/mm/Makefile Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/mm/Makefile Sun Jan 15 22:48:21 1995 @@ -0,0 +1,32 @@ +# +# 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 diff -u --recursive --new-file v1.1.81/linux/arch/mips/mm/fault.c linux/arch/mips/mm/fault.c --- v1.1.81/linux/arch/mips/mm/fault.c Thu Jan 1 02:00:00 1970 +++ linux/arch/mips/mm/fault.c Sun Jan 15 23:46:21 1995 @@ -0,0 +1,343 @@ +/* + * arch/mips/mm/memory.c + * + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * Ported to MIPS by Ralf Baechle + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +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); + +/* + * This routine handles page faults. It determines the address, + * and the problem, and then passes it off to one of the appropriate + * routines. + */ +asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) +{ + struct vm_area_struct * vma; + unsigned long address; + unsigned long page; + + /* get the address */ + __asm__("dmfc0\t%0,$8" + : "=r" (address)); + + 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 0 + if (regs->eflags & VM_MASK) { + unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT; + if (bit < 32) + current->tss.screen_bitmap |= 1 << bit; + } +#endif + if (!(vma->vm_page_prot & PAGE_USER)) + goto bad_area; + if (error_code & PAGE_PRESENT) { + if (!(vma->vm_page_prot & (PAGE_RW | PAGE_COW))) + goto bad_area; + do_wp_page(vma, address, error_code); + return; + } +printk("do_page_fault: do_no_page(%x, %x, %d)", vma, address, error_code); + do_no_page(vma, address, error_code); + 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: +printk("Bad Area...\n"); + if (error_code & PAGE_USER) { + current->tss.cp0_badvaddr = address; + current->tss.error_code = error_code; + current->tss.trap_no = 14; + 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("This processor honours the WP bit even when in supervisor mode. Good.\n"); + if ((unsigned long) (address-TASK_SIZE) < PAGE_SIZE) { + printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); + pg0[0] = PAGE_SHARED; + } else + printk(KERN_ALERT "Unable to handle kernel paging request"); + printk(" at virtual address %08lx\n",address); + page = current->tss.pg_dir; + printk(KERN_ALERT "current->tss.pg_dir = %08lx\n", page); + page = ((unsigned long *) page)[address >> 22]; + printk(KERN_ALERT "*pde = %08lx\n", page); + if (page & PAGE_PRESENT) { + page &= PAGE_MASK; + address &= 0x003ff000; + page = ((unsigned long *) page)[address >> PAGE_SHIFT]; + printk(KERN_ALERT "*pte = %08lx\n", page); + } + 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]; + unsigned long dummy; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + "1:\tsw\t%2,(%0)\n\t" + "subu\t%1,%1,1\n\t" + "bne\t$0,%1,1b\n\t" + "addiu\t%0,%0,1\n\t" + ".set\treorder" + :"=r" (dummy), + "=r" (dummy) + :"r" (BAD_PAGE + PAGE_TABLE), + "0" ((long) empty_bad_page_table), + "1" (PTRS_PER_PAGE)); + + return (unsigned long) empty_bad_page_table; +} + +unsigned long __bad_page(void) +{ + extern char empty_bad_page[PAGE_SIZE]; + unsigned long dummy; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + "1:\tsw\t$0,(%0)\n\t" + "subu\t%1,%1,1\n\t" + "bne\t$0,%1,1b\n\t" + "addiu\t%0,%0,1\n\t" + ".set\treorder" + :"=r" (dummy), + "=r" (dummy) + :"0" ((long) empty_bad_page), + "1" (PTRS_PER_PAGE)); + + return (unsigned long) empty_bad_page; +} + +unsigned long __zero_page(void) +{ + extern char empty_zero_page[PAGE_SIZE]; + unsigned long dummy; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + "1:\tsw\t$0,(%0)\n\t" + "subu\t%1,%1,1\n\t" + "bne\t$0,%1,1b\n\t" + "addiu\t%0,%0,1\n\t" + ".set\treorder" + :"=r" (dummy), + "=r" (dummy) + :"0" ((long) empty_zero_page), + "1" (PTRS_PER_PAGE)); + + 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; + + start_mem = PAGE_ALIGN(start_mem); + address = 0; + pg_dir = swapper_pg_dir; + while (address < end_mem) { + tmp = *pg_dir; + tmp &= PAGE_MASK; + if (!tmp) { + tmp = start_mem; + start_mem += PAGE_SIZE; + } + /* + * also map it in at 0x00000000 for init + */ + *pg_dir = tmp | PAGE_TABLE; + 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; + } + } +#if KERNELBASE == KSEG0 + cacheflush(); +#endif + invalidate(); + return free_area_init(start_mem, end_mem); +} + +void mem_init(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_mem = PAGE_ALIGN(start_mem); + + 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)]) { + /* + * We don't have any reserved pages on the + * MIPS systems supported until now + */ + if (0) + reservedpages++; + else if (tmp < ((unsigned long) &etext - KERNELBASE)) + 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)); + + invalidate(); + 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; +} diff -u --recursive --new-file v1.1.81/linux/arch/sparc/Makefile linux/arch/sparc/Makefile --- v1.1.81/linux/arch/sparc/Makefile Wed Jan 11 21:14:25 1995 +++ linux/arch/sparc/Makefile Mon Jan 16 07:28:17 1995 @@ -19,8 +19,9 @@ HEAD := arch/sparc/kernel/head.o -SUBDIRS := $(SUBDIRS) arch/sparc/kernel arch/sparc/lib -ARCHIVES := arch/sparc/kernel/kernel.o arch/sparc/lib/lib.a $(ARCHIVES) +SUBDIRS := $(SUBDIRS) arch/sparc/kernel arch/sparc/lib arch/sparc/mm +ARCHIVES := arch/sparc/kernel/kernel.o arch/sparc/mm/mm.o $(ARCHIVES) +LIBS := arch/sparc/lib/lib.a $(LIBS) archclean: diff -u --recursive --new-file v1.1.81/linux/arch/sparc/kernel/Makefile linux/arch/sparc/kernel/Makefile --- v1.1.81/linux/arch/sparc/kernel/Makefile Mon Jan 9 11:24:20 1995 +++ linux/arch/sparc/kernel/Makefile Mon Jan 16 07:27:11 1995 @@ -18,14 +18,14 @@ .S.o: $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o -OBJS = entry.o traps.o irq.o process.o +OBJS = entry.o traps.o irq.o process.o promops.o signal.o ioport.o all: kernel.o head.o head.o: head.s head.s: head.S $(TOPDIR)/include/asm-sparc/head.h - $(CPP) -traditional -o $*.s $< + $(CPP) -D__ASSEMBLY__ -traditional -o $*.s $< kernel.o: $(OBJS) $(LD) -r -o kernel.o $(OBJS) diff -u --recursive --new-file v1.1.81/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S --- v1.1.81/linux/arch/sparc/kernel/entry.S Wed Jan 11 21:14:25 1995 +++ linux/arch/sparc/kernel/entry.S Mon Jan 16 07:27:11 1995 @@ -283,8 +283,9 @@ sethi %hi(lnx_winmask), %l6 or %l6, %lo(lnx_winmask), %l6 ldub [%l6 + %l3], %l5 - b back_to_userland_safety ! may need a sched() rd %wim, %l4 + jmp %l1 + rett %l2 /* A window spill has occurred. This presents a weird situation, a restore * was attempted and a trap occurred. Therefore the restore attempt had no @@ -370,7 +371,7 @@ sethi %hi(_current), %l6 ld [%l6 + %lo(_current)], %l6 st %l4, [%l6 + THREAD_UWINDOWS] ! update current->tss values - ld [%l6 + THREAD_WIN], %l5 + ld [%l6 + THREAD_WIM], %l5 sll %l4, %l5, %l4 wr %l4, 0x0, %wim ld [%l6 + THREAD_KSP], %sp ! set to kernel stack pointer @@ -389,7 +390,7 @@ std %i0, [%sp + C_STACK + 0x30] std %i2, [%sp + C_STACK + 0x38] std %i4, [%sp + C_STACK + 0x40] - call _sparc_trap + call sparc_trap std %i6, [%sp + C_STACK + 0x48] ldd [%sp + C_STACK], %l0 @@ -472,6 +473,29 @@ jmp %l1 rett %l2 + .globl trap_entry +trap_entry: + TRAP_WIN_CLEAN + jmp %l1 + rett %l2 + + .globl linux_trap_nmi +linux_trap_nmi: + TRAP_WIN_CLEAN + jmp %l1 + rett %l2 + + .globl sparc_trap +sparc_trap: + TRAP_WIN_CLEAN + jmp %l1 + rett %l2 + + .globl leave_trap +leave_trap: + jmp %l1 + rett %l2 + /* The following two things point to window management tables. The first one is used to quickly look up how many user windows there are from trap-land. The second is used in a trap handler to determine if a rett @@ -486,3 +510,147 @@ lnx_winmask: .byte 2, 4, 8, 16, 32, 64, 128,1 ! lnx_winmask[0..7] + .align 4 + .globl _sys_call_table +_sys_call_table: + .long _sys_setup /* 0 */ + .long _sys_exit + .long _sys_fork + .long _sys_read + .long _sys_write + .long _sys_open /* 5 */ + .long _sys_close + .long _sys_waitpid + .long _sys_creat + .long _sys_link + .long _sys_unlink /* 10 */ + .long _sys_execve + .long _sys_chdir + .long _sys_time + .long _sys_mknod + .long _sys_chmod /* 15 */ + .long _sys_chown + .long _sys_break + .long _sys_stat + .long _sys_lseek + .long _sys_getpid /* 20 */ + .long _sys_mount + .long _sys_umount + .long _sys_setuid + .long _sys_getuid + .long _sys_stime /* 25 */ + .long _sys_ni_syscall /* this will be sys_ptrace() */ + .long _sys_alarm + .long _sys_fstat + .long _sys_pause + .long _sys_utime /* 30 */ + .long _sys_stty + .long _sys_gtty + .long _sys_access + .long _sys_nice + .long _sys_ftime /* 35 */ + .long _sys_sync + .long _sys_kill + .long _sys_rename + .long _sys_mkdir + .long _sys_rmdir /* 40 */ + .long _sys_dup + .long _sys_pipe + .long _sys_times + .long _sys_prof + .long _sys_brk /* 45 */ + .long _sys_setgid + .long _sys_getgid + .long _sys_signal + .long _sys_geteuid + .long _sys_getegid /* 50 */ + .long _sys_acct + .long _sys_phys + .long _sys_lock + .long _sys_ioctl + .long _sys_fcntl /* 55 */ + .long _sys_mpx + .long _sys_setpgid + .long _sys_ulimit + .long _sys_olduname + .long _sys_umask /* 60 */ + .long _sys_chroot + .long _sys_ustat + .long _sys_dup2 + .long _sys_getppid + .long _sys_getpgrp /* 65 */ + .long _sys_setsid + .long _sys_sigaction + .long _sys_sgetmask + .long _sys_ssetmask + .long _sys_setreuid /* 70 */ + .long _sys_setregid + .long _sys_sigsuspend + .long _sys_sigpending + .long _sys_sethostname + .long _sys_setrlimit /* 75 */ + .long _sys_getrlimit + .long _sys_getrusage + .long _sys_gettimeofday + .long _sys_settimeofday + .long _sys_getgroups /* 80 */ + .long _sys_setgroups + .long _sys_select + .long _sys_symlink + .long _sys_lstat + .long _sys_readlink /* 85 */ + .long _sys_uselib + .long _sys_swapon + .long _sys_reboot + .long _sys_readdir + .long _sys_mmap /* 90 */ + .long _sys_munmap + .long _sys_truncate + .long _sys_ftruncate + .long _sys_fchmod + .long _sys_fchown /* 95 */ + .long _sys_getpriority + .long _sys_setpriority + .long _sys_profil + .long _sys_statfs + .long _sys_fstatfs /* 100 */ + .long _sys_ni_syscall + .long _sys_socketcall + .long _sys_syslog + .long _sys_setitimer + .long _sys_getitimer /* 105 */ + .long _sys_newstat + .long _sys_newlstat + .long _sys_newfstat + .long _sys_uname + .long _sys_ni_syscall /* 110 */ + .long _sys_vhangup + .long _sys_idle + .long _sys_ni_syscall /* was vm86, meaningless on Sparc */ + .long _sys_wait4 + .long _sys_swapoff /* 115 */ + .long _sys_sysinfo + .long _sys_ipc + .long _sys_fsync + .long _sys_sigreturn + .long _sys_ni_syscall /* 120 */ + .long _sys_setdomainname + .long _sys_newuname + .long _sys_ni_syscall + .long _sys_adjtimex + .long _sys_mprotect /* 125 */ + .long _sys_sigprocmask + .long _sys_create_module + .long _sys_init_module + .long _sys_delete_module + .long _sys_get_kernel_syms /* 130 */ + .long _sys_ni_syscall + .long _sys_getpgid + .long _sys_fchdir + .long _sys_bdflush + .long _sys_sysfs /* 135 */ + .long _sys_personality + .long 0 /* for afs_syscall */ + .long _sys_setfsuid + .long _sys_setfsgid + .long _sys_llseek /* 140 */ diff -u --recursive --new-file v1.1.81/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S --- v1.1.81/linux/arch/sparc/kernel/head.S Wed Jan 11 21:14:25 1995 +++ linux/arch/sparc/kernel/head.S Mon Jan 16 07:27:11 1995 @@ -73,6 +73,7 @@ .asciz "sun4c" .ascii " " + .align 4 /* * Sun people can't spell worth damn. "compatability" indeed. * At least we *know* we can't spell, and use a spell-checker. @@ -120,6 +121,8 @@ /* XXX how to figure out vm mapped by prom? May have to scan magic addresses */ mem_prop_physavail: .asciz "available" + + .align 4 mem_prop_phystot: .asciz "reg" /* v2_memory descriptor struct kludged here for assembly, if it ain't broke */ @@ -129,6 +132,8 @@ .align 4 v2_printf_physavail: .asciz "Physical Memory Available: 0x%x bytes" + + .align 4 v2_printf_phystot: .asciz "Physical Memory: 0x%x bytes" /* A place to store property strings returned from the prom 'node' funcs */ @@ -136,15 +141,16 @@ .align 4 prop_string_buf: .skip 32 + .align 4 prop_name: .asciz "name" + .align 4 - current_node: .skip 4 - .align 4 /* nice little boot message */ + .align 4 boot_msg: .ascii "Booting Sparc-Linux V0.00PRE-ALPHA " .ascii WHO_COMPILED_ME @@ -497,7 +503,8 @@ */ gokernel: or %g0, %o0, %g7 - st %o0, [_prom_vector_p] ! we will need it later + sethi %hi(_prom_vector_p), %g1 + st %o0, [%g1 + %lo(_prom_vector_p)] ! we will need it later rd %psr, %l2 rd %wim, %l3 rd %tbr, %l4 @@ -781,7 +788,7 @@ /* I want a kernel stack NOW! */ set USRSTACK - C_STACK, %fp - set estack0 - C_STACK - 80, %sp + set USRSTACK - C_STACK + 80, %sp rd %psr, %l0 wr %l0, PSR_ET, %psr WRITE_PAUSE @@ -878,8 +885,12 @@ add %g2, 0x4, %g2 #endif +/* First we call init_prom() to set up romvec, then off to start_kernel() */ + sethi %hi(_prom_vector_p), %g5 - ld [%g5 + %lo(_prom_vector_p)], %o0 + call _init_prom + ld [%g5 + %lo(_prom_vector_p)], %o0 /* delay slot */ + call _start_kernel nop @@ -964,4 +975,41 @@ _boot_tbr: .skip 4 _boot_smp_ptr: .skip 4 + + .align 4 +/* Miscellaneous pieces of information saved at kernel startup. */ + .globl _kernel_text_len, _kernel_data_len, _kernel_bss_len +_kernel_text_len: .word 0 +_kernel_data_len: .word 0 +_kernel_bss_len: .word 0 + +/* These are for page alignment/offset information as they change from + machine to machine. +*/ + + .globl _pgshift, _nbpg, _pgofset + + .align 4 +_pgshift: + .word 1 +_nbpg: + .word 1 +_pgofset: + .word 1 + +/* Just to get the kernel through the compiler for now */ + .globl _swapper_pg_dir,_pg0 + .globl _empty_bad_page + .globl _empty_bad_page_table + .globl _empty_zero_page + .globl _floppy_track_buffer +_floppy_track_buffer: + .fill 512*2*36,1,0 + + .align 4 +_swapper_pg_dir: .skip 0x1000 +_pg0: .skip 0x1000 +_empty_bad_page: .skip 0x1000 +_empty_bad_page_table: .skip 0x1000 +_empty_zero_page: .skip 0x1000 diff -u --recursive --new-file v1.1.81/linux/arch/sparc/kernel/ioport.c linux/arch/sparc/kernel/ioport.c --- v1.1.81/linux/arch/sparc/kernel/ioport.c Thu Jan 1 02:00:00 1970 +++ linux/arch/sparc/kernel/ioport.c Mon Jan 16 07:27:11 1995 @@ -0,0 +1,20 @@ +/* ioport.c: I/O access on the Sparc. Work in progress.. Most of the things + * in this file are for the sole purpose of getting the kernel + * throught the compiler. :-) + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#include +#include +#include +#include +#include + +/* + * this changes the io permissions bitmap in the current task. + */ +asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on) +{ + return 0; +} diff -u --recursive --new-file v1.1.81/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c --- v1.1.81/linux/arch/sparc/kernel/irq.c Wed Jan 11 21:14:25 1995 +++ linux/arch/sparc/kernel/irq.c Mon Jan 16 07:27:11 1995 @@ -104,13 +104,6 @@ return; } -static void math_error_irq(int cpl) -{ - return; -} - -static void no_action(int cpl) { } - unsigned int probe_irq_on (void) { unsigned int irqs = 0; diff -u --recursive --new-file v1.1.81/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c --- v1.1.81/linux/arch/sparc/kernel/process.c Wed Jan 11 21:14:25 1995 +++ linux/arch/sparc/kernel/process.c Mon Jan 16 07:27:11 1995 @@ -99,3 +99,11 @@ putname(filename); return error; } + +/* + * Bogon bios32 stuff... + */ +unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end) +{ + return memory_start; +} diff -u --recursive --new-file v1.1.81/linux/arch/sparc/kernel/promops.c linux/arch/sparc/kernel/promops.c --- v1.1.81/linux/arch/sparc/kernel/promops.c Thu Jan 1 02:00:00 1970 +++ linux/arch/sparc/kernel/promops.c Mon Jan 16 07:27:11 1995 @@ -0,0 +1,21 @@ +/* promops.c: Prom node tree operations and Prom Vector initialization + * initialization routines. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#include + +extern struct linux_romvec *romvec; + +/* This gets called from head.S upon bootup to initialize the + * prom vector pointer for the rest of the kernel. + */ + +void +init_prom(struct linux_romvec *r_ptr) +{ + romvec = r_ptr; + + return; +} diff -u --recursive --new-file v1.1.81/linux/arch/sparc/kernel/signal.c linux/arch/sparc/kernel/signal.c --- v1.1.81/linux/arch/sparc/kernel/signal.c Thu Jan 1 02:00:00 1970 +++ linux/arch/sparc/kernel/signal.c Mon Jan 16 07:27:11 1995 @@ -0,0 +1,72 @@ +/* + * linux/arch/sparc/kernel/signal.c + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#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; + + mask = current->blocked; + current->blocked = set & _BLOCKABLE; + + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(mask,regs)) + return -EINTR; + } +} + +asmlinkage int sys_sigreturn(unsigned long __unused) +{ + __unused=1; + + do_exit(SIGSEGV); + return __unused; +} + +/* + * Set up a signal frame... Make the stack look the way iBCS2 expects + * it to look. + */ +void setup_frame(struct sigaction * sa, unsigned long ** fp, unsigned long eip, + struct pt_regs * regs, int signr, unsigned long oldmask) +{ + return; +} + +/* + * 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. + */ +asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs) +{ + return 1; +} diff -u --recursive --new-file v1.1.81/linux/arch/sparc/kernel/traps.c linux/arch/sparc/kernel/traps.c --- v1.1.81/linux/arch/sparc/kernel/traps.c Wed Jan 11 21:14:25 1995 +++ linux/arch/sparc/kernel/traps.c Mon Jan 16 07:27:11 1995 @@ -39,3 +39,7 @@ return; } +void die_if_kernel(char * str, struct pt_regs * regs, long err) +{ + return; +} diff -u --recursive --new-file v1.1.81/linux/arch/sparc/lib/Makefile linux/arch/sparc/lib/Makefile --- v1.1.81/linux/arch/sparc/lib/Makefile Wed Jan 11 21:14:25 1995 +++ linux/arch/sparc/lib/Makefile Mon Jan 16 07:27:58 1995 @@ -9,7 +9,7 @@ .c.o: $(CC) $(CFLAGS) -c $< -OBJS = mul.o rem.o sdiv.o udiv.o umul.o urem.o +OBJS = mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) @@ -33,8 +33,10 @@ urem.o: urem.S $(CC) -DST_DIV0=0x2 -c -o urem.o urem.S +ashrdi3.o: ashrdi3.S + $(CC) -c -o ashrdi3.o ashrdi3.S + dep: - $(CPP) -M *.S > .depend # # include a dependency file if one exists diff -u --recursive --new-file v1.1.81/linux/arch/sparc/lib/ashrdi3.S linux/arch/sparc/lib/ashrdi3.S --- v1.1.81/linux/arch/sparc/lib/ashrdi3.S Thu Jan 1 02:00:00 1970 +++ linux/arch/sparc/lib/ashrdi3.S Mon Jan 16 07:27:58 1995 @@ -0,0 +1,26 @@ +/* ashrdi3.S: The filesystem code creates all kinds of references to + * this little routine on the sparc with gcc. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + + .globl ___ashrdi3 +___ashrdi3: + tst %o2 + be 3f + or %g0, 32, %g2 + sub %g2, %o2, %g2 + tst %g2 + bg 1f + sra %o0, %o2, %o4 + sra %o0, 31, %o4 + sub %g0, %g2, %g2 + ba 2f + sra %o0, %g2, %o5 +1: sll %o0, %g2, %g3 + srl %o1, %o2, %g2 + or %g2, %g3, %o5 +2: or %g0, %o4, %o0 + or %g0, %o5, %o1 +3: jmpl %o7 + 8, %g0 + nop diff -u --recursive --new-file v1.1.81/linux/arch/sparc/mm/Makefile linux/arch/sparc/mm/Makefile --- v1.1.81/linux/arch/sparc/mm/Makefile Thu Jan 1 02:00:00 1970 +++ linux/arch/sparc/mm/Makefile Mon Jan 16 07:27:23 1995 @@ -0,0 +1,32 @@ +# +# Makefile for the linux Sparc-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 vac-flush.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 diff -u --recursive --new-file v1.1.81/linux/arch/sparc/mm/fault.c linux/arch/sparc/mm/fault.c --- v1.1.81/linux/arch/sparc/mm/fault.c Thu Jan 1 02:00:00 1970 +++ linux/arch/sparc/mm/fault.c Mon Jan 16 07:27:23 1995 @@ -0,0 +1,387 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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); + +/* Sparc stuff... I know this is a ugly place to put the PROM vector, don't + * remind me. + */ +extern char* trapbase; +extern unsigned int end[], etext[], msgbuf[]; +struct linux_romvec *romvec; + +/* foo */ + +int tbase_needs_unmapping; + +/* At boot time we determine these two values necessary for setting + * up the segment maps and page table entries (pte's). + */ + +int num_segmaps, num_contexts; +int invalid_segment; + +/* various Virtual Address Cache parameters we find at boot time... */ + +int vac_size, vac_linesize, vac_do_hw_vac_flushes; +int vac_entries_per_context, vac_entries_per_segment; +int vac_entries_per_page; + +/* + * 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 + +/* Traverse the memory lists in the prom to see how much physical we + * have. + */ + +unsigned long +probe_memory(void) +{ + register struct linux_romvec *lprom; + register struct linux_mlist_v0 *mlist; + register unsigned long bytes, base_paddr; + register int i; + + bytes = 0; + base_paddr = 0; + lprom = romvec; + switch(lprom->pv_romvers) + { + case 0: + mlist=(*(lprom->pv_v0mem.v0_totphys)); + bytes=mlist->num_bytes; + base_paddr = (unsigned long) mlist->start_adr; + printk("Bank 1: starting at 0x%x holding %d bytes\n", + (unsigned int) base_paddr, (int) bytes); + i=1; + if(mlist->theres_more != (void *)0) + { + i++; + mlist=mlist->theres_more; + bytes+=mlist->num_bytes; + printk("Bank %d: starting at 0x%x holding %d bytes\n", i, + (unsigned int) mlist->start_adr, (int) mlist->num_bytes); + } + break; + case 2: + printk("no v2 memory probe support yet.\n"); + (*(lprom->pv_halt))(); + break; + } + printk("Physical memory: %d bytes starting at va 0x%x\n", + (unsigned int) bytes, (int) base_paddr); + + return bytes; +} + +/* Sparc routine to reserve the mapping of the open boot prom */ + +/* uncomment this for FAME and FORTUNE! */ +/* #define DEBUG_MAP_PROM */ + +int +map_the_prom(int curr_num_segs) +{ + register unsigned long prom_va_begin; + register unsigned long prom_va_end; + register int segmap_entry, i; + + prom_va_begin = LINUX_OPPROM_BEGVM; + prom_va_end = LINUX_OPPROM_ENDVM; + +#ifdef DEBUG_MAP_PROM + printk("\ncurr_num_segs = 0x%x\n", curr_num_segs); +#endif + + while( prom_va_begin < prom_va_end) + { + segmap_entry=get_segmap(prom_va_begin); + + curr_num_segs = ((segmap_entry 0;) + (*romvec->pv_setctxt)(i, (char *) prom_va_begin, + segmap_entry); + + if(segmap_entry == invalid_segment) + { + +#ifdef DEBUG_MAP_PROM + printk("invalid_segments, virt_addr 0x%x\n", prom_va_begin); +#endif + + prom_va_begin += 0x40000; /* num bytes per segment entry */ + continue; + } + + /* DUH, prom maps itself so that users can access it. This is + * broken. + */ + +#ifdef DEBUG_MAP_PROM + printk("making segmap for prom privileged, va = 0x%x\n", + prom_va_begin); +#endif + + for(i = 0x40; --i >= 0; prom_va_begin+=4096) + { + put_pte(prom_va_begin, get_pte(prom_va_begin) | 0x20000000); + } + + } + + printk("Mapped the PROM in all contexts...\n"); + +#ifdef DEBUG_MAP_PROM + printk("curr_num_segs = 0x%x\n", curr_num_segs); +#endif + + return curr_num_segs; + +} + +/* + * This routine handles page faults. It determines the address, + * and the problem, and then passes it off to one of the appropriate + * routines. + */ +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]; + + return (unsigned long) empty_bad_page_table; +} + +unsigned long __bad_page(void) +{ + extern char empty_bad_page[PAGE_SIZE]; + + return (unsigned long) empty_bad_page; +} + +unsigned long __zero_page(void) +{ + extern char empty_zero_page[PAGE_SIZE]; + + return (unsigned long) empty_zero_page; +} + +void show_mem(void) +{ + int i=0,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) +{ + int pg_segmap; + unsigned long i, a, b, mask=0; + register int num_segs, num_ctx; + register char * c; + + num_segs = num_segmaps; + num_ctx = num_contexts; + + num_segs -= 1; + invalid_segment = num_segs; + +/* On the sparc we first need to allocate the segmaps for the + * PROM's virtual space, and make those segmaps unusable. We + * map the PROM in ALL contexts therefore the break key and the + * sync command work no matter what state you took the machine + * out of + */ + + printk("mapping the prom...\n"); + num_segs = map_the_prom(num_segs); + + start_mem = PAGE_ALIGN(start_mem); + + /* ok, allocate the kernel pages, map them in all contexts + * (with help from the prom), and lock them. Isn't the sparc + * fun kiddies? TODO + */ + + b=PGDIR_ALIGN(start_mem)>>18; + c= (char *)0x0; + + printk("mapping kernel in all contexts...\n"); + + for(a=0; apv_setctxt))(i, (char *) c, a); + c += 4096; + } + } + + /* Ok, since now mapped in all contexts, we can free up + * context zero to be used amongst user processes. + */ + + /* free context 0 here TODO */ + + /* invalidate all user pages and initialize the pte struct + * for userland. TODO + */ + + /* Make the kernel text unwritable and cacheable, the prom + * loaded out text as writable, only sneaky sunos kernels need + * self-modifying code. + */ + + a= (unsigned long) etext; + b=PAGE_ALIGN((unsigned long) msgbuf); + mask=~(PTE_NC|PTE_W); /* make cacheable + not writable */ + + printk("changing kernel text perms...\n"); + + + /* must do for every segment since kernel uses all contexts + * and unlike some sun kernels I know of, we can't hard wire + * context 0 just for the kernel, that is unnecessary. + */ + + for(i=0; i<8; i++) + { + b=PAGE_ALIGN((unsigned long) trapbase); + + switch_to_context(i); + + for(;b> 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; +} diff -u --recursive --new-file v1.1.81/linux/arch/sparc/mm/vac-flush.c linux/arch/sparc/mm/vac-flush.c --- v1.1.81/linux/arch/sparc/mm/vac-flush.c Mon Jan 9 07:21:58 1995 +++ linux/arch/sparc/mm/vac-flush.c Mon Jan 16 07:27:23 1995 @@ -8,7 +8,7 @@ /* Flush all VAC entries for the current context */ -extern int do_hw_vac_flushes, vac_size, vac_linesize; +extern int vac_do_hw_vac_flushes, vac_size, vac_linesize; extern int vac_entries_per_context, vac_entries_per_segment; extern int vac_entries_per_page; @@ -21,7 +21,7 @@ entries_left = vac_entries_per_context; address = (char *) 0; - if(do_hw_vac_flushes) + if(vac_do_hw_vac_flushes) { while(entries_left-- >=0) { @@ -44,14 +44,14 @@ flush_vac_segment(register unsigned int segment) { register int entries_left, offset; - register char* address; + register char* address = (char *) 0; entries_left = vac_entries_per_segment; __asm__ __volatile__("sll %0, 18, %1\n\t" "sra %1, 0x2, %1\n\t" : "=r" (segment) : "0" (address)); - if(do_hw_vac_flushes) + if(vac_do_hw_vac_flushes) { while(entries_left-- >=0) { @@ -75,9 +75,9 @@ { register int entries_left, offset; - if(do_hw_vac_flushes) + if(vac_do_hw_vac_flushes) { - hw_flush_vac_page_entry(addr); + hw_flush_vac_page_entry((unsigned long *) addr); } else { @@ -85,7 +85,7 @@ offset = vac_linesize; while(entries_left-- >=0) { - sw_flush_vac_page_entry(addr); + sw_flush_vac_page_entry((unsigned long *) addr); addr += offset; } } diff -u --recursive --new-file v1.1.81/linux/drivers/block/README.sbpcd linux/drivers/block/README.sbpcd --- v1.1.81/linux/drivers/block/README.sbpcd Fri Jan 13 16:57:03 1995 +++ linux/drivers/block/README.sbpcd Sun Jan 15 21:46:23 1995 @@ -1,4 +1,4 @@ -This README belongs to release 3.1 or newer of the SoundBlaster Pro +This README belongs to release 3.2 or newer of the SoundBlaster Pro (Matsushita, Kotobuki, Panasonic, CreativeLabs, Longshine and soon TEAC, too) CD-ROM driver for Linux. @@ -32,7 +32,7 @@ new drives. But I mostly will not answer (just use) it. This driver is NOT for Mitsumi or Sony or Aztech or Philips or XXX drives, -and this driver is in no way useable for any new IDE ATAPI drive. +and this driver is in no way usable for any new IDE ATAPI drive. For Aztech CDA-268 drives (and for some Wearnes, Okano and Orchid drives), Werner Zimmermann has done a driver which currently resides at ftp.gwdg.de under /pub/linux/cdrom/drivers/aztech/. diff -u --recursive --new-file v1.1.81/linux/drivers/block/cdu31a.c linux/drivers/block/cdu31a.c --- v1.1.81/linux/drivers/block/cdu31a.c Mon Jan 9 11:24:20 1995 +++ linux/drivers/block/cdu31a.c Mon Jan 16 07:17:35 1995 @@ -373,7 +373,7 @@ } static void -cdu31a_interrupt(int unused) +cdu31a_interrupt(int irq, struct pt_regs *regs) { disable_interrupts(); if (cdu31a_irq_wait != NULL) diff -u --recursive --new-file v1.1.81/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v1.1.81/linux/drivers/block/floppy.c Wed Jan 11 21:14:26 1995 +++ linux/drivers/block/floppy.c Mon Jan 16 13:41:14 1995 @@ -1414,7 +1414,7 @@ { 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 }; /* interrupt handler */ -static void floppy_interrupt(int unused) +static void floppy_interrupt(int irq, struct pt_regs * regs) { void (*handler)(void) = DEVICE_INTR; diff -u --recursive --new-file v1.1.81/linux/drivers/block/hd.c linux/drivers/block/hd.c --- v1.1.81/linux/drivers/block/hd.c Mon Jan 9 11:24:20 1995 +++ linux/drivers/block/hd.c Mon Jan 16 07:17:35 1995 @@ -934,7 +934,7 @@ NULL /* next */ }; -static void hd_interrupt(int unused) +static void hd_interrupt(int irq, struct pt_regs *regs) { void (*handler)(void) = DEVICE_INTR; diff -u --recursive --new-file v1.1.81/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c --- v1.1.81/linux/drivers/block/ide-cd.c Fri Jan 13 16:57:03 1995 +++ linux/drivers/block/ide-cd.c Sun Jan 15 00:54:27 1995 @@ -559,7 +559,7 @@ ++rq->sector; } - /* If we've statisfied the current request, terminate it successfully. */ + /* If we've satisfied the current request, terminate it successfully. */ if (rq->nr_sectors == 0) { cdrom_end_request (1, dev); diff -u --recursive --new-file v1.1.81/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v1.1.81/linux/drivers/block/ide.c Fri Jan 13 16:57:04 1995 +++ linux/drivers/block/ide.c Mon Jan 16 07:17:35 1995 @@ -1189,13 +1189,13 @@ #if OPTIMIZE_IRQS /* entry point for all interrupts on ide0 when sharing_single_irq==0 */ -static void ide0_intr (int irq) +static void ide0_intr (int irq, struct pt_regs *regs) { IDE_INTR(0); } /* entry point for all interrupts on ide1 when sharing_single_irq==0 */ -static void ide1_intr (int irq) +static void ide1_intr (int irq, struct pt_regs *regs) { IDE_INTR(1); } @@ -1206,7 +1206,7 @@ #define ide1_intr ide_intr /* entry point for all interrupts when sharing_single_irq==0 */ -static void ide_intr (int irq) +static void ide_intr (int irq, struct pt_regs *regs) { #if SUPPORT_TWO_INTERFACES byte hwif = (irq != ide_irq[0]); @@ -1602,7 +1602,7 @@ /* * Non-ATAPI drives seem to always use big-endian string ordering. * Most ATAPI cdrom drives, such as the NEC, Vertos, and some Mitsumi - * models, use little-endian. But otherMitsumi models appear to use + * models, use little-endian. But other Mitsumi models appear to use * big-endian, confusing the issue. We try to take all of this into * consideration, "knowing" that Mitsumi drive names begin with "FX". */ @@ -2080,7 +2080,7 @@ static byte rc = 0; unsigned long flags; const char *msg = "", *primary_secondary[] = {"primary", "secondary"}; - void (*handler)(int) = HWIF ? &ide1_intr : &ide0_intr; + void (*handler)(int, struct pt_regs *) = HWIF ? &ide1_intr : &ide0_intr; #if SUPPORT_SHARING_IRQ if (sharing_single_irq) { diff -u --recursive --new-file v1.1.81/linux/drivers/block/mcd.c linux/drivers/block/mcd.c --- v1.1.81/linux/drivers/block/mcd.c Mon Jan 9 11:24:20 1995 +++ linux/drivers/block/mcd.c Mon Jan 16 07:17:35 1995 @@ -597,7 +597,7 @@ */ static void -mcd_interrupt(int unused) +mcd_interrupt(int irq, struct pt_regs * regs) { int st; diff -u --recursive --new-file v1.1.81/linux/drivers/block/sbpcd.c linux/drivers/block/sbpcd.c --- v1.1.81/linux/drivers/block/sbpcd.c Fri Jan 13 16:57:04 1995 +++ linux/drivers/block/sbpcd.c Sun Jan 15 21:46:23 1995 @@ -9,7 +9,7 @@ * Not for the TEAC CD-55A drive (yet). * Not for the CreativeLabs CD200 drive (yet). * - * NOTE: This is release 3.1. + * NOTE: This is release 3.2. * It works with my SbPro & drive CR-521 V2.11 from 2/92 * and with the new CR-562-B V0.75 on a "naked" Panasonic * CI-101P interface. And vice versa. @@ -176,6 +176,8 @@ * entries for some people, but will help the DAU (german TLA, english: * "newbie", maybe ;-) to install his "first" system from a CD. * + * 3.2 Still testing with CD200 and CD-55A drives. + * * TODO * * disk change detection @@ -253,7 +255,7 @@ #include "blk.h" -#define VERSION "3.1 Eberhard Moenkeberg " +#define VERSION "3.2 Eberhard Moenkeberg " /* * still testing around... @@ -263,8 +265,6 @@ */ #define READ_AUDIO 4 /* max. number of audio frames to read with one */ /* request (allocates n* 2352 bytes kernel memory!) */ -#define TEAC 0 /* if 1: enable TEAC CD-55A support (not usable yet) */ -#define CD200 1 /* if 1: enable CD200 support (not usable yet) */ #define JUKEBOX 1 /* tray control: eject tray if no disk is in */ #define EJECT 1 /* tray control: eject tray after last use */ #define LONG_TIMING 0 /* test against timeouts with "gold" CDs on CR-521 */ @@ -289,6 +289,9 @@ #define INLINE inline #endif +#define TEAC 0 +#define CD200 0 + /*==========================================================================*/ /* * provisions for more than 1 driver issues @@ -408,7 +411,7 @@ */ static void sbp_read_cmd(void); static int sbp_data(void); -static int cmd_out(void); +static int cmd_out(int); static int DiskInfo(void); static int sbpcd_chk_disk_change(dev_t); @@ -516,7 +519,7 @@ static u_int response_count=0; static u_int flags_cmd_out; static u_char cmd_type=0; -static u_char drvcmd[7]; +static u_char drvcmd[10]; static u_char infobuf[20]; static u_char xa_head_buf[CD_XA_HEAD]; static u_char xa_tail_buf[CD_XA_TAIL]; @@ -803,7 +806,7 @@ { int i; - for (i=0;i<7;i++) drvcmd[i]=0; + for (i=0;i<10;i++) drvcmd[i]=0; cmd_type=0; } /*==========================================================================*/ @@ -1072,7 +1075,7 @@ else /* CD200, CD-55A */ { } - i=cmd_out(); + i=cmd_out(7); DriveStruct[d].error_byte=0; DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: cmd_out(82) returns %d (%02X)\n",i,i)); if (i<0) return (i); @@ -1087,19 +1090,19 @@ return (i); } /*==========================================================================*/ -static int cmd_out(void) +static int cmd_out(int len) { int i=0; if (flags_cmd_out&f_putcmd) { DPRINTF((DBG_CMD,"SBPCD: cmd_out: put")); - for (i=0;i<7;i++) DPRINTF((DBG_CMD," %02X",drvcmd[i])); + for (i=0;i0) return (i); DriveStruct[d].diskstate_flags |= volume_bit; return (0); @@ -1405,7 +1408,7 @@ flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check; response_count=0; cmd_type=0; - i=cmd_out(); + i=cmd_out(7); return (i); } /*==========================================================================*/ @@ -1421,7 +1424,7 @@ drvcmd[0]=CMD1_RESET; flags_cmd_out=f_putcmd; response_count=0; - i=cmd_out(); + i=cmd_out(7); } else /* CD200, CD-55A */ { @@ -1499,7 +1502,7 @@ } if (pau_res!=1) drvcmd[1]=0x80; response_count=0; - i=cmd_out(); + i=cmd_out(7); return (i); } /*==========================================================================*/ @@ -1528,7 +1531,7 @@ else /* CD200, CD-55A */ { } - i=cmd_out(); + i=cmd_out(7); DPRINTF((DBG_LCS,"SBPCD: p_door_locked bit %d after\n", st_door_locked)); return (i); } @@ -1557,7 +1560,7 @@ { } response_count=0; - i=cmd_out(); + i=cmd_out(7); DPRINTF((DBG_LCS,"SBPCD: p_door_closed bit %d after\n", st_door_closed)); return (i); } @@ -1589,7 +1592,7 @@ else /* CD200, CD-55A */ { } - i=cmd_out(); + i=cmd_out(7); if (i<0) return (i); DPRINTF((DBG_SQ,"SBPCD: xx_ReadSubQ:")); for (i=0;i<(fam1_drive?11:13);i++) @@ -1645,7 +1648,7 @@ else /* CD200, CD-55A */ { } - i=cmd_out(); + i=cmd_out(7); if (i<0) return (i); i=0; if (fam0L_drive) DriveStruct[d].sense_byte=0; @@ -1705,7 +1708,7 @@ { } response_count=0; - i=cmd_out(); + i=cmd_out(7); if (i<0) return (i); DriveStruct[d].diskstate_flags |= frame_size_bit; return (0); @@ -1740,7 +1743,7 @@ else /* CD200, CD-55A */ { } - i=cmd_out(); + i=cmd_out(7); if (i<0) return (i); if (fam1_drive) { @@ -1848,7 +1851,7 @@ { } response_count=5; - i=cmd_out(); + i=cmd_out(7); if (i<0) return (i); DriveStruct[d].CDsize_blk=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])); if (fam1_drive) DriveStruct[d].CDsize_blk=msf2blk(DriveStruct[d].CDsize_blk); @@ -1881,7 +1884,7 @@ { } response_count=6; - i=cmd_out(); + i=cmd_out(7); if (i<0) return (i); DriveStruct[d].xa_byte=infobuf[0]; DriveStruct[d].n_first_track=infobuf[1]; @@ -1918,7 +1921,7 @@ } drvcmd[2]=num; response_count=8; - i=cmd_out(); + i=cmd_out(7); if (i<0) return (i); DriveStruct[d].TocEnt_nixbyte=infobuf[0]; DriveStruct[d].TocEnt_ctl_adr=swap_nibbles(infobuf[1]); @@ -1949,7 +1952,7 @@ else /* CD200, CD-55A */ { } - i=cmd_out(); + i=cmd_out(7); return (i); } /*==========================================================================*/ @@ -2013,7 +2016,7 @@ else /* CD200, CD-55A */ { } - i=cmd_out(); + i=cmd_out(7); if (i<0) return (i); if (fam0L_drive) { @@ -2072,7 +2075,7 @@ drvcmd[0]=CMD1_MULTISESS; response_count=6; flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check; - i=cmd_out(); + i=cmd_out(7); if (i<0) return (i); if ((infobuf[0]&0x80)!=0) { @@ -2097,7 +2100,7 @@ drvcmd[2]=1; response_count=8; flags_cmd_out=f_putcmd; - i=cmd_out(); + i=cmd_out(7); if (i<0) return (i); DriveStruct[d].lba_multi=msf2blk(make32(make16(0,infobuf[5]), make16(infobuf[6],infobuf[7]))); @@ -2142,7 +2145,7 @@ flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; cmd_type=READ_SC; DriveStruct[d].frame_size=CD_FRAMESIZE_SUB; - i=cmd_out(); /* which buffer to use? */ + i=cmd_out(7); /* which buffer to use? */ return (i); } #endif FUTURE @@ -2310,12 +2313,12 @@ DPRINTF((DBG_INI,"SBPCD: check_version entered.\n")); DriveStruct[d].drv_type=0; - /* check for CD200 and CD-55A first */ + /* check for CD200 first */ clr_cmdbuf(); drvcmd[0]=CMD2_READ_ERR; response_count=9; flags_cmd_out=f_putcmd; - i=cmd_out(); + i=cmd_out(7); if (i<0) DPRINTF((DBG_INI,"SBPCD: CMD2_READERR returns %d (ok anyway).\n",i)); /* read drive version */ clr_cmdbuf(); @@ -2329,9 +2332,30 @@ drvcmd[0]=CMD2_READ_VER; response_count=12; flags_cmd_out=f_putcmd; - i=cmd_out(); + i=cmd_out(7); if (i<0) DPRINTF((DBG_INI,"SBPCD: CMD2_READ_VER returns %d\n",i)); - else + + if (i<0) + { + /* check for CD-55A */ + clr_cmdbuf(); + drvcmd[0]=CMDT_READ_ERR; + response_count=5; + flags_cmd_out=f_putcmd; + i=cmd_out(7); + if (i<0) DPRINTF((DBG_INI,"SBPCD: CMDT_READERR returns %d (ok anyway).\n",i)); + /* read drive version */ + clr_cmdbuf(); + for (i=0;i<12;i++) infobuf[i]=0; + if (sbpro_type==1) OUT(CDo_sel_i_d,0); + response_count=12; /* may be too much */ + drvcmd[0]=CMDT_READ_VER; + drvcmd[4]=response_count; + flags_cmd_out=f_putcmd; + i=cmd_out(10); /* possibly only 6 */ + if (i<0) DPRINTF((DBG_INI,"SBPCD: CMDT_READ_VER returns %d\n",i)); + } + if (i>=0) /* either from CD200 or CD-55A */ { for (i=0, j=0;i<12;i++) j+=infobuf[i]; if (j) @@ -2341,39 +2365,35 @@ for (i=0;i<12;i++) DPRINTF((DBG_ID,"%c",infobuf[i])); DPRINTF((DBG_ID,"\"\n")); } + for (i=0;i<5;i++) if (infobuf[i]!=family2[i]) break; + if (i==5) + { + DriveStruct[d].drive_model[0]='C'; + DriveStruct[d].drive_model[1]='D'; + DriveStruct[d].drive_model[2]='2'; + DriveStruct[d].drive_model[3]='0'; + DriveStruct[d].drive_model[4]='0'; + DriveStruct[d].drive_model[5]=infobuf[i++]; + DriveStruct[d].drive_model[6]=infobuf[i++]; + DriveStruct[d].drive_model[7]=0; + DriveStruct[d].drv_type=drv_fam2; + } else { - for (i=0;i<5;i++) if (infobuf[i]!=family2[i]) break; + for (i=0;i<5;i++) if (infobuf[i]!=familyT[i]) break; if (i==5) { DriveStruct[d].drive_model[0]='C'; DriveStruct[d].drive_model[1]='D'; - DriveStruct[d].drive_model[2]='2'; - DriveStruct[d].drive_model[3]='0'; - DriveStruct[d].drive_model[4]='0'; - DriveStruct[d].drive_model[5]=infobuf[i++]; + DriveStruct[d].drive_model[2]='-'; + DriveStruct[d].drive_model[3]='5'; + DriveStruct[d].drive_model[4]='5'; + DriveStruct[d].drive_model[5]='A'; DriveStruct[d].drive_model[6]=infobuf[i++]; - DriveStruct[d].drive_model[7]=0; - DriveStruct[d].drv_type=drv_fam2; - } - else - { - printk("\n\nSBPCD: possibly CD-55A present.\n"); - for (i=0;i<5;i++) if (infobuf[i]!=familyT[i]) break; - if (i==5) - { - DriveStruct[d].drive_model[0]='C'; - DriveStruct[d].drive_model[1]='D'; - DriveStruct[d].drive_model[2]='-'; - DriveStruct[d].drive_model[3]='5'; - DriveStruct[d].drive_model[4]='5'; - DriveStruct[d].drive_model[5]='A'; - DriveStruct[d].drive_model[6]=infobuf[i++]; - DriveStruct[d].drive_model[7]=infobuf[i++]; - DriveStruct[d].drive_model[8]=0; - } - DriveStruct[d].drv_type=drv_famT; + DriveStruct[d].drive_model[7]=infobuf[i++]; + DriveStruct[d].drive_model[8]=0; } + DriveStruct[d].drv_type=drv_famT; /* assumed, not sure here */ } } @@ -2385,7 +2405,7 @@ drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */ response_count=9; flags_cmd_out=f_putcmd; - i=cmd_out(); + i=cmd_out(7); if (i<0) DPRINTF((DBG_INI,"SBPCD: CMD0_READERR returns %d (ok anyway).\n",i)); /* read drive version */ clr_cmdbuf(); @@ -2393,7 +2413,7 @@ drvcmd[0]=CMD0_READ_VER; /* same as CMD1_ and CMDL_ */ response_count=12; flags_cmd_out=f_putcmd; - i=cmd_out(); + i=cmd_out(7); if (i<0) DPRINTF((DBG_INI,"SBPCD: CMD0_READ_VER returns %d\n",i)); for (i=0, j=0;i<12;i++) j+=infobuf[i]; @@ -2488,7 +2508,8 @@ } else if (fam2_drive) { - printk("\n\nSBPCD: new drive CD200 (%s)detected.\n", DriveStruct[d].firmware_version); + printk("\n\nSBPCD: new drive CD200 (%s)detected.\n", + DriveStruct[d].firmware_version); printk("SBPCD: support is not fulfilled yet - drive gets ignored.\n"); if (j!=101) /* only 1.01 known at time */ ask_mail(); @@ -2921,7 +2942,7 @@ drvcmd[6]=pos_audio_end&0x00FF; } response_count=0; - i=cmd_out(); + i=cmd_out(7); return (i); } /*==========================================================================*/ diff -u --recursive --new-file v1.1.81/linux/drivers/block/xd.c linux/drivers/block/xd.c --- v1.1.81/linux/drivers/block/xd.c Wed Aug 31 10:12:56 1994 +++ linux/drivers/block/xd.c Mon Jan 16 07:17:35 1995 @@ -380,7 +380,7 @@ } /* xd_interrupt_handler: interrupt service routine */ -static void xd_interrupt_handler (int unused) +static void xd_interrupt_handler(int irq, struct pt_regs * regs) { if (inb(XD_STATUS) & STAT_INTERRUPT) { /* check if it was our device */ #ifdef DEBUG_OTHER diff -u --recursive --new-file v1.1.81/linux/drivers/char/atixlmouse.c linux/drivers/char/atixlmouse.c --- v1.1.81/linux/drivers/char/atixlmouse.c Wed Aug 10 20:18:48 1994 +++ linux/drivers/char/atixlmouse.c Mon Jan 16 07:17:35 1995 @@ -63,7 +63,7 @@ struct wait_queue *wait; } mouse; -void mouse_interrupt(int unused) +void mouse_interrupt(int irq, struct pt_regs * regs) { char dx, dy, buttons; diff -u --recursive --new-file v1.1.81/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c --- v1.1.81/linux/drivers/char/busmouse.c Fri Oct 28 12:54:44 1994 +++ linux/drivers/char/busmouse.c Mon Jan 16 07:17:35 1995 @@ -43,7 +43,7 @@ mouse_irq=ints[1]; } -static void mouse_interrupt(int unused) +static void mouse_interrupt(int irq, struct pt_regs *regs) { char dx, dy; unsigned char buttons; diff -u --recursive --new-file v1.1.81/linux/drivers/char/console.c linux/drivers/char/console.c --- v1.1.81/linux/drivers/char/console.c Fri Jan 13 10:12:22 1995 +++ linux/drivers/char/console.c Mon Jan 16 07:17:35 1995 @@ -97,6 +97,40 @@ #include "kbd_kern.h" #include "vt_kern.h" +#ifdef __alpha__ + +static inline void scrwritew(unsigned short val, unsigned short * addr) +{ + if ((long) addr < 0) + *addr = val; + else + writew(val, (unsigned long) addr); +} + +static inline unsigned short scrreadw(unsigned short * addr) +{ + if ((long) addr < 0) + return *addr; + return readw((unsigned long) addr); +} + +#else + +static inline void scrwritew(unsigned short val, unsigned short * addr) +{ + *addr = val; +} + +static inline unsigned short scrreadw(unsigned short * addr) +{ + return *addr; +} + +#endif + +#define writew(x,y) scrwritew((x),(y)) +#define readw(x) scrreadw(x) + #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif @@ -300,7 +334,7 @@ count /= 2; while (count) { count--; - *(addr++) = c; + writew(c, addr++); } } @@ -688,12 +722,12 @@ count = (video_num_lines-1)*video_num_columns; while (count) { count--; - *(d++) = *(s++); + writew(readw(s++),d++); } count = video_num_columns; while (count) { count--; - *(d++) = video_erase_char; + writew(video_erase_char, d++); } scr_end -= origin-video_mem_start; pos -= origin-video_mem_start; @@ -707,7 +741,7 @@ count = video_num_columns; while (count) { count--; - *(d++) = video_erase_char; + writew(video_erase_char, d++); } } set_origin(currcons); @@ -718,12 +752,12 @@ while (count) { count--; - *(d++) = *(s++); + writew(readw(s++), d++); } count = video_num_columns; while (count) { count--; - *(d++) = video_erase_char; + writew(video_erase_char, d++); } } } @@ -740,12 +774,12 @@ count = (b-t-1)*video_num_columns; while (count) { count--; - *(--d) = *(--s); + writew(readw(--s), --d); } count = video_num_columns; while (count) { count--; - *(--d) = video_erase_char; + writew(video_erase_char, --d); } has_scrolled = 1; } @@ -821,7 +855,7 @@ } while (count) { count--; - *(start++) = video_erase_char; + writew(video_erase_char, start++); } need_wrap = 0; } @@ -849,7 +883,7 @@ } while (count) { count--; - *(start++) = video_erase_char; + writew(video_erase_char, start++); } need_wrap = 0; } @@ -867,7 +901,7 @@ while (count) { count--; - *(start++) = video_erase_char; + writew(video_erase_char, start++); } need_wrap = 0; } @@ -1043,14 +1077,18 @@ } static void invert_screen(int currcons) { - unsigned char *p; + unsigned short *p; if (can_do_color) - for (p = (unsigned char *)origin+1; p < (unsigned char *)scr_end; p+=2) - *p = (*p & 0x88) | (((*p >> 4) | (*p << 4)) & 0x77); + for (p = (unsigned short *)origin; p < (unsigned short *)scr_end; p++) { + unsigned short old = readw(p); + writew((old & 0x88ff) | (((old >> 4) | (old << 4)) & 0x7700), p); + } else - for (p = (unsigned char *)origin+1; p < (unsigned char *)scr_end; p+=2) - *p ^= *p & 0x07 == 1 ? 0x70 : 0x77; + for (p = (unsigned short *)origin; p < (unsigned short *)scr_end; p++) { + unsigned short old = readw(p); + writew(old ^ ((old & 0x0700 == 0x0100) ? 0x7000 : 0x7700), p); + } } static void set_mode(int currcons, int on_off) @@ -1152,8 +1190,8 @@ unsigned short * p = (unsigned short *) pos; while (i++ < video_num_columns) { - tmp = *p; - *p = old; + tmp = readw(p); + writew(old, p); old = tmp; p++; } @@ -1172,10 +1210,10 @@ unsigned short * p = (unsigned short *) pos; while (++i < video_num_columns) { - *p = *(p+1); + writew(readw(p+1), p); p++; } - *p = video_erase_char; + writew(video_erase_char, p); need_wrap = 0; } @@ -1418,7 +1456,7 @@ } if (decim) insert_char(currcons); - *(unsigned short *) pos = (attr << 8) + tc; + writew((attr << 8) + tc, (unsigned short *) pos); if (x == video_num_columns - 1) need_wrap = decawm; else { @@ -1792,7 +1830,7 @@ if (c == 10 || c == 13) continue; } - *(unsigned short *) pos = (attr << 8) + c; + writew((attr << 8) + c, (unsigned short *) pos); if (x == video_num_columns - 1) { need_wrap = 1; continue; @@ -1965,6 +2003,7 @@ origin = video_mem_start; scr_end = video_mem_start + video_num_lines * video_size_row; gotoxy(currcons,orig_x,orig_y); + set_origin(currcons); printable = 1; printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n", can_do_color ? "colour" : "mono", diff -u --recursive --new-file v1.1.81/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c --- v1.1.81/linux/drivers/char/cyclades.c Mon Jan 9 07:22:02 1995 +++ linux/drivers/char/cyclades.c Mon Jan 16 07:17:35 1995 @@ -518,7 +518,7 @@ * while we are probing for submarines. */ static void -cy_probe(int irq) +cy_probe(int irq, struct pt_regs *regs) { cy_irq_triggered = irq; cy_triggered |= 1 << irq; @@ -530,7 +530,7 @@ received, out buffer empty, modem change, etc. */ static void -cy_interrupt(int irq) +cy_interrupt(int irq, struct pt_regs *regs) { struct tty_struct *tty; int status; diff -u --recursive --new-file v1.1.81/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- v1.1.81/linux/drivers/char/keyboard.c Wed Jan 11 21:14:26 1995 +++ linux/drivers/char/keyboard.c Mon Jan 16 13:41:14 1995 @@ -330,14 +330,14 @@ e0_keys[scancode - 128]; } -static void keyboard_interrupt(int int_pt_regs) +static void keyboard_interrupt(int irq, struct pt_regs *regs) { unsigned char scancode, keycode; static unsigned int prev_scancode = 0; /* remember E0, E1 */ char up_flag; /* 0 or 0200 */ char raw_mode; - pt_regs = (struct pt_regs *) int_pt_regs; + pt_regs = regs; send_cmd(0xAD); /* disable keyboard */ kb_wait(); if ((inb_p(0x64) & kbd_read_mask) != 0x01) @@ -1165,10 +1165,10 @@ * controller to pulse the reset-line low. We try that for a while, * and if it doesn't work, we do some other stupid things. */ +#ifdef __i386__ void hard_reset_now(void) { int i, j; - extern unsigned long pg0[1024]; sti(); /* rebooting needs to touch the page at absolute addr 0 */ @@ -1181,11 +1181,10 @@ /* nothing */; outb(0xfe,0x64); /* pulse reset low */ } -#ifdef __i386__ __asm__("\tlidt _no_idt"); -#endif } } +#endif unsigned long kbd_init(unsigned long kmem_start) { @@ -1206,6 +1205,17 @@ bh_base[KEYBOARD_BH].routine = kbd_bh; request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard"); +#ifdef __alpha__ + /* enable keyboard interrupts */ + outb(0x60,0x64); + while (inb(0x64) & 2) + /* nothing */; + outb(0x1,0x60); + while (inb(0x64) & 2) + /* nothing */; + send_data(0xf0); /* Select scan code */ + send_data(0x01); /* type 1 */ +#endif mark_bh(KEYBOARD_BH); return kmem_start; } diff -u --recursive --new-file v1.1.81/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v1.1.81/linux/drivers/char/lp.c Wed Jan 11 21:14:26 1995 +++ linux/drivers/char/lp.c Mon Jan 16 07:17:35 1995 @@ -153,7 +153,7 @@ unsigned int lp_last_call = 0; #endif -static void lp_interrupt(int irq) +static void lp_interrupt(int irq, struct pt_regs *regs) { struct lp_struct *lp = &lp_table[0]; struct lp_struct *lp_end = &lp_table[LP_NO]; diff -u --recursive --new-file v1.1.81/linux/drivers/char/msbusmouse.c linux/drivers/char/msbusmouse.c --- v1.1.81/linux/drivers/char/msbusmouse.c Wed Aug 10 20:18:48 1994 +++ linux/drivers/char/msbusmouse.c Mon Jan 16 07:17:35 1995 @@ -41,7 +41,7 @@ static struct mouse_status mouse; -static void ms_mouse_interrupt(int unused) +static void ms_mouse_interrupt(int irq, struct pt_regs * regs) { char dx, dy; unsigned char buttons; diff -u --recursive --new-file v1.1.81/linux/drivers/char/psaux.c linux/drivers/char/psaux.c --- v1.1.81/linux/drivers/char/psaux.c Thu Oct 13 14:07:07 1994 +++ linux/drivers/char/psaux.c Mon Jan 16 07:17:35 1995 @@ -192,7 +192,7 @@ * is waiting in the keyboard/aux controller. */ -static void aux_interrupt(int cpl) +static void aux_interrupt(int cpl, struct pt_regs * regs) { int head = queue->head; int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1); @@ -213,7 +213,7 @@ */ #ifdef CONFIG_82C710_MOUSE -static void qp_interrupt(int cpl) +static void qp_interrupt(int cpl, struct pt_regs * regs) { int head = queue->head; int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1); diff -u --recursive --new-file v1.1.81/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v1.1.81/linux/drivers/char/serial.c Mon Jan 9 11:24:21 1995 +++ linux/drivers/char/serial.c Mon Jan 16 07:17:36 1995 @@ -346,7 +346,7 @@ * This is the serial driver's interrupt routine while we are probing * for submarines. */ -static void rs_probe(int irq) +static void rs_probe(int irq, struct pt_regs * regs) { rs_irq_triggered = irq; rs_triggered |= 1 << irq; @@ -504,7 +504,7 @@ /* * This is the serial driver's generic interrupt routine */ -static void rs_interrupt(int irq) +static void rs_interrupt(int irq, struct pt_regs * regs) { int status; struct async_struct * info; @@ -561,7 +561,7 @@ /* * This is the serial driver's interrupt routine for a single port */ -static void rs_interrupt_single(int irq) +static void rs_interrupt_single(int irq, struct pt_regs * regs) { int status; int pass_counter = 0; @@ -603,7 +603,7 @@ /* * This is the serial driver's generic interrupt routine */ -static void rs_interrupt(int irq) +static void rs_interrupt(int irq, struct pt_regs * regs) { int status; struct async_struct * info; @@ -660,7 +660,7 @@ /* * This is the serial driver's interrupt routine for a single port */ -static void rs_interrupt_single(int irq) +static void rs_interrupt_single(int irq, struct pt_regs * regs) { int status; struct async_struct * info; @@ -759,9 +759,9 @@ serial_out(info, UART_IER, info->IER); info = info->next_port; } while (info); - rs_interrupt(i); + rs_interrupt(i, NULL); } else - rs_interrupt_single(i); + rs_interrupt_single(i, NULL); sti(); } } @@ -771,7 +771,7 @@ if (IRQ_ports[0]) { cli(); - rs_interrupt(0); + rs_interrupt(0, NULL); sti(); timer_table[RS_TIMER].expires = jiffies + IRQ_timeout[0] - 2; @@ -849,7 +849,7 @@ unsigned short ICP; unsigned long flags; int retval; - void (*handler)(int); + void (*handler)(int, struct pt_regs *); if (info->flags & ASYNC_INITIALIZED) return 0; diff -u --recursive --new-file v1.1.81/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c --- v1.1.81/linux/drivers/char/tpqic02.c Mon Jan 9 07:22:02 1995 +++ linux/drivers/char/tpqic02.c Mon Jan 16 07:17:36 1995 @@ -1795,7 +1795,7 @@ * When we are finished, set flags to indicate end, disable timer. * NOTE: This *must* be fast! */ -static void qic02_tape_interrupt(int unused) +static void qic02_tape_interrupt(int irq, struct pt_regs *regs) { int stat, r, i; diff -u --recursive --new-file v1.1.81/linux/drivers/net/3c501.c linux/drivers/net/3c501.c --- v1.1.81/linux/drivers/net/3c501.c Wed Jan 11 21:14:27 1995 +++ linux/drivers/net/3c501.c Mon Jan 16 07:17:36 1995 @@ -109,7 +109,7 @@ static int el1_probe1(struct device *dev, int ioaddr); static int el_open(struct device *dev); static int el_start_xmit(struct sk_buff *skb, struct device *dev); -static void el_interrupt(int reg_ptr); +static void el_interrupt(int irq, struct pt_regs *regs); static void el_receive(struct device *dev); static void el_reset(struct device *dev); static int el1_close(struct device *dev); @@ -396,9 +396,8 @@ /* The typical workload of the driver: Handle the ether interface interrupts. */ static void -el_interrupt(int reg_ptr) +el_interrupt(int irq, struct pt_regs *regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; int ioaddr; diff -u --recursive --new-file v1.1.81/linux/drivers/net/3c505.c linux/drivers/net/3c505.c --- v1.1.81/linux/drivers/net/3c505.c Mon Jan 9 07:22:05 1995 +++ linux/drivers/net/3c505.c Mon Jan 16 07:17:36 1995 @@ -665,12 +665,11 @@ * ******************************************************/ -static void elp_interrupt(int reg_ptr) +static void elp_interrupt(int irq, struct pt_regs *regs) { int len; int dlen; - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev; elp_device * adapter; int timeout; diff -u --recursive --new-file v1.1.81/linux/drivers/net/3c507.c linux/drivers/net/3c507.c --- v1.1.81/linux/drivers/net/3c507.c Mon Jan 9 11:24:21 1995 +++ linux/drivers/net/3c507.c Mon Jan 16 07:17:36 1995 @@ -282,7 +282,7 @@ static int el16_probe1(struct device *dev, int ioaddr); static int el16_open(struct device *dev); static int el16_send_packet(struct sk_buff *skb, struct device *dev); -static void el16_interrupt(int reg_ptr); +static void el16_interrupt(int irq, struct pt_regs *regs); static void el16_rx(struct device *dev); static int el16_close(struct device *dev); static struct enet_statistics *el16_get_stats(struct device *dev); @@ -509,9 +509,8 @@ /* The typical workload of the driver: Handle the network interface interrupts. */ static void -el16_interrupt(int reg_ptr) +el16_interrupt(int irq, struct pt_regs *regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; int ioaddr, status, boguscount = 0; diff -u --recursive --new-file v1.1.81/linux/drivers/net/3c509.c linux/drivers/net/3c509.c --- v1.1.81/linux/drivers/net/3c509.c Mon Jan 9 11:24:21 1995 +++ linux/drivers/net/3c509.c Mon Jan 16 07:17:36 1995 @@ -102,7 +102,7 @@ static ushort read_eeprom(short ioaddr, int index); static int el3_open(struct device *dev); static int el3_start_xmit(struct sk_buff *skb, struct device *dev); -static void el3_interrupt(int reg_ptr); +static void el3_interrupt(int irq, struct pt_regs *regs); static void update_stats(int addr, struct device *dev); static struct enet_statistics *el3_get_stats(struct device *dev); static int el3_rx(struct device *dev); @@ -460,9 +460,8 @@ /* The EL3 interrupt handler. */ static void -el3_interrupt(int reg_ptr) +el3_interrupt(int irq, struct pt_regs *regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); int ioaddr, status; int i = 0; diff -u --recursive --new-file v1.1.81/linux/drivers/net/8390.c linux/drivers/net/8390.c --- v1.1.81/linux/drivers/net/8390.c Mon Jan 9 07:22:05 1995 +++ linux/drivers/net/8390.c Mon Jan 16 07:17:36 1995 @@ -238,9 +238,8 @@ /* The typical workload of the driver: Handle the ether interface interrupts. */ -void ei_interrupt(int reg_ptr) +void ei_interrupt(int irq, struct pt_regs * regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); int e8390_base; int interrupts, boguscount = 0; diff -u --recursive --new-file v1.1.81/linux/drivers/net/8390.h linux/drivers/net/8390.h --- v1.1.81/linux/drivers/net/8390.h Tue Nov 22 15:40:12 1994 +++ linux/drivers/net/8390.h Mon Jan 16 07:17:36 1995 @@ -24,7 +24,7 @@ extern int ethdev_init(struct device *dev); extern void NS8390_init(struct device *dev, int startp); extern int ei_open(struct device *dev); -extern void ei_interrupt(int reg_ptr); +extern void ei_interrupt(int irq, struct pt_regs *regs); #ifndef HAVE_AUTOIRQ /* From auto_irq.c */ diff -u --recursive --new-file v1.1.81/linux/drivers/net/apricot.c linux/drivers/net/apricot.c --- v1.1.81/linux/drivers/net/apricot.c Mon Jan 9 11:24:21 1995 +++ linux/drivers/net/apricot.c Mon Jan 16 07:17:36 1995 @@ -186,7 +186,7 @@ static int i596_open(struct device *dev); static int i596_start_xmit(struct sk_buff *skb, struct device *dev); -static void i596_interrupt(int reg_ptr); +static void i596_interrupt(int irq, struct pt_regs *regs); static int i596_close(struct device *dev); static struct enet_statistics *i596_get_stats(struct device *dev); static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd); @@ -751,9 +751,8 @@ } static void -i596_interrupt(int reg_ptr) +i596_interrupt(int irq, struct pt_regs *regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); struct i596_private *lp; short ioaddr; diff -u --recursive --new-file v1.1.81/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c --- v1.1.81/linux/drivers/net/arcnet.c Fri Jan 13 16:57:04 1995 +++ linux/drivers/net/arcnet.c Mon Jan 16 07:17:36 1995 @@ -310,7 +310,7 @@ static int arcnet_tx(struct device *dev,struct ClientData *hdr,short length, char *data); -static void arcnet_interrupt(int reg_ptr); +static void arcnet_interrupt(int irq, struct pt_regs *regs); static void arcnet_inthandler(struct device *dev); static void arcnet_rx(struct device *dev,int recbuf); @@ -1086,9 +1086,8 @@ /* The typical workload of the driver: Handle the network interface interrupts. */ static void -arcnet_interrupt(int reg_ptr) +arcnet_interrupt(int irq, struct pt_regs *regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); if (dev == NULL) { diff -u --recursive --new-file v1.1.81/linux/drivers/net/at1700.c linux/drivers/net/at1700.c --- v1.1.81/linux/drivers/net/at1700.c Mon Jan 9 11:24:21 1995 +++ linux/drivers/net/at1700.c Mon Jan 16 07:17:36 1995 @@ -120,7 +120,7 @@ static int read_eeprom(int ioaddr, int location); static int net_open(struct device *dev); static int net_send_packet(struct sk_buff *skb, struct device *dev); -static void net_interrupt(int reg_ptr); +static void net_interrupt(int irq, struct pt_regs *regs); static void net_rx(struct device *dev); static int net_close(struct device *dev); static struct enet_statistics *net_get_stats(struct device *dev); @@ -435,9 +435,8 @@ /* The typical workload of the driver: Handle the network interface interrupts. */ static void -net_interrupt(int reg_ptr) +net_interrupt(int irq, struct pt_regs *regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; int ioaddr, status; diff -u --recursive --new-file v1.1.81/linux/drivers/net/atp.c linux/drivers/net/atp.c --- v1.1.81/linux/drivers/net/atp.c Wed Jan 11 21:14:27 1995 +++ linux/drivers/net/atp.c Mon Jan 16 07:17:36 1995 @@ -137,7 +137,7 @@ static void write_packet(short ioaddr, int length, unsigned char *packet, int mode); static void trigger_send(short ioaddr, int length); static int net_send_packet(struct sk_buff *skb, struct device *dev); -static void net_interrupt(int reg_ptr); +static void net_interrupt(int irq, struct pt_regs *regs); static void net_rx(struct device *dev); static void read_block(short ioaddr, int length, unsigned char *buffer, int data_mode); static int net_close(struct device *dev); @@ -478,9 +478,8 @@ /* The typical workload of the driver: Handle the network interface interrupts. */ static void -net_interrupt(int reg_ptr) +net_interrupt(int irq, struct pt_regs * regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; int ioaddr, status, boguscount = 20; diff -u --recursive --new-file v1.1.81/linux/drivers/net/auto_irq.c linux/drivers/net/auto_irq.c --- v1.1.81/linux/drivers/net/auto_irq.c Mon Jan 9 07:22:05 1995 +++ linux/drivers/net/auto_irq.c Mon Jan 16 07:17:36 1995 @@ -50,7 +50,7 @@ static volatile int irq_bitmap; /* The irqs we actually found. */ static int irq_handled; /* The irq lines we have a handler on. */ -static void autoirq_probe(int irq) +static void autoirq_probe(int irq, struct pt_regs * regs) { irq_number = irq; set_bit(irq, (void *)&irq_bitmap); /* irq_bitmap |= 1 << irq; */ diff -u --recursive --new-file v1.1.81/linux/drivers/net/de600.c linux/drivers/net/de600.c --- v1.1.81/linux/drivers/net/de600.c Mon Jan 9 07:22:05 1995 +++ linux/drivers/net/de600.c Mon Jan 16 07:17:36 1995 @@ -249,7 +249,7 @@ static int de600_start_xmit(struct sk_buff *skb, struct device *dev); /* Dispatch from interrupts. */ -static void de600_interrupt(int reg_ptr); +static void de600_interrupt(int irq, struct pt_regs *regs); static int de600_tx_intr(struct device *dev, int irq_status); static void de600_rx_intr(struct device *dev); @@ -495,9 +495,8 @@ * Handle the network interface interrupts. */ static void -de600_interrupt(int reg_ptr) +de600_interrupt(int irq, struct pt_regs * regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = irq2dev_map[irq]; byte irq_status; int retrig = 0; diff -u --recursive --new-file v1.1.81/linux/drivers/net/de620.c linux/drivers/net/de620.c --- v1.1.81/linux/drivers/net/de620.c Mon Jan 9 07:22:05 1995 +++ linux/drivers/net/de620.c Mon Jan 16 07:17:36 1995 @@ -175,7 +175,7 @@ static int de620_start_xmit(struct sk_buff *, struct device *); /* Dispatch from interrupts. */ -static void de620_interrupt(int); +static void de620_interrupt(int, struct pt_regs *); static int de620_rx_intr(struct device *); /* Initialization */ @@ -565,9 +565,8 @@ * */ static void -de620_interrupt(int reg_ptr) +de620_interrupt(int irq, struct pt_regs *regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = irq2dev_map[irq]; byte irq_status; int bogus_count = 0; diff -u --recursive --new-file v1.1.81/linux/drivers/net/depca.c linux/drivers/net/depca.c --- v1.1.81/linux/drivers/net/depca.c Mon Jan 9 11:24:21 1995 +++ linux/drivers/net/depca.c Mon Jan 16 07:17:36 1995 @@ -321,7 +321,7 @@ */ static int depca_open(struct device *dev); static int depca_start_xmit(struct sk_buff *skb, struct device *dev); -static void depca_interrupt(int reg_ptr); +static void depca_interrupt(int irq, struct pt_regs * regs); static int depca_close(struct device *dev); static struct enet_statistics *depca_get_stats(struct device *dev); #ifdef HAVE_MULTICAST @@ -955,9 +955,8 @@ ** The DEPCA interrupt handler. */ static void -depca_interrupt(int reg_ptr) +depca_interrupt(int irq, struct pt_regs * regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); struct depca_private *lp; int csr0, ioaddr, nicsr; diff -u --recursive --new-file v1.1.81/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c --- v1.1.81/linux/drivers/net/eexpress.c Mon Jan 9 11:24:21 1995 +++ linux/drivers/net/eexpress.c Mon Jan 16 07:17:36 1995 @@ -290,7 +290,7 @@ static int eexp_probe1(struct device *dev, short ioaddr); static int eexp_open(struct device *dev); static int eexp_send_packet(struct sk_buff *skb, struct device *dev); -static void eexp_interrupt(int reg_ptr); +static void eexp_interrupt(int irq, struct pt_regs *regs); static void eexp_rx(struct device *dev); static int eexp_close(struct device *dev); static struct enet_statistics *eexp_get_stats(struct device *dev); @@ -515,9 +515,8 @@ /* The typical workload of the driver: Handle the network interface interrupts. */ static void -eexp_interrupt(int reg_ptr) +eexp_interrupt(int irq, struct pt_regs *regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; int ioaddr, status, boguscount = 0; diff -u --recursive --new-file v1.1.81/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c --- v1.1.81/linux/drivers/net/ewrk3.c Mon Jan 9 11:24:21 1995 +++ linux/drivers/net/ewrk3.c Mon Jan 16 07:17:36 1995 @@ -289,7 +289,7 @@ */ static int ewrk3_open(struct device *dev); static int ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev); -static void ewrk3_interrupt(int reg_ptr); +static void ewrk3_interrupt(int irq, struct pt_regs *regs); static int ewrk3_close(struct device *dev); static struct enet_statistics *ewrk3_get_stats(struct device *dev); static void set_multicast_list(struct device *dev, int num_addrs, void *addrs); @@ -904,9 +904,8 @@ ** The EWRK3 interrupt handler. */ static void -ewrk3_interrupt(int reg_ptr) +ewrk3_interrupt(int irq, struct pt_regs * regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); struct ewrk3_private *lp; int iobase; diff -u --recursive --new-file v1.1.81/linux/drivers/net/lance.c linux/drivers/net/lance.c --- v1.1.81/linux/drivers/net/lance.c Mon Jan 9 11:24:22 1995 +++ linux/drivers/net/lance.c Mon Jan 16 07:17:36 1995 @@ -235,7 +235,7 @@ static void lance_init_ring(struct device *dev); static int lance_start_xmit(struct sk_buff *skb, struct device *dev); static int lance_rx(struct device *dev); -static void lance_interrupt(int reg_ptr); +static void lance_interrupt(int irq, struct pt_regs *regs); static int lance_close(struct device *dev); static struct enet_statistics *lance_get_stats(struct device *dev); #ifdef HAVE_MULTICAST @@ -750,9 +750,8 @@ /* The LANCE interrupt handler. */ static void -lance_interrupt(int reg_ptr) +lance_interrupt(int irq, struct pt_regs * regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); struct lance_private *lp; int csr0, ioaddr, boguscnt=10; diff -u --recursive --new-file v1.1.81/linux/drivers/net/ni52.c linux/drivers/net/ni52.c --- v1.1.81/linux/drivers/net/ni52.c Wed Jan 11 21:14:27 1995 +++ linux/drivers/net/ni52.c Mon Jan 16 07:17:36 1995 @@ -190,7 +190,7 @@ #define NI52_ADDR2 0x01 static int ni52_probe1(struct device *dev,int ioaddr); -static void ni52_interrupt(int reg_ptr); +static void ni52_interrupt(int irq, struct pt_regs *regs); static int ni52_open(struct device *dev); static int ni52_close(struct device *dev); static int ni52_send_packet(struct sk_buff *,struct device *); @@ -713,9 +713,9 @@ * Interrupt Handler ... */ -static void ni52_interrupt(int reg_ptr) +static void ni52_interrupt(int irq, struct pt_regs *regs) { - struct device *dev = (struct device *) irq2dev_map[-((struct pt_regs *)reg_ptr)->orig_eax-2]; + struct device *dev = (struct device *) irq2dev_map[irq]; unsigned short stat; int pd = 0; struct priv *p; @@ -725,7 +725,7 @@ #endif if (dev == NULL) { - printk ("ni52-interrupt: irq %d for unknown device.\n",(int) -(((struct pt_regs *)reg_ptr)->orig_eax+2)); + printk ("ni52-interrupt: irq %d for unknown device.\n", irq); return; } p = (struct priv *) dev->priv; diff -u --recursive --new-file v1.1.81/linux/drivers/net/ni65.c linux/drivers/net/ni65.c --- v1.1.81/linux/drivers/net/ni65.c Wed Jan 11 21:14:27 1995 +++ linux/drivers/net/ni65.c Mon Jan 16 07:17:36 1995 @@ -112,7 +112,7 @@ #define writedatareg(val) {outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);} static int ni65_probe1(struct device *dev,int); -static void ni65_interrupt(int reg_ptr); +static void ni65_interrupt(int irq, struct pt_regs *regs); static void recv_intr(struct device *dev); static void xmit_intr(struct device *dev); static int ni65_open(struct device *dev); @@ -397,9 +397,8 @@ * interrupt handler */ -static void ni65_interrupt(int reg_ptr) +static void ni65_interrupt(int irq, struct pt_regs * regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); int csr0; struct device *dev = (struct device *) irq2dev_map[irq]; diff -u --recursive --new-file v1.1.81/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v1.1.81/linux/drivers/net/plip.c Mon Jan 9 11:24:22 1995 +++ linux/drivers/net/plip.c Mon Jan 16 07:17:36 1995 @@ -179,7 +179,7 @@ /* Routines used internally. */ static void plip_device_clear(struct device *dev); -static void plip_interrupt(int reg_ptr); +static void plip_interrupt(int irq, struct pt_regs *regs); static int plip_error(struct device *dev); static int plip_receive_packet(struct device *dev); @@ -688,9 +688,8 @@ /* Handle the parallel port interrupts. */ static void -plip_interrupt(int reg_ptr) +plip_interrupt(int irq, struct pt_regs * regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *) irq2dev_map[irq]; struct net_local *nl = (struct net_local *)dev->priv; struct plip_local *rcv = &nl->rcv_data; diff -u --recursive --new-file v1.1.81/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c --- v1.1.81/linux/drivers/net/sk_g16.c Wed Jan 11 21:14:27 1995 +++ linux/drivers/net/sk_g16.c Mon Jan 16 07:17:36 1995 @@ -487,7 +487,7 @@ static int SK_open(struct device *dev); static int SK_send_packet(struct sk_buff *skb, struct device *dev); -static void SK_interrupt(int reg_ptr); +static void SK_interrupt(int irq, struct pt_regs * regs); static void SK_rxintr(struct device *dev); static void SK_txintr(struct device *dev); static int SK_close(struct device *dev); @@ -1300,7 +1300,7 @@ * Description : SK_G16 interrupt handler which checks for LANCE * Errors, handles transmit and receive interrupts * - * Parameters : I : int reg_ptr - + * Parameters : I : int irq, struct pt_regs * regs - * Return Value : None * Errors : None * Globals : None @@ -1309,9 +1309,8 @@ * YY/MM/DD uid Description -*/ -static void SK_interrupt(int reg_ptr) +static void SK_interrupt(int irq, struct pt_regs * regs) { - int irq = - (((struct pt_regs *)reg_ptr)->orig_eax+2); int csr0; struct device *dev = (struct device *) irq2dev_map[irq]; struct priv *p = (struct priv *) dev->priv; diff -u --recursive --new-file v1.1.81/linux/drivers/net/skeleton.c linux/drivers/net/skeleton.c --- v1.1.81/linux/drivers/net/skeleton.c Mon Jan 9 11:24:22 1995 +++ linux/drivers/net/skeleton.c Mon Jan 16 07:17:36 1995 @@ -97,7 +97,7 @@ static int netcard_probe1(struct device *dev, int ioaddr); static int net_open(struct device *dev); static int net_send_packet(struct sk_buff *skb, struct device *dev); -static void net_interrupt(int reg_ptr); +static void net_interrupt(int irq, struct pt_regs *regs); static void net_rx(struct device *dev); static int net_close(struct device *dev); static struct enet_statistics *net_get_stats(struct device *dev); @@ -355,9 +355,8 @@ /* The typical workload of the driver: Handle the network interface interrupts. */ static void -net_interrupt(int reg_ptr) +net_interrupt(int irq, struct pt_regs * regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; int ioaddr, status, boguscount = 0; diff -u --recursive --new-file v1.1.81/linux/drivers/net/znet.c linux/drivers/net/znet.c --- v1.1.81/linux/drivers/net/znet.c Mon Jan 9 07:22:06 1995 +++ linux/drivers/net/znet.c Mon Jan 16 07:17:36 1995 @@ -182,7 +182,7 @@ int znet_probe(struct device *dev); static int znet_open(struct device *dev); static int znet_send_packet(struct sk_buff *skb, struct device *dev); -static void znet_interrupt(int reg_ptr); +static void znet_interrupt(int irq, struct pt_regs *regs); static void znet_rx(struct device *dev); static int znet_close(struct device *dev); static struct enet_statistics *net_get_stats(struct device *dev); @@ -402,9 +402,8 @@ } /* The ZNET interrupt handler. */ -static void znet_interrupt(int reg_ptr) +static void znet_interrupt(int irq, struct pt_regs * regs) { - int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); struct device *dev = irq2dev_map[irq]; int ioaddr; int boguscnt = 20; diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c --- v1.1.81/linux/drivers/scsi/53c7,8xx.c Mon Jan 9 07:22:06 1995 +++ linux/drivers/scsi/53c7,8xx.c Mon Jan 16 07:17:37 1995 @@ -175,7 +175,7 @@ static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result); static int NCR53c8xx_run_tests (struct Scsi_Host *host); static int NCR53c8xx_script_len; -static void NCR53c7x0_intr (int irq); +static void NCR53c7x0_intr(int irq, struct pt_regs * regs); static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd); static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd); @@ -2927,7 +2927,7 @@ } /* - * Function : static void NCR53c7x0_intr (int irq) + * Function : static void NCR53c7x0_intr (int irq, struct pt_regs * regs) * * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing * the same IRQ line. @@ -2937,7 +2937,7 @@ * this handler. */ -static void NCR53c7x0_intr (int irq) { +static void NCR53c7x0_intr (int irq, struct pt_regs * regs) { NCR53c7x0_local_declare(); struct Scsi_Host *host; /* Host we are looking at */ unsigned char istat; /* Values of interrupt regs */ diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/ChangeLog linux/drivers/scsi/ChangeLog --- v1.1.81/linux/drivers/scsi/ChangeLog Fri Jan 13 16:57:04 1995 +++ linux/drivers/scsi/ChangeLog Sun Jan 15 00:54:27 1995 @@ -128,7 +128,7 @@ * hosts.c: Spelling. - * qlogic.c: Update to version 0.38a. Add more support for PCMIA. + * qlogic.c: Update to version 0.38a. Add more support for PCMCIA. * scsi.c: Mask device type with 0x1f during scan_scsis. Add support for deadlocking, err, make that getting out of diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c --- v1.1.81/linux/drivers/scsi/NCR5380.c Tue Nov 29 10:07:13 1994 +++ linux/drivers/scsi/NCR5380.c Mon Jan 16 07:17:37 1995 @@ -600,8 +600,8 @@ static int probe_irq; -static void probe_intr (int sig) { - probe_irq = sig; +static void probe_intr (int irq, struct pt_regs * regs) { + probe_irq = irq; }; static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible) { diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/README.st linux/drivers/scsi/README.st --- v1.1.81/linux/drivers/scsi/README.st Fri Jan 13 16:57:04 1995 +++ linux/drivers/scsi/README.st Sun Jan 15 00:54:27 1995 @@ -146,7 +146,7 @@ The MTEOM command is by default implemented as spacing over 32767 filemarks. With this method the file number in the status is correct. The user can request using direct spacing to EOD by setting -ST_FAST_EOM 1 (or using the MTSTOPTIONS ioctl). In this case the file +ST_FAST_EOM 1 (or using the MT_ST_OPTIONS ioctl). In this case the file number will be invalid. When using read ahead or buffered writes the position within the file diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c --- v1.1.81/linux/drivers/scsi/aha152x.c Mon Jan 9 11:24:22 1995 +++ linux/drivers/scsi/aha152x.c Mon Jan 16 12:47:35 1995 @@ -313,7 +313,7 @@ static int aborting=0, abortion_complete=0, abort_result; -void aha152x_intr( int irqno ); +void aha152x_intr( int irq, struct pt_regs * ); void aha152x_done( int error ); void aha152x_setup( char *str, int *ints ); @@ -1163,7 +1163,7 @@ /* * Interrupts handler (main routine of the driver) */ -void aha152x_intr( int irqno ) +void aha152x_intr( int irqno, struct pt_regs * regs ) { int done=0, phase; diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c --- v1.1.81/linux/drivers/scsi/aha1542.c Mon Jan 9 11:24:22 1995 +++ linux/drivers/scsi/aha1542.c Mon Jan 16 07:17:37 1995 @@ -345,7 +345,7 @@ } /* A "high" level interrupt handler */ -static void aha1542_intr_handle(int foo) +static void aha1542_intr_handle(int irq, struct pt_regs *regs) { void (*my_done)(Scsi_Cmnd *) = NULL; int errstatus, mbi, mbo, mbistatus; @@ -353,16 +353,12 @@ unsigned int flags; struct Scsi_Host * shost; Scsi_Cmnd * SCtmp; - int irqno, * irqp, flag; + int flag; int needs_restart; struct mailbox * mb; struct ccb *ccb; - irqp = (int *) foo; - irqp -= 2; /* Magic - this is only required for slow interrupt handlers */ - irqno = *irqp; - - shost = aha_host[irqno - 9]; + shost = aha_host[irq - 9]; if(!shost) panic("Splunge!"); mb = HOSTDATA(shost)->mb; diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c --- v1.1.81/linux/drivers/scsi/aha1740.c Mon Jan 9 11:24:22 1995 +++ linux/drivers/scsi/aha1740.c Mon Jan 16 07:17:37 1995 @@ -164,7 +164,7 @@ } /* A "high" level interrupt handler */ -void aha1740_intr_handle(int foo) +void aha1740_intr_handle(int irq, struct pt_regs * regs) { void (*my_done)(Scsi_Cmnd *); int errstatus, adapstat; diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/aha274x.c linux/drivers/scsi/aha274x.c --- v1.1.81/linux/drivers/scsi/aha274x.c Tue Nov 29 10:07:14 1994 +++ linux/drivers/scsi/aha274x.c Mon Jan 16 07:17:37 1995 @@ -188,14 +188,14 @@ short rate; char *english; } aha274x_synctab[] = { - 100, 0, "10.0", - 125, 1, "8.0", - 150, 2, "6.67", - 175, 3, "5.7", - 200, 4, "5.0", - 225, 5, "4.4", - 250, 6, "4.0", - 275, 7, "3.6" + {100, 0, "10.0"}, + {125, 1, "8.0"}, + {150, 2, "6.67"}, + {175, 3, "5.7"}, + {200, 4, "5.0"}, + {225, 5, "4.4"}, + {250, 6, "4.0"}, + {275, 7, "3.6"} }; static int aha274x_synctab_max = @@ -322,8 +322,8 @@ char *name; int *flag; } options[] = { - "extended", &aha274x_extended, - NULL + {"extended", &aha274x_extended}, + {NULL, NULL } }; for (p = strtok(s, ","); p; p = strtok(NULL, ",")) { @@ -456,7 +456,7 @@ * be disabled all through this function unless we say otherwise. */ static -void aha274x_isr(int irq) +void aha274x_isr(int irq, struct pt_regs * regs) { int base, intstat; struct aha274x_host *p; @@ -745,9 +745,9 @@ unsigned char signature[sizeof(buf)]; enum aha_type type; } S[] = { - 4, { 0x04, 0x90, 0x77, 0x71 }, T_274X, /* host adapter 274x */ - 4, { 0x04, 0x90, 0x77, 0x70 }, T_274X, /* motherboard 274x */ - 4, { 0x04, 0x90, 0x77, 0x56 }, T_284X, /* 284x, BIOS enabled */ + {4, { 0x04, 0x90, 0x77, 0x71 }, T_274X}, /* host adapter 274x */ + {4, { 0x04, 0x90, 0x77, 0x70 }, T_274X}, /* motherboard 274x */ + {4, { 0x04, 0x90, 0x77, 0x56 }, T_284X}, /* 284x, BIOS enabled */ }; for (i = 0; i < sizeof(buf); i++) { @@ -887,7 +887,7 @@ /* * Lock out other contenders for our i/o space. */ - snarf_region(O_MINREG(base), O_MAXREG(base)-O_MINREG(base)); + request_region(O_MINREG(base), O_MAXREG(base)-O_MINREG(base), "aha27x"); /* * Any card-type-specific adjustments before we register diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/buslogic.c linux/drivers/scsi/buslogic.c --- v1.1.81/linux/drivers/scsi/buslogic.c Mon Jan 9 11:24:22 1995 +++ linux/drivers/scsi/buslogic.c Mon Jan 16 07:17:37 1995 @@ -422,7 +422,7 @@ } /* A "high" level interrupt handler. */ -static void buslogic_interrupt(int junk) +static void buslogic_interrupt(int irq, struct pt_regs * regs) { void (*my_done)(Scsi_Cmnd *) = NULL; int errstatus, mbistatus = MBX_NOT_IN_USE, number_serviced, found; @@ -430,15 +430,12 @@ struct Scsi_Host *shpnt; Scsi_Cmnd *sctmp; unsigned long flags; - int irqno, base, flag; + int base, flag; int needs_restart; struct mailbox *mb; struct ccb *ccb; - /* Magic - this -2 is only required for slow interrupt handlers */ - irqno = ((int *)junk)[-2]; - - shpnt = host[irqno - 9]; + shpnt = host[irq - 9]; if (!shpnt) panic("buslogic_interrupt: NULL SCSI host entry"); diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c --- v1.1.81/linux/drivers/scsi/eata.c Mon Jan 9 11:24:22 1995 +++ linux/drivers/scsi/eata.c Mon Jan 16 13:31:06 1995 @@ -1,6 +1,11 @@ /* * eata.c - Low-level driver for EATA/DMA SCSI host adapters. * + * 16 Jan 1995 rev. 1.12 for linux 1.1.81 + * Fix mscp structure comments (no functional change). + * Display a message if check_region detects a port address + * already in use. + * * 17 Dec 1994 rev. 1.11 for linux 1.1.74 * Use the scsicam_bios_param routine. This allows an easy * migration path from disk partition tables created using @@ -196,11 +201,11 @@ /* MailBox SCSI Command Packet */ struct mscp { unchar sreset:1, /* SCSI Bus Reset Signal should be asserted */ - interp:1, /* The controller interprets cp, not the target */ + init:1, /* Re-initialize controller and self test */ reqsen:1, /* Transfer Request Sense Data to addr using DMA */ sg:1, /* Use Scatter/Gather */ :1, - init:1, /* Re-initialize controller and self test */ + interp:1, /* The controller interprets cp, not the target */ dout:1, /* Direction of Transfer is Out (Host to Target) */ din:1; /* Direction of Transfer is In (Target to Host) */ unchar sense_len; /* Request Sense Length */ @@ -251,7 +256,7 @@ #define HD(board) ((struct hostdata *) &sh[board]->hostdata) #define BN(board) (HD(board)->board_name) -static void eata_interrupt_handler(int); +static void eata_interrupt_handler(int, struct pt_regs *); static int do_trace = FALSE; static inline unchar wait_on_busy(ushort iobase) { @@ -308,7 +313,11 @@ sprintf(name, "%s%d", driver_name, j); - if(check_region(*port_base, REG_REGION)) return FALSE; + if(check_region(*port_base, REG_REGION)) { + printk("%s: address 0x%03x already in use, detaching.\n", + name, *port_base); + return FALSE; + } if (do_dma(*port_base, 0, READ_CONFIG_PIO)) return FALSE; @@ -385,7 +394,7 @@ sh[j]->cmd_per_lun = MAX_CMD_PER_LUN; /* Register the I/O space that we use */ - request_region(sh[j]->io_port, REG_REGION,"eata"); + request_region(sh[j]->io_port, REG_REGION, driver_name); memset(HD(j), 0, sizeof(struct hostdata)); HD(j)->subversion = subversion; @@ -746,7 +755,7 @@ } } -static void eata_interrupt_handler(int irq) { +static void eata_interrupt_handler(int irq, struct pt_regs * regs) { Scsi_Cmnd *SCpnt; unsigned int i, j, k, flags, status, loops, total_loops = 0; struct mssp *spp; diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/eata.h linux/drivers/scsi/eata.h --- v1.1.81/linux/drivers/scsi/eata.h Tue Dec 20 10:23:14 1994 +++ linux/drivers/scsi/eata.h Mon Jan 16 13:31:06 1995 @@ -7,7 +7,7 @@ #include -#define EATA_VERSION "1.11.00" +#define EATA_VERSION "1.12.00" int eata_detect(Scsi_Host_Template *); int eata_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c --- v1.1.81/linux/drivers/scsi/eata_dma.c Fri Jan 13 16:57:05 1995 +++ linux/drivers/scsi/eata_dma.c Mon Jan 16 07:17:37 1995 @@ -40,9 +40,9 @@ * support I need. * * * * Thanks also to Greg Hosler who did a lot of testing and * - * found quite a number of bugs during the devellopment. * + * found quite a number of bugs during the development. * ************************************************************ - * last change: 95/01/08 * + * last change: 95/01/15 * ************************************************************/ /* Look in eata_dma.h for configuration information */ @@ -87,7 +87,7 @@ return information; } -void eata_int_handler(int irq) +void eata_int_handler(int irq, struct pt_regs * regs) { uint i, result; uint hba_stat, scsi_stat, eata_stat; @@ -163,7 +163,7 @@ HD(cmd)->t_timeout[cmd->target] = 0; break; case 0x01: /* Selection Timeout */ - result = DID_BAD_TARGET << 16; /* These two lines are new */ + result = DID_BAD_TARGET << 16; break; case 0x02: /* Command Timeout */ if (HD(cmd)->t_timeout[cmd->target] > 1) @@ -516,6 +516,41 @@ } } + +char * get_board_data(ulong base, uint irq, uint id) +{ + struct eata_ccb cp; + struct eata_sp sp; + static char buff[256]; + + memset(&cp, 0, sizeof(struct eata_ccb)); + memset(buff, 0, sizeof(buff)); + + cp.DataIn = TRUE; + cp.Interpret = TRUE; /* Interpret command */ + + cp.cp_datalen = htonl(255); + cp.cp_dataDMA = htonl((long)buff); + + cp.cp_id = id; + cp.cp_lun = 0; + + cp.cp_cdb[0] = INQUIRY; + cp.cp_cdb[1] = 0; + cp.cp_cdb[2] = 0; + cp.cp_cdb[3] = 0; + cp.cp_cdb[4] = 255; + cp.cp_cdb[5] = 0; + + cp.cp_statDMA = htonl((ulong) &sp); + + eata_send_command((ulong) &cp, (uint) base, EATA_CMD_DMA_SEND_CP); + while (!(inb(base + HA_RAUXSTAT) & HA_AIRQ)); + inb((uint) base + HA_RSTATUS); + + return (buff); +} + int check_blink_state(long base) { uint ret = 0; @@ -602,13 +637,11 @@ { ulong size = 0; unchar dma_channel = 0; + char *buff; uint i; struct Scsi_Host *sh; hostdata *hd; - printk("EATA compliant HBA detected. EATA Level %x\n", - (uint) (gc->version)); - DBG(DBG_REGISTER, print_config(gc)); if (!gc->DMA_support) { @@ -648,7 +681,6 @@ reg_IRQ[gc->IRQ]++; } - request_region(base, 9, "eata_dma"); if(gc->HAA_valid == FALSE) gc->MAX_CHAN = 0; @@ -660,6 +692,13 @@ printk("Warning: Queue size had to be corrected.\n" "This might be a PM2012 with a defective Firmware\n"); } + + buff = get_board_data((uint)base, gc->IRQ, gc->scsi_id[3]); + + if(!(strncmp("PM2322", &buff[16], 6) || strncmp("PM3021", &buff[16], 6) + || strncmp("PM3222", &buff[16], 6) || strncmp("PM3224", &buff[16], 6))) + gc->MAX_CHAN = 0; + if (gc->MAX_CHAN) { printk("This is a multichannel HBA. Linux doesn't support them,\n"); printk("so we'll try to register every channel as a virtual HBA.\n"); @@ -673,6 +712,17 @@ memset(hd->ccb, 0, (sizeof(struct eata_ccb) * ntohs(gc->queuesiz)) / (gc->MAX_CHAN + 1)); + strncpy(SD(sh)->vendor, &buff[8], 8); + SD(sh)->vendor[8] = 0; + strncpy(SD(sh)->name, &buff[16], 17); + SD(sh)->name[17] = 0; + SD(sh)->revision[0] = buff[32]; + SD(sh)->revision[1] = buff[33]; + SD(sh)->revision[2] = buff[34]; + SD(sh)->revision[3] = '.'; + SD(sh)->revision[4] = buff[35]; + SD(sh)->revision[5] = 0; + sh->base = (char *) base; sh->irq = gc->IRQ; sh->dma_channel = dma_channel; @@ -697,9 +747,9 @@ hd->channel = i; - if (gc->is_PCI) + if (buff[21] == '4') hd->bustype = 'P'; - else if (gc->is_EISA) + else if (buff[21] == '2') hd->bustype = 'E'; else hd->bustype = 'I'; @@ -788,7 +838,7 @@ return ((long)base); } else { EISAbases[i] = 0; - printk("No vaild IRQ. HBA removed from list\n"); + printk("No valid IRQ. HBA removed from list\n"); } } else /* Nothing found here so we take it from the list */ @@ -870,7 +920,7 @@ if (!(error = pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_0, &base))) { - /* Check if the address is vaild */ + /* Check if the address is valid */ if (base & 0x01) { base &= 0xfffffffe; /* EISA tag there ? */ @@ -963,13 +1013,18 @@ for (i = 1; i < registered_HBAs; i++) HBA_ptr = SD(HBA_ptr)->prev; - printk("\nRegistered HBAs:\n"); - printk(" # Type: BaseIO: IRQ: Chan: ID: Prim: QS: SG: CPL:\n"); + printk("Registered HBAs:\n"); + printk("HBA no. VID: Boardtype: Revis: Bus: BaseIO: IRQ: Chan: ID: Prim: QS: SG: CPL:\n"); for (i = 1; i <= registered_HBAs; i++) { - printk("%2d %c 0x%04x %2d %d %d %d %2d %2d %2d\n", - i, SD(HBA_ptr)->bustype, (uint) HBA_ptr->base, HBA_ptr->irq, - SD(HBA_ptr)->channel, HBA_ptr->this_id, SD(HBA_ptr)->primary, - HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun); + printk("scsi%-2d: %.4s %.11s v%s ", HBA_ptr->host_no, + SD(HBA_ptr)->vendor, SD(HBA_ptr)->name, SD(HBA_ptr)->revision); + if(SD(HBA_ptr)->bustype == 'P') printk("PCI "); + else if(SD(HBA_ptr)->bustype == 'E') printk("EISA"); + else printk(" ISA"); + printk(" 0x%04x %2d %d %d %d %2d %2d %2d\n", + (uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, + HBA_ptr->this_id, SD(HBA_ptr)->primary, HBA_ptr->can_queue, + HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun); HBA_ptr = SD(HBA_ptr)->next; } DBG(DPT_DEBUG,DELAY(1200)); diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/eata_dma.h linux/drivers/scsi/eata_dma.h --- v1.1.81/linux/drivers/scsi/eata_dma.h Fri Jan 13 16:57:05 1995 +++ linux/drivers/scsi/eata_dma.h Sun Jan 15 21:44:00 1995 @@ -2,7 +2,7 @@ * Header file for eata_dma.c Linux EATA-DMA SCSI driver * * (c) 1993,94,95 Michael Neuffer * ********************************************************* -* last change: 94/01/08 * +* last change: 95/01/15 * ********************************************************/ @@ -16,7 +16,7 @@ #define VER_MAJOR 2 #define VER_MINOR 1 -#define VER_SUB "0f" +#define VER_SUB "0g" /************************************************************************ * Here you can configure your drives that are using a non-standard * @@ -76,7 +76,7 @@ #define EATA_DMA { \ NULL, NULL, \ - "EATA (Extended Attachment) driver\n", \ + "EATA (Extended Attachment) driver", \ eata_detect, \ NULL, \ eata_info, \ @@ -192,9 +192,9 @@ struct reg_bit { /* reading this one will clear the interrupt */ unchar error:1; /* previous command ended in an error */ - unchar more:1; /* more DATA comming soon, poll BSY & DRQ (PIO) */ + unchar more:1; /* more DATA coming soon, poll BSY & DRQ (PIO) */ unchar corr:1; /* data read was successfully corrected with ECC*/ - unchar drq:1; /* data request aktive */ + unchar drq:1; /* data request active */ unchar sc:1; /* seek complete */ unchar fault:1; /* write fault */ unchar ready:1; /* drive ready */ @@ -332,6 +332,9 @@ }; typedef struct hstd{ + char vendor[9]; + char name[18]; + char revision[6]; unchar bustype; /* bustype of HBA */ unchar channel; /* no. of scsi channel */ unchar state; /* state of HBA */ @@ -363,5 +366,26 @@ int bios_drives; /* number of emulated drives */ struct drive_geom_emul drv[2]; /* drive structures */ }; + +struct lun_map { + unchar id:5, + chan:3; + unchar lun; +}; + +typedef struct emul_pp { + unchar p_code:6, + null:1, + p_save:1; + unchar p_lenght; + ushort cylinder; + unchar heads; + unchar sectors; + unchar null2; + unchar s_lunmap:4, + ems:1; + ushort drive_type; /* In Little Endian ! */ + struct lun_map lunmap[4]; +}emulpp; #endif /* _EATA_H */ diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c --- v1.1.81/linux/drivers/scsi/fdomain.c Mon Jan 9 11:24:22 1995 +++ linux/drivers/scsi/fdomain.c Mon Jan 16 07:17:37 1995 @@ -1,10 +1,10 @@ /* fdomain.c -- Future Domain TMC-16x0 SCSI driver * Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu - * Revised: Wed Dec 7 09:36:57 1994 by faith@cs.unc.edu + * Revised: Sat Jan 14 21:39:15 1995 by faith@cs.unc.edu * Author: Rickard E. Faith, faith@cs.unc.edu - * Copyright 1992, 1993, 1994 Rickard E. Faith + * Copyright 1992, 1993, 1994, 1995 Rickard E. Faith * - * $Id: fdomain.c,v 5.22 1994/12/07 15:15:46 root Exp $ + * $Id: fdomain.c,v 5.26 1995/01/15 02:39:19 root Exp $ * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -136,6 +136,10 @@ Thanks for Stephen Henson (shenson@nyx10.cs.du.edu) for providing the patch for the Quantum ISA-200S SCSI adapter. + + Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, + and to Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to + some random TMC-1680 repackaged by IBM. All of the alpha testers deserve much thanks. @@ -186,7 +190,7 @@ #include #include -#define VERSION "$Revision: 5.22 $" +#define VERSION "$Revision: 5.26 $" /* START OF USER DEFINABLE OPTIONS */ @@ -304,7 +308,7 @@ static int FIFO_Size = 0x2000; /* 8k FIFO for pre-tmc18c30 chips */ -extern void fdomain_16x0_intr( int unused ); +extern void fdomain_16x0_intr( int irq, struct pt_regs * regs ); static void *addresses[] = { (void *)0xc8000, @@ -312,6 +316,7 @@ (void *)0xce000, (void *)0xde000, (void *)0xd0000, /* Extra addresses for PCI boards */ + (void *)0xe0000, }; #define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned )) @@ -361,9 +366,11 @@ { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50, 2, 0, 2 }, { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92", 5, 44, 3, 0, 0 }, { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93", 5, 44, 3, 2, 0 }, + { "IBM F1 P2 BIOS v1.0104/29/93", 5, 28, 3, -1, 0 }, { "Future Domain Corp. V1.0008/18/93", 5, 33, 3, 4, 0 }, - { "FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 }, { "Future Domain Corp. V1.0008/18/93", 26, 33, 3, 4, 1 }, + { "FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 }, + { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5", 5, 44, 3, 5, 0 }, { "FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1, 0 }, /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE @@ -376,27 +383,38 @@ geometry information in the on-board RAM area for each of the first three BIOS's, it is still important to enter a fully qualified signature in the table for any new BIOS's (after the host SCSI ID and - geometry location are verified.) */ + geometry location are verified). */ }; #define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature )) -static void print_banner( struct Scsi_Host * shpnt ) +static void print_banner( struct Scsi_Host *shpnt ) { - printk( "%s", fdomain_16x0_info(shpnt) ); - printk( "Future Domain: BIOS version %d.%d, %s\n", - bios_major, bios_minor, + if (!shpnt) return; /* This won't ever happen */ + + printk( "scsi%d : BIOS version ", shpnt->host_no ); + + if (bios_major >= 0) printk( "%d.", bios_major ); + else printk( "?." ); + + if (bios_minor >= 0) printk( "%d", bios_minor ); + else printk( "?." ); + + printk( " at 0x%x using scsi id %d\n", + (unsigned)bios_base, shpnt->this_id ); + + printk( "scsi%d : %s chip at 0x%x irq ", + shpnt->host_no, chip == tmc1800 ? "TMC-1800" : (chip == tmc18c50 ? "TMC-18C50" - : (chip == tmc18c30 ? "TMC-18C30" : "Unknown")) ); - - if (interrupt_level) { - printk( "Future Domain: BIOS at %x; port base at %x; using IRQ %d\n", - (unsigned)bios_base, port_base, interrupt_level ); - } else { - printk( "Future Domain: BIOS at %x; port base at %x; *NO* IRQ\n", - (unsigned)bios_base, port_base ); - } + : (chip == tmc18c30 ? "TMC-18C30" : "Unknown")), + port_base ); + + if (interrupt_level) printk( "%d", interrupt_level ); + else printk( "" ); + + if (PCI_bus) printk( " (PCI bus)" ); + printk( "\n" ); } static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */ @@ -515,6 +533,7 @@ int i, j; int flag = 0; int retcode; + struct Scsi_Host *shpnt; #if DO_DETECT const int buflen = 255; Scsi_Cmnd SCinit; @@ -649,8 +668,6 @@ return 0; /* Cannot find valid set of ports */ } - print_banner(NULL); - SCSI_Mode_Cntl_port = port_base + SCSI_Mode_Cntl; FIFO_Data_Count_port = port_base + FIFO_Data_Count; Interrupt_Cntl_port = port_base + Interrupt_Cntl; @@ -669,48 +686,51 @@ if (fdomain_test_loopback()) { #if DEBUG_DETECT - printk( "Future Domain: LOOPBACK TEST FAILED, FAILING DETECT!\n" ); + printk( "fdomain: LOOPBACK TEST FAILED, FAILING DETECT!\n" ); #endif return 0; - } /* Log IRQ with kernel */ - + } + + if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) { + adapter_mask = 0x80; + tpnt->this_id = 7; + } + + /* Print out a banner here in case we can't + get resources. */ + + shpnt = scsi_register( tpnt, 0 ); + print_banner( shpnt ); + + /* Log IRQ with kernel */ if (!interrupt_level) { - panic( "Future Domain: *NO* interrupt level selected!\n" ); + panic( "fdomain: *NO* interrupt level selected!\n" ); } else { /* Register the IRQ with the kernel */ - retcode = request_irq( interrupt_level, fdomain_16x0_intr, SA_INTERRUPT, "FDomain"); + retcode = request_irq( interrupt_level, + fdomain_16x0_intr, SA_INTERRUPT, "fdomain" ); if (retcode < 0) { if (retcode == -EINVAL) { - printk( "Future Domain: IRQ %d is bad!\n", interrupt_level ); - printk( " This shouldn't happen!\n" ); - printk( " Send mail to faith@cs.unc.edu\n" ); + printk( "fdomain: IRQ %d is bad!\n", interrupt_level ); + printk( " This shouldn't happen!\n" ); + printk( " Send mail to faith@cs.unc.edu\n" ); } else if (retcode == -EBUSY) { - printk( "Future Domain: IRQ %d is already in use!\n", - interrupt_level ); - printk( " Please use another IRQ!\n" ); + printk( "fdomain: IRQ %d is already in use!\n", interrupt_level ); + printk( " Please use another IRQ!\n" ); } else { - printk( "Future Domain: Error getting IRQ %d\n", interrupt_level ); - printk( " This shouldn't happen!\n" ); - printk( " Send mail to faith@cs.unc.edu\n" ); + printk( "fdomain: Error getting IRQ %d\n", interrupt_level ); + printk( " This shouldn't happen!\n" ); + printk( " Send mail to faith@cs.unc.edu\n" ); } - panic( "Future Domain: Driver requires interruptions\n" ); - } else { - printk( "Future Domain: IRQ %d requested from kernel\n", - interrupt_level ); + panic( "fdomain: Driver requires interruptions\n" ); } } /* Log I/O ports with kernel */ + request_region( port_base, 0x10, "fdomain" ); - request_region( port_base, 0x10 ,"fdomain"); - - if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) { - adapter_mask = 0x80; - tpnt->this_id = 7; - } - #if DO_DETECT /* These routines are here because of the way the SCSI bus behaves after @@ -725,7 +745,7 @@ SCinit.use_sg = 0; SCinit.lun = 0; - printk( "Future Domain detection routine scanning for devices:\n" ); + printk( "fdomain: detection routine scanning for devices:\n" ); for (i = 0; i < 8; i++) { SCinit.target = i; if (i == tpnt->this_id) /* Skip host adapter */ @@ -764,15 +784,15 @@ } #endif - return 1; + return 1; /* Maximum of one adapter will be detected. */ } -const char *fdomain_16x0_info(struct Scsi_Host * shpnt) +const char *fdomain_16x0_info( struct Scsi_Host *ignore ) { static char buffer[80]; char *pt; - strcpy( buffer, "Future Domain: TMC-16x0 SCSI driver, version" ); + strcpy( buffer, "Future Domain TMC-16x0 SCSI driver, version" ); if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */ strcat( buffer, strchr( VERSION, ':' ) + 1 ); pt = strrchr( buffer, '$') - 1; @@ -780,10 +800,9 @@ pt = buffer + strlen( buffer ) - 1; if (*pt != ' ') ++pt; - *pt++ = '\n'; *pt = '\0'; } else { /* Assume VERSION is a number */ - strcat( buffer, " " VERSION "\n" ); + strcat( buffer, " " VERSION ); } return buffer; @@ -817,7 +836,7 @@ printk( "Arbitration failed, status = %x\n", status ); #endif #if ERRORS_ONLY - printk( "Future Domain: Arbitration failed, status = %x\n", status ); + printk( "fdomain: Arbitration failed, status = %x\n", status ); #endif return 1; } @@ -857,7 +876,7 @@ if (chip == tmc18c30 && !flag) /* Skip first failure for 18C30 chips. */ ++flag; else - printk( "Future Domain: Selection failed\n" ); + printk( "fdomain: Selection failed\n" ); } #endif return 1; @@ -872,22 +891,28 @@ current_SC->result = error; if (current_SC->scsi_done) current_SC->scsi_done( current_SC ); - else panic( "Future Domain: current_SC->scsi_done() == NULL" ); + else panic( "fdomain: current_SC->scsi_done() == NULL" ); } else { - panic( "Future Domain: my_done() called outside of command\n" ); + panic( "fdomain: my_done() called outside of command\n" ); } #if DEBUG_RACE in_interrupt_flag = 0; #endif } -void fdomain_16x0_intr( int unused ) +void fdomain_16x0_intr( int irq, struct pt_regs * regs ) { int status; int done = 0; unsigned data_count; - sti(); + /* The fdomain_16x0_intr is only called via + the interrupt handler. The goal of the + sti() here is to allow other + interruptions while this routine is + running. */ + + sti(); /* Yes, we really want sti() here */ outb( 0x00, Interrupt_Cntl_port ); @@ -997,9 +1022,9 @@ #endif #if ERRORS_ONLY if (current_SC->SCp.Status && current_SC->SCp.Status != 2) { - printk( "Future Domain: target = %d, command = %x, " - "Status = %x\n", - current_SC->target, current_SC->cmnd[0], + printk( "fdomain: target = %d, command = %x, status = %x\n", + current_SC->target, + current_SC->cmnd[0], current_SC->SCp.Status ); } #endif @@ -1015,8 +1040,7 @@ if (!current_SC->SCp.Message) ++done; #if DEBUG_MESSAGES || EVERY_ACCESS if (current_SC->SCp.Message) { - printk( "Future Domain: Message = %x\n", - current_SC->SCp.Message ); + printk( "fdomain: message = %x\n", current_SC->SCp.Message ); } #endif break; @@ -1277,7 +1301,7 @@ || code == 0x24 || !code))) - printk( "Future Domain: REQUEST SENSE " + printk( "fdomain: REQUEST SENSE " "Key = %x, Code = %x, Qualifier = %x\n", key, code, qualifier ); } @@ -1309,7 +1333,7 @@ int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) { if (in_command) { - panic( "Future Domain: fdomain_16x0_queue() NOT REENTRANT!\n" ); + panic( "fdomain: fdomain_16x0_queue() NOT REENTRANT!\n" ); } #if EVERY_ACCESS printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n", @@ -1387,8 +1411,13 @@ unsigned int imr; unsigned int irr; unsigned int isr; + + if (!SCpnt || !SCpnt->host) { + printk( "fdomain: cannot provide detailed information\n" ); + } - print_banner(SCpnt->host); + printk( "%s\n", fdomain_16x0_info( SCpnt->host ) ); + print_banner( SCpnt->host ); switch (SCpnt->SCp.phase) { case in_arbitration: printk( "arbitration " ); break; case in_selection: printk( "selection " ); break; @@ -1448,16 +1477,18 @@ int fdomain_16x0_abort( Scsi_Cmnd *SCpnt) { + unsigned long flags; #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT - printk( "Future Domain: Abort " ); + printk( "fdomain: abort " ); #endif + save_flags( flags ); cli(); if (!in_command) { #if EVERY_ACCESS || ERRORS_ONLY printk( " (not in command)\n" ); #endif - sti(); + restore_flags( flags ); return SCSI_ABORT_NOT_RUNNING; } @@ -1471,7 +1502,7 @@ current_SC->result = DID_ABORT << 16; - sti(); + restore_flags( flags ); /* Aborts are not done well. . . */ my_done( DID_ABORT << 16 ); @@ -1486,7 +1517,7 @@ #endif #if ERRORS_ONLY - printk( "Future Domain: SCSI Bus Reset\n" ); + if (SCpnt) printk( "fdomain: SCSI Bus Reset\n" ); #endif #if DEBUG_RESET @@ -1580,7 +1611,9 @@ info_array[0] = i->heads; info_array[1] = i->sectors; info_array[2] = i->cylinders; - } else if (bios_major == 3 && bios_minor < 4) { /* 3.0 and 3.2 BIOS */ + } else if (bios_major == 3 + && bios_minor >= 0 + && bios_minor < 4) { /* 3.0 and 3.2 BIOS */ i = (struct drive_info *)( (char *)bios_base + 0x1f71 + drive * 10 ); info_array[0] = i->heads + 1; info_array[1] = i->sectors; diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/fdomain.h linux/drivers/scsi/fdomain.h --- v1.1.81/linux/drivers/scsi/fdomain.h Tue Nov 29 10:07:12 1994 +++ linux/drivers/scsi/fdomain.h Sun Jan 15 13:02:18 1995 @@ -1,10 +1,10 @@ /* fdomain.h -- Header for Future Domain TMC-16x0 driver * Created: Sun May 3 18:47:33 1992 by faith@cs.unc.edu - * Revised: Sat Jul 30 20:20:31 1994 by faith@cs.unc.edu + * Revised: Sat Jan 14 20:56:52 1995 by faith@cs.unc.edu * Author: Rickard E. Faith, faith@cs.unc.edu - * Copyright 1992, 1993, 1994 Rickard E. Faith + * Copyright 1992, 1993, 1994, 1995 Rickard E. Faith * - * $Id: fdomain.h,v 5.7 1994/07/31 03:09:15 faith Exp $ + * $Id: fdomain.h,v 5.10 1995/01/15 01:56:56 root Exp $ * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -33,7 +33,8 @@ int fdomain_16x0_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) ); int fdomain_16x0_biosparam( Disk *, int, int * ); -#define FDOMAIN_16X0 { NULL, NULL, \ +#define FDOMAIN_16X0 { NULL, \ + NULL, \ NULL, \ fdomain_16x0_detect, \ NULL, \ diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/in2000.c linux/drivers/scsi/in2000.c --- v1.1.81/linux/drivers/scsi/in2000.c Mon Jan 9 11:24:23 1995 +++ linux/drivers/scsi/in2000.c Mon Jan 16 07:17:37 1995 @@ -266,7 +266,7 @@ ficmsk = 0;} } -static void in2000_intr_handle(int foo) +static void in2000_intr_handle(int irq, struct pt_regs *regs) { int result=0; unsigned int count,auxstatus,scsistatus,cmdphase,scsibyte; diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/qlogic.c linux/drivers/scsi/qlogic.c --- v1.1.81/linux/drivers/scsi/qlogic.c Mon Jan 9 11:24:23 1995 +++ linux/drivers/scsi/qlogic.c Mon Jan 16 07:17:37 1995 @@ -386,7 +386,7 @@ #if QL_USE_IRQ /*----------------------------------------------------------------*/ /* interrupt handler */ -static void ql_ihandl(int irq) +static void ql_ihandl(int irq, struct pt_regs * regs) { Scsi_Cmnd *icmd; REG0; diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v1.1.81/linux/drivers/scsi/scsi.c Fri Jan 13 16:57:06 1995 +++ linux/drivers/scsi/scsi.c Sat Jan 14 21:04:27 1995 @@ -2146,7 +2146,7 @@ Scsi_Cmnd * SCpnt; struct Scsi_Device_Template * sdtpnt; int j, i; - char * name; + const char * name; if (tpnt->next || !tpnt->detect) return 1; /* Must be already loaded, or no detect routine available */ diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c --- v1.1.81/linux/drivers/scsi/seagate.c Mon Jan 9 07:22:07 1995 +++ linux/drivers/scsi/seagate.c Mon Jan 16 07:17:37 1995 @@ -192,7 +192,7 @@ */ static int hostno = -1; -static void seagate_reconnect_intr(int); +static void seagate_reconnect_intr(int, struct pt_regs *); #ifdef FAST static int fast = 1; @@ -450,7 +450,7 @@ * asserting SEL. */ -static void seagate_reconnect_intr (int unused) +static void seagate_reconnect_intr(int irq, struct pt_regs * regs) { int temp; Scsi_Cmnd * SCtmp; diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c --- v1.1.81/linux/drivers/scsi/sr.c Fri Jan 13 16:57:06 1995 +++ linux/drivers/scsi/sr.c Sun Jan 15 00:25:52 1995 @@ -357,7 +357,7 @@ *((unsigned long*)buf+1) = 12; buf[8+0] = 0x15; buf[8+1] = (1 << 4); - buf[8+2] = 12; + buf[8+4] = 12; buf[14+ 3] = 0x08; buf[14+ 4] = 0x83; buf[14+10] = 0x08; @@ -985,7 +985,7 @@ major = MAJOR_NR << 8; - for(cpnt = scsi_CDs, i=0; idevice == SDp) { /* * Since the cdrom is read-only, no need to sync the device. diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c --- v1.1.81/linux/drivers/scsi/u14-34f.c Mon Jan 9 11:24:23 1995 +++ linux/drivers/scsi/u14-34f.c Mon Jan 16 13:31:06 1995 @@ -1,6 +1,10 @@ /* * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters. * + * 16 Jan 1995 rev. 1.13 for linux 1.1.81 + * Display a message if check_region detects a port address + * already in use. + * * 15 Dec 1994 rev. 1.12 for linux 1.1.74 * The host->block flag is set for all the detected ISA boards. * @@ -245,7 +249,7 @@ #define HD(board) ((struct hostdata *) &sh[board]->hostdata) #define BN(board) (HD(board)->board_name) -static void u14_34f_interrupt_handler(int); +static void u14_34f_interrupt_handler(int, struct pt_regs *); static int do_trace = FALSE; static inline unchar wait_on_busy(ushort iobase) { @@ -301,7 +305,11 @@ sprintf(name, "%s%d", driver_name, j); - if(check_region(*port_base, REG_REGION)) return FALSE; + if(check_region(*port_base, REG_REGION)) { + printk("%s: address 0x%03x already in use, detaching.\n", + name, *port_base); + return FALSE; + } if (inb(*port_base + REG_PRODUCT_ID1) != PRODUCT_ID1) return FALSE; @@ -352,7 +360,7 @@ if (sh[j]->base == 0) outb(CMD_ENA_INTR, sh[j]->io_port + REG_SYS_MASK); /* Register the I/O space that we use */ - request_region(sh[j]->io_port, REG_REGION,"u14-34f"); + request_region(sh[j]->io_port, REG_REGION, driver_name); memset(HD(j), 0, sizeof(struct hostdata)); HD(j)->heads = mapping_table[config_2.mapping_mode].heads; @@ -706,7 +714,7 @@ return 0; } -static void u14_34f_interrupt_handler(int irq) { +static void u14_34f_interrupt_handler(int irq, struct pt_regs * regs) { Scsi_Cmnd *SCpnt; unsigned int i, j, k, flags, status, loops, total_loops = 0; struct mscp *spp; diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h --- v1.1.81/linux/drivers/scsi/u14-34f.h Tue Dec 20 10:23:14 1994 +++ linux/drivers/scsi/u14-34f.h Mon Jan 16 13:31:06 1995 @@ -10,7 +10,7 @@ int u14_34f_reset(Scsi_Cmnd *); int u14_34f_biosparam(Disk *, int, int *); -#define U14_34F_VERSION "1.12.04" +#define U14_34F_VERSION "1.13.00" #define ULTRASTOR_14_34F { \ NULL, \ diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c --- v1.1.81/linux/drivers/scsi/ultrastor.c Mon Jan 9 11:24:23 1995 +++ linux/drivers/scsi/ultrastor.c Mon Jan 16 07:17:37 1995 @@ -283,7 +283,7 @@ }; #endif -static void ultrastor_interrupt(int cpl); +static void ultrastor_interrupt(int, struct pt_regs *); static inline void build_sg_list(struct mscp *, Scsi_Cmnd *SCpnt); @@ -1014,7 +1014,7 @@ return 0; } -static void ultrastor_interrupt(int cpl) +static void ultrastor_interrupt(int irq, struct pt_regs *regs) { unsigned int status; #if ULTRASTOR_MAX_CMDS > 1 diff -u --recursive --new-file v1.1.81/linux/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c --- v1.1.81/linux/drivers/scsi/wd7000.c Mon Jan 9 11:24:23 1995 +++ linux/drivers/scsi/wd7000.c Mon Jan 16 07:17:37 1995 @@ -797,15 +797,8 @@ #define wd7000_intr_ack(host) outb(0,host->iobase+ASC_INTR_ACK) -void wd7000_intr_handle(int irq) +void wd7000_intr_handle(int irq, struct pt_regs * regs) { -#ifdef 0 - /* - * Use irqp as the parm, and the following declaration, if - * SA_INTERRUPT is not used. - */ - register int irq = *(((int *)irqp)-2); -#endif register int flag, icmb, errstatus, icmb_status; register int host_error, scsi_error; register Scb *scb; /* for SCSI commands */ @@ -1189,7 +1182,7 @@ if (inb(host->iobase+ASC_STAT) & INT_IM) { printk("wd7000_abort: lost interrupt\n"); - wd7000_intr_handle(host->irq); + wd7000_intr_handle(host->irq, NULL); return SCSI_ABORT_SUCCESS; } diff -u --recursive --new-file v1.1.81/linux/drivers/sound/Makefile linux/drivers/sound/Makefile --- v1.1.81/linux/drivers/sound/Makefile Tue Oct 18 10:07:28 1994 +++ linux/drivers/sound/Makefile Fri Jan 13 17:25:07 1995 @@ -71,6 +71,8 @@ $(MAKE) /usr/include/sys/soundcard.h $(CPP) -M *.c > .depend +modules: + # # include a dependency file if one exists # diff -u --recursive --new-file v1.1.81/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c --- v1.1.81/linux/drivers/sound/soundcard.c Sat Nov 5 20:03:11 1994 +++ linux/drivers/sound/soundcard.c Mon Jan 16 07:17:37 1995 @@ -221,7 +221,7 @@ } int -snd_set_irq_handler (int interrupt_level, void (*hndlr) (int)) +snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, struct pt_regs *)) { int retcode; diff -u --recursive --new-file v1.1.81/linux/fs/minix/namei.c linux/fs/minix/namei.c --- v1.1.81/linux/fs/minix/namei.c Sat Oct 22 16:37:14 1994 +++ linux/fs/minix/namei.c Mon Jan 16 12:48:15 1995 @@ -189,6 +189,7 @@ } } else { dir->i_mtime = dir->i_ctime = CURRENT_TIME; + dir->i_dirt = 1; for (i = 0; i < info->s_namelen ; i++) de->name[i] = (i < namelen) ? name[i] : 0; dir->i_version = ++event; diff -u --recursive --new-file v1.1.81/linux/fs/nfs/inode.c linux/fs/nfs/inode.c --- v1.1.81/linux/fs/nfs/inode.c Wed Jan 11 21:14:28 1995 +++ linux/fs/nfs/inode.c Fri Jan 13 18:11:13 1995 @@ -263,7 +263,7 @@ char kernel_version[] = UTS_RELEASE; static struct file_system_type nfs_fs_type = { - nfs_read_super, "nfs", 1, NULL + nfs_read_super, "nfs", 0, NULL }; int init_module(void) diff -u --recursive --new-file v1.1.81/linux/include/asm-alpha/console.h linux/include/asm-alpha/console.h --- v1.1.81/linux/include/asm-alpha/console.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-alpha/console.h Mon Jan 16 07:17:37 1995 @@ -0,0 +1,47 @@ +#ifndef __AXP_CONSOLE_H +#define __AXP_CONSOLE_H + +/* + * Console callback routine numbers + */ +#define CCB_GETC 0x01 +#define CCB_PUTS 0x02 +#define CCB_RESET_TERM 0x03 +#define CCB_SET_TERM_INT 0x04 +#define CCB_SET_TERM_CTL 0x05 +#define CCB_PROCESS_KEYCODE 0x06 + +#define CCB_OPEN 0x10 +#define CCB_CLOSE 0x11 +#define CCB_IOCTL 0x12 +#define CCB_READ 0x13 +#define CCB_WRITE 0x14 + +#define CCB_SET_ENV 0x20 +#define CCB_RESET_ENV 0x21 +#define CCB_GET_ENV 0x22 +#define CCB_SAVE_ENV 0x23 + +/* + * Environment variable numbers + */ +#define ENV_AUTO_ACTION 0x01 +#define ENV_BOOT_DEV 0x02 +#define ENV_BOOTDEF_DEV 0x03 +#define ENV_BOOTED_DEV 0x04 +#define ENV_BOOT_FILE 0x05 +#define ENV_BOOTED_FILE 0x06 +#define ENV_BOOT_OSFLAGS 0x07 +#define ENV_BOOTED_OSFLAGS 0x08 +#define ENV_BOOT_RESET 0x09 +#define ENV_DUMP_DEV 0x0A +#define ENV_ENABLE_AUDIT 0x0B +#define ENV_LICENCE 0x0C +#define ENV_CHAR_SET 0x0D +#define ENV_LANGUAGE 0x0E +#define ENV_TTY_DEV 0x0F + +extern unsigned long dispatch(unsigned long code, ...); +#define puts(x,l) dispatch(CCB_PUTS,0,x,l) + +#endif diff -u --recursive --new-file v1.1.81/linux/include/asm-alpha/dma.h linux/include/asm-alpha/dma.h --- v1.1.81/linux/include/asm-alpha/dma.h Fri Jan 13 10:12:23 1995 +++ linux/include/asm-alpha/dma.h Mon Jan 16 13:41:14 1995 @@ -20,8 +20,8 @@ #include /* need byte IO */ -#define dma_outb outb_local -#define dma_inb inb_local +#define dma_outb outb +#define dma_inb inb /* * NOTES about DMA transfers: diff -u --recursive --new-file v1.1.81/linux/include/asm-alpha/hwrpb.h linux/include/asm-alpha/hwrpb.h --- v1.1.81/linux/include/asm-alpha/hwrpb.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-alpha/hwrpb.h Mon Jan 16 07:17:37 1995 @@ -0,0 +1,125 @@ +#ifndef _HWRPB_H +#define _HWRPB_H + +#define INIT_HWRPB ((struct hwrpb_struct *) 0x10000000) + +struct pcb_struct { + unsigned long ksp; + unsigned long usp; + unsigned long ptbr; + unsigned int pcc; + unsigned int asn; + unsigned long unique; + unsigned long flags; + unsigned long res1, res2; +}; + +struct percpu_struct { + unsigned long hwpcb[16]; + unsigned long flags; + unsigned long pal_mem_size; + unsigned long pal_scratch_size; + unsigned long pal_mem_pa; + unsigned long pal_scratch_pa; + unsigned long pal_revision; + unsigned long type; + unsigned long variation; + unsigned long revision; + unsigned long serial_no[2]; + unsigned long logout_area_pa; + unsigned long logout_area_len; + unsigned long halt_PCBB; + unsigned long halt_PC; + unsigned long halt_PS; + unsigned long halt_arg; + unsigned long halt_ra; + unsigned long halt_pv; + unsigned long halt_reason; + unsigned long res; + unsigned long ipc_buffer[21]; + unsigned long palcode_avail[16]; + unsigned long compatibility; +}; + +struct procdesc_struct { + unsigned long weird_vms_stuff; + unsigned long address; +}; + +struct vf_map_struct { + unsigned long va; + unsigned long pa; + unsigned long count; +}; + +struct crb_struct { + struct procdesc_struct * dispatch_va; + struct procdesc_struct * dispatch_pa; + struct procdesc_struct * fixup_va; + struct procdesc_struct * fixup_pa; + /* virtual->physical map */ + unsigned long map_entries; + unsigned long map_pages; + struct vf_map_struct map[1]; +}; + +struct memclust_struct { + unsigned long start_pfn; + unsigned long numpages; + unsigned long numtested; + unsigned long bitmap_va; + unsigned long bitmap_pa; + unsigned long bitmap_chksum; + unsigned long usage; +}; + +struct memdesc_struct { + unsigned long chksum; + unsigned long optional_pa; + unsigned long numclusters; + struct memclust_struct cluster[0]; +}; + +struct hwrpb_struct { + unsigned long phys_addr; /* check: physical address of the hwrpb */ + unsigned long id; /* check: "HWRPB\0\0\0" */ + unsigned long revision; + unsigned long size; /* size of hwrpb */ + unsigned long cpuid; + unsigned long pagesize; /* 8192, I hope */ + unsigned long pa_bits; /* number of physical address bits */ + unsigned long max_asn; + unsigned char ssn[16]; /* system serial number: big bother is watching */ + unsigned long sys_type; + unsigned long sys_variation; + unsigned long sys_revision; + unsigned long intr_freq; /* interval clock frequency * 4096 */ + unsigned long cycle_freq; /* cycle counter frequency */ + unsigned long vptb; /* Virtual Page Table Base address */ + unsigned long res1; + unsigned long tbhb_offset; /* Translation Buffer Hint Block */ + unsigned long nr_processors; + unsigned long processor_size; + unsigned long processor_offset; + unsigned long ctb_nr; + unsigned long ctb_size; /* console terminal block size */ + unsigned long ctbt_offset; /* console terminal block table offset */ + unsigned long crb_offset; /* console callback routine block */ + unsigned long mddt_offset; /* memory data descriptor table */ + unsigned long cdb_offset; /* configuration data block (or NULL) */ + unsigned long frut_offset; /* FRU table (or NULL) */ + void (*save_terminal)(unsigned long); + unsigned long save_terminal_data; + void (*restore_terminal)(unsigned long); + unsigned long restore_terminal_data; + void (*CPU_restart)(unsigned long); + unsigned long CPU_restart_data; + unsigned long res2; + unsigned long res3; + unsigned long chksum; + unsigned long rxrdy; + unsigned long txrdy; + unsigned long dsrdbt_offset; /* "Dynamic System Recognition Data Block Table" Whee */ +}; + +#endif diff -u --recursive --new-file v1.1.81/linux/include/asm-alpha/io.h linux/include/asm-alpha/io.h --- v1.1.81/linux/include/asm-alpha/io.h Mon Jan 9 07:22:09 1995 +++ linux/include/asm-alpha/io.h Mon Jan 16 13:41:14 1995 @@ -89,26 +89,84 @@ * The "local" functions are those that don't go out to the EISA bus, * but instead act on the VL82C106 chip directly.. This is mainly the * keyboard, RTC, printer and first two serial lines.. + * + * The local stuff makes for some complications, but it seems to be + * gone in the PCI version. I hope I can get DEC suckered^H^H^H^H^H^H^H^H + * convinced that I need one of the newer machines. */ -extern inline unsigned long inb_local(unsigned long addr) +extern inline unsigned int __local_inb(unsigned long addr) { long result = *(volatile int *) ((addr << 9) + EISA_VL82C106); return 0xffUL & result; } -extern inline void outb_local(unsigned char b, unsigned long addr) +extern inline void __local_outb(unsigned char b, unsigned long addr) { *(volatile unsigned int *) ((addr << 9) + EISA_VL82C106) = b; mb(); } -extern inline unsigned int inb(unsigned long addr) +extern inline unsigned int __inb(unsigned long addr) { long result = *(volatile int *) ((addr << 7) + EISA_IO + 0x00); result >>= (addr & 3) * 8; return 0xffUL & result; } +extern inline void __outb(unsigned char b, unsigned long addr) +{ + *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x00) = b * 0x01010101; + mb(); +} + +/* + * This is a stupid one: I'll make it a bitmap soon, promise.. + * + * On the other hand: this allows gcc to optimize. Hmm. I'll + * have to use the __constant_p() stuff here. + * + * The PCI version just returns zero all the time, I do believe.. + */ +extern inline int __is_local(unsigned long addr) +{ + /* keyboard */ + if (addr == 0x60 || addr == 0x64) + return 1; + + /* RTC */ + if (addr == 0x170 || addr == 0x171) + return 1; + + /* motherboard COM2 */ + if (addr >= 0x2f8 && addr <= 0x2ff) + return 1; + + /* motherboard LPT1 */ + if (addr >= 0x3bc && addr <= 0x3be) + return 1; + + /* motherboard COM2 */ + if (addr >= 0x3f8 && addr <= 0x3ff) + return 1; + + return 0; +} + +extern inline unsigned int inb(unsigned long addr) +{ + if (__is_local(addr)) + return __local_inb(addr); + return __inb(addr); +} + +extern inline void outb(unsigned char b, unsigned long addr) +{ + if (__is_local(addr)) + __local_outb(b, addr); + else + __outb(b, addr); +} + extern inline unsigned int inw(unsigned long addr) { long result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20); @@ -119,12 +177,6 @@ extern inline unsigned int inl(unsigned long addr) { return *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x60); -} - -extern inline void outb(unsigned char b, unsigned long addr) -{ - *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x00) = b * 0x01010101; - mb(); } extern inline void outw(unsigned short b, unsigned long addr) diff -u --recursive --new-file v1.1.81/linux/include/asm-alpha/page.h linux/include/asm-alpha/page.h --- v1.1.81/linux/include/asm-alpha/page.h Fri Jan 13 10:12:23 1995 +++ linux/include/asm-alpha/page.h Mon Jan 16 07:17:37 1995 @@ -13,28 +13,69 @@ ".long 51" \ : : :"$1", "$16", "$17", "$22","$23","$24","$25") - /* PAGE_SHIFT determines the page size */ +/* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 13 #define PGDIR_SHIFT 23 #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PAGE_OFFSET 0xFFFFFC0000000000 +#define MAP_NR(addr) (((addr) - PAGE_OFFSET) >> PAGE_SHIFT) +#define MAP_PAGE_RESERVED (1<<31) + +typedef unsigned int mem_map_t; + +#define PAGE_PRESENT 0x001 +#define PAGE_RW 0x002 +#define PAGE_USER 0x004 +#define PAGE_ACCESSED 0x020 +#define PAGE_DIRTY 0x040 +#define PAGE_COW 0x200 /* implemented in software (one of the AVL bits) */ + +#define PAGE_PRIVATE (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED | PAGE_COW) +#define PAGE_SHARED (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED) +#define PAGE_COPY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED | PAGE_COW) +#define PAGE_READONLY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED) +#define PAGE_EXECONLY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED) +#define PAGE_TABLE (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED) + +#define PAGE_CHG_MASK (PAGE_MASK | PAGE_ACCESSED | PAGE_DIRTY) + #ifdef __KERNEL__ - /* number of bits that fit into a memory pointer */ +/* + * BAD_PAGETABLE is used when we need a bogus page-table, while + * BAD_PAGE is used for a bogus page. + * + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern unsigned long __bad_page(void); +extern unsigned long __bad_pagetable(void); +extern unsigned long __zero_page(void); + +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE __zero_page() + +/* number of bits that fit into a memory pointer */ #define BITS_PER_PTR (8*sizeof(unsigned long)) - /* to mask away the intra-page address bits */ + +/* to mask away the intra-page address bits */ #define PAGE_MASK (~(PAGE_SIZE-1)) - /* to mask away the intra-page address bits */ + +/* to mask away the intra-page address bits */ #define PGDIR_MASK (~(PGDIR_SIZE-1)) - /* to align the pointer to the (next) page boundary */ + +/* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - /* to align the pointer to a pointer address */ + +/* to align the pointer to a pointer address */ #define PTR_MASK (~(sizeof(void*)-1)) - /* sizeof(void*)==1<ps & 8) diff -u --recursive --new-file v1.1.81/linux/include/asm-alpha/signal.h linux/include/asm-alpha/signal.h --- v1.1.81/linux/include/asm-alpha/signal.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-alpha/signal.h Mon Jan 16 07:17:37 1995 @@ -0,0 +1,12 @@ +#ifndef _ASMAXP_SIGNAL_H +#define _ASMAXP_SIGNAL_H + +struct sigcontext_struct { + /* + * what should we have here? I'd probably better use the same + * stack layout as OSF/1, just in case we ever want to try + * running their binaries.. + */ +}; + +#endif diff -u --recursive --new-file v1.1.81/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h --- v1.1.81/linux/include/asm-alpha/system.h Thu Dec 29 19:58:42 1994 +++ linux/include/asm-alpha/system.h Mon Jan 16 13:41:14 1995 @@ -10,12 +10,23 @@ * We leave one page for the initial stack page, and one page for * the initial process structure. Also, the console eats 3 MB for * the initial bootloader (one of which we can reclaim later). - * So the initial load address is 0xfffffc0000304000UL + * With a few other pages for various reasons, we'll use an initial + * load address of 0xfffffc0000310000UL */ +#define BOOT_PCB 0x20000000 +#define BOOT_ADDR 0x20000000 +#define BOOT_SIZE (16*1024) + +#define KERNEL_START 0xfffffc0000300000 #define INIT_PCB 0xfffffc0000300000 #define INIT_STACK 0xfffffc0000302000 -#define START_ADDR 0xfffffc0000304000 -#define START_SIZE (32*1024) +#define EMPTY_PGT 0xfffffc0000304000 +#define EMPTY_PGE 0xfffffc0000308000 +#define ZERO_PGE 0xfffffc000030A000 +#define SWAPPER_PGD 0xfffffc000030C000 + +#define START_ADDR 0xfffffc0000310000 +#define START_SIZE (1024*1024) /* * Common PAL-code @@ -66,6 +77,8 @@ extern void wrent(void *, unsigned long); extern void wrkgp(unsigned long); +extern void wrusp(unsigned long); +extern unsigned long rdusp(void); #define halt() __asm__ __volatile__(".long 0"); #define move_to_user_mode() halt() diff -u --recursive --new-file v1.1.81/linux/include/asm-i386/page.h linux/include/asm-i386/page.h --- v1.1.81/linux/include/asm-i386/page.h Fri Jan 13 10:12:23 1995 +++ linux/include/asm-i386/page.h Mon Jan 16 07:17:37 1995 @@ -10,21 +10,74 @@ #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PAGE_OFFSET 0 +#define MAP_NR(addr) ((addr) >> PAGE_SHIFT) +#define MAP_PAGE_RESERVED (1<<15) + +typedef unsigned short mem_map_t; + +#define PAGE_PRESENT 0x001 +#define PAGE_RW 0x002 +#define PAGE_USER 0x004 +#define PAGE_PWT 0x008 /* 486 only - not used currently */ +#define PAGE_PCD 0x010 /* 486 only - not used currently */ +#define PAGE_ACCESSED 0x020 +#define PAGE_DIRTY 0x040 +#define PAGE_COW 0x200 /* implemented in software (one of the AVL bits) */ + +#define PAGE_PRIVATE (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED | PAGE_COW) +#define PAGE_SHARED (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED) +#define PAGE_COPY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED | PAGE_COW) +#define PAGE_READONLY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED) +#define PAGE_EXECONLY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED) +#define PAGE_TABLE (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED) + +#define PAGE_CHG_MASK (PAGE_MASK | PAGE_ACCESSED | PAGE_DIRTY | PAGE_PWT | PAGE_PCD) + #ifdef __KERNEL__ - /* number of bits that fit into a memory pointer */ +/* + * 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 + +/* page table for 0-4MB for everybody */ +extern unsigned long pg0[1024]; + +/* + * BAD_PAGETABLE is used when we need a bogus page-table, while + * BAD_PAGE is used for a bogus page. + * + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern unsigned long __bad_page(void); +extern unsigned long __bad_pagetable(void); +extern unsigned long __zero_page(void); + +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE __zero_page() + +/* number of bits that fit into a memory pointer */ #define BITS_PER_PTR (8*sizeof(unsigned long)) - /* to mask away the intra-page address bits */ + +/* to mask away the intra-page address bits */ #define PAGE_MASK (~(PAGE_SIZE-1)) - /* to mask away the intra-page address bits */ + +/* to mask away the intra-page address bits */ #define PGDIR_MASK (~(PGDIR_SIZE-1)) - /* to align the pointer to the (next) page boundary */ + +/* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - /* to align the pointer to a pointer address */ + +/* to align the pointer to a pointer address */ #define PTR_MASK (~(sizeof(void*)-1)) - /* sizeof(void*)==1< + +#if defined(__R4000__) + +/* + * The following functions will only work for the R4000! + */ +extern __inline__ int set_bit(int nr, void *addr) +{ + int mask, retval, mw; + + addr += ((nr >> 3) & ~3); + mask = 1 << (nr & 0x1f); + do { + mw = load_linked(addr); + retval = (mask & mw) != 0; + } + while (!store_conditional(addr, mw|mask)); + + return retval; +} + +extern __inline__ int clear_bit(int nr, void *addr) +{ + int mask, retval, mw; + + addr += ((nr >> 3) & ~3); + mask = 1 << (nr & 0x1f); + do { + mw = load_linked(addr); + retval = (mask & mw) != 0; + } + while (!store_conditional(addr, mw & ~mask)); + + return retval; +} + +extern __inline__ int change_bit(int nr, void *addr) +{ + int mask, retval, mw; + + addr += ((nr >> 3) & ~3); + mask = 1 << (nr & 0x1f); + do { + mw = load_linked(addr); + retval = (mask & mw) != 0; + } + while (!store_conditional(addr, mw ^ mask)); + + return retval; +} + +extern __inline__ int find_first_zero_bit (void *addr, unsigned size) +{ + int res; + + if (!size) + return 0; + + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n" + "1:\tsubu\t$1,%2,%0\n\t" + "blez\t$1,2f\n\t" + "lw\t$1,(%4)\n\t" + "addiu\t%4,%4,4\n\t" + "beql\t%1,$1,1b\n\t" + "addiu\t%0,%0,32\n\t" + "li\t%1,1\n" + "1:\tand\t%4,$1,%1\n\t" + "beq\t$0,%4,2f\n\t" + "sll\t%1,%1,1\n\t" + "bne\t$0,%1,1b\n\t" + "add\t%0,%0,1\n\t" + ".set\tat\n\t" + ".set\treorder\n" + "2:" + : "=d" (res) + : "d" ((unsigned int) 0xffffffff), + "d" (size), + "0" ((signed int) 0), + "d" (addr) + : "$1"); + + return res; +} + +#else /* !defined(__R4000__) */ + +#define __USE_PORTABLE_STRINGS_H + +#define __USE_GENERIC_set_bit +#define __USE_GENERIC_clear_bit +#define __USE_GENERIC_change_bit +#define __USE_GENERIC_find_first_zero_bit + +#endif /* !defined(__R4000__) */ + +extern __inline__ int test_bit(int nr, void *addr) +{ + int mask; + unsigned long *a; + + a = addr; + addr += nr >> 5; + mask = 1 << (nr & 0x1f); + return ((mask & *a) != 0); +} + +extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n" + "1:\tand\t$1,%2,%1\n\t" + "beq\t$0,$1,2f\n\t" + "sll\t%2,%2,1\n\t" + "bne\t$0,%2,1b\n\t" + "addiu\t%0,%0,1\n\t" + ".set\tat\n\t" + ".set\treorder\n" + : "=r" (set) + : "r" (*p >> bit), + "r" (1), + "0" (0) + : "$1"); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} /* - * On MIPS inline assembler bitfunctions are as effective - * as the standard C counterparts. + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. */ +extern __inline__ unsigned long ffz(unsigned long word) +{ + unsigned int __res; + unsigned int mask = 1; + + __asm__ __volatile__ ( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "li\t%2,1\n" + "1:\tand\t$1,%2,%1\n\t" + "beq\t$0,$1,2f\n\t" + "sll\t%2,%2,1\n\t" + "bne\t$0,%2,1b\n\t" + "add\t%0,%0,1\n\t" + ".set\tat\n\t" + ".set\treorder\n" + "2:\n\t" + : "=r" (__res), "=r" (word), "=r" (mask) + : "1" (~(word)), + "2" (mask), + "0" (0) + : "$1"); + + return __res; +} + +#ifdef __USE_PORTABLE_BITOPS_H #include +#endif -#endif /* _ASM_MIPS_BITOPS_H_ */ +#endif /* __ASM_MIPS_BITOPS_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/bootinfo.h linux/include/asm-mips/bootinfo.h --- v1.1.81/linux/include/asm-mips/bootinfo.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/bootinfo.h Fri Jan 13 20:43:00 1995 @@ -0,0 +1,150 @@ +/* + * bootinfo.h -- Definition of the Linux/MIPS boot information structure + * + * Copyright (C) 1994 by Waldorf Electronics + * Written by Ralf Baechle and Andreas Busse + * + * Based on Linux/68k linux/include/linux/bootstrap.h + * Copyright (C) 1992 by Greg Harp + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file README.legal in the main directory of this archive + * for more details. + */ + +#ifndef __ASM_MIPS_BOOTINFO_H +#define __ASM_MIPS_BOOTINFO_H + +/* + * Valid values for machtype field + */ +#define MACH_UNKNOWN 0 /* whatever... */ +#define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */ +#define MACH_ACER_PICA_61 2 /* Acer PICA-61 (PICA1) */ +#define MACH_MIPS_MAGNUM_4000 3 /* Mips Magnum 4000 (aka RC4030) */ + +/* + * Valid values for cputype field + */ +#define CPU_UNKNOWN 0 +#define CPU_R2000 1 +#define CPU_R3000 2 +#define CPU_R3000A 3 +#define CPU_R3041 4 +#define CPU_R3051 5 +#define CPU_R3052 6 +#define CPU_R3081 7 +#define CPU_R3081E 8 +#define CPU_R4000PC 9 +#define CPU_R4000SC 10 +#define CPU_R4000MC 11 +#define CPU_R4200 12 +#define CPU_R4400PC 13 +#define CPU_R4400SC 14 +#define CPU_R4400MC 15 +#define CPU_R4600 16 +#define CPU_R6000 17 +#define CPU_R6000A 18 +#define CPU_R8000 19 +#define CPU_R10000 20 + +#define CPU_NAMES { "UNKNOWN", "R2000", "R3000", "R3000A", "R3041", "R3051", \ + "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \ + "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000", \ + "R6000A", "R8000", "R10000" } + +#define CL_SIZE (80) + +#ifndef __ASSEMBLY__ + +/* + * Some machine parameters passed by MILO. Note that bootinfo + * *must* be in the data segment since the kernel clears the + * bss segment directly after startup. + */ + +struct bootinfo { + + unsigned long machtype; /* machine type */ + unsigned long cputype; /* system CPU & FPU */ + + /* + * Installed RAM + */ + unsigned long memlower; + unsigned long memupper; + + /* + * Cache Sizes (0xffffffff = unknown) + */ + unsigned long icache_size; + unsigned long icache_linesize; + unsigned long dcache_size; + unsigned long dcache_linesize; + unsigned long scache_size; + unsigned long scache_linesize; + + /* + * TLB Info + */ + unsigned long tlb_entries; + + /* + * DMA buffer size (Deskstation only) + */ + unsigned long dma_cache_size; + unsigned long dma_cache_base; + + /* + * Ramdisk Info + */ + unsigned long ramdisk_size; /* ramdisk size in 1024 byte blocks */ + unsigned long ramdisk_base; /* address of the ram disk in mem */ + + /* + * Video ram info (not in tty.h) + */ + unsigned long vram_base; /* video ram base address */ + + char command_line[CL_SIZE]; /* kernel command line parameters */ + +}; + +extern struct bootinfo boot_info; + +/* + * Defaults, may be overwritten by milo. We initialize + * them to make sure that both boot_info and screen_info + * are in the .data segment since the .bss segment is + * cleared during startup. + */ +#define BOOT_INFO { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"" } + +#else /* !__ASSEMBLY__ */ + +/* + * Same structure, but as offsets for usage within assembler source. + * Don't mess with struct bootinfo without changing offsets too! + */ + +#define OFFSET_BOOTINFO_MACHTYPE 0 +#define OFFSET_BOOTINFO_CPUTYPE 4 +#define OFFSET_BOOTINFO_MEMLOWER 8 +#define OFFSET_BOOTINFO_MEMUPPER 12 +#define OFFSET_BOOTINFO_ICACHE_SIZE 16 +#define OFFSET_BOOTINFO_ICACHE_LINESIZE 20 +#define OFFSET_BOOTINFO_DCACHE_SIZE 24 +#define OFFSET_BOOTINFO_DCACHE_LINESIZE 28 +#define OFFSET_BOOTINFO_SCACHE_SIZE 32 +#define OFFSET_BOOTINFO_SCACHE_LINESIZE 36 +#define OFFSET_BOOTINFO_TLB_ENTRIES 40 +#define OFFSET_BOOTINFO_DMA_CACHE_SIZE 44 +#define OFFSET_BOOTINFO_DMA_CACHE_BASE 48 +#define OFFSET_BOOTINFO_RAMDISK_SIZE 52 +#define OFFSET_BOOTINFO_RAMDISK_BASE 56 +#define OFFSET_BOOTINFO_VRAM_BASE 60 +#define OFFSET_BOOTINFO_COMMAND_LINE 64 + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_MIPS_BOOTINFO_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/bugs.h linux/include/asm-mips/bugs.h --- v1.1.81/linux/include/asm-mips/bugs.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/bugs.h Mon Jan 16 00:54:27 1995 @@ -0,0 +1,36 @@ +/* + * include/asm-mips/bugs.h + * + * Copyright (C) 1995 Waldorf Electronics + * written by Ralf Baechle + */ +#include + +/* + * This is included by init/main.c to check for architecture-dependent bugs. + * + * Needs: + * void check_bugs(void); + */ + +extern struct bootinfo boot_info; + +static void check_wait(void) +{ + printk("Checking for 'wait' instruction... "); + switch(boot_info.cputype) { + case CPU_R4200: + case CPU_R4600: + wait_available = 1; + printk(" available.\n"); + break; + default: + printk(" unavailable.\n"); + break; + } +} + +static void check_bugs(void) +{ + check_wait(); +} diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/byteorder.h linux/include/asm-mips/byteorder.h --- v1.1.81/linux/include/asm-mips/byteorder.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/byteorder.h Sat Jan 14 02:27:06 1995 @@ -0,0 +1,82 @@ +#ifndef __ASM_MIPS_BYTEORDER_H +#define __ASM_MIPS_BYTEORDER_H + +#undef ntohl +#undef ntohs +#undef htonl +#undef htons + +extern unsigned long int ntohl(unsigned long int); +extern unsigned short int ntohs(unsigned short int); +extern unsigned long int htonl(unsigned long int); +extern unsigned short int htons(unsigned short int); + +extern unsigned long int __ntohl(unsigned long int); +extern unsigned short int __ntohs(unsigned short int); +extern unsigned long int __constant_ntohl(unsigned long int); +extern unsigned short int __constant_ntohs(unsigned short int); + +/* + * The constant and non-constant versions here are the same. + * Maybe I'll come up with an mips-optimized routine for the + * non-constant ones (the constant ones don't need it: gcc + * will optimize it to the correct constant) + */ + +extern __inline__ unsigned long int +__ntohl(unsigned long int x) +{ + return (((x & 0x000000ffU) << 24) | + ((x & 0x0000ff00U) << 8) | + ((x & 0x00ff0000U) >> 8) | + ((x & 0xff000000U) >> 24)); +} + +extern __inline__ unsigned long int +__constant_ntohl(unsigned long int x) +{ + return (((x & 0x000000ffU) << 24) | + ((x & 0x0000ff00U) << 8) | + ((x & 0x00ff0000U) >> 8) | + ((x & 0xff000000U) >> 24)); +} + +extern __inline__ unsigned short int +__ntohs(unsigned short int x) +{ + return (((x & 0x00ff) << 8) | + ((x & 0xff00) >> 8)); +} + +extern __inline__ unsigned short int +__constant_ntohs(unsigned short int x) +{ + return (((x & 0x00ff) << 8) | + ((x & 0xff00) >> 8)); +} + +#define __htonl(x) __ntohl(x) +#define __htons(x) __ntohs(x) +#define __constant_htonl(x) __constant_ntohl(x) +#define __constant_htons(x) __constant_ntohs(x) + +#ifdef __OPTIMIZE__ +# define ntohl(x) \ +(__builtin_constant_p((long)(x)) ? \ + __constant_ntohl((x)) : \ + __ntohl((x))) +# define ntohs(x) \ +(__builtin_constant_p((short)(x)) ? \ + __constant_ntohs((x)) : \ + __ntohs((x))) +# define htonl(x) \ +(__builtin_constant_p((long)(x)) ? \ + __constant_htonl((x)) : \ + __htonl((x))) +# define htons(x) \ +(__builtin_constant_p((short)(x)) ? \ + __constant_htons((x)) : \ + __htons((x))) +#endif + +#endif /* __ASM_MIPS_BYTEORDER_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/cachectl.h linux/include/asm-mips/cachectl.h --- v1.1.81/linux/include/asm-mips/cachectl.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/cachectl.h Fri Jan 13 20:28:54 1995 @@ -0,0 +1,32 @@ +/* + * include/asm-mips/cachectl.h + * + * Written by Ralf Baechle, + * Copyright (C) 1994 by Waldorf GMBH + * + * Defines for Risc/OS compatible cacheflush systemcall + */ +#ifndef __ASM_MIPS_CACHECTL +#define __ASM_MIPS_CACHECTL + +/* + * cachectl.h -- defines for MIPS cache control system calls + */ + +/* + * Options for cacheflush system call + */ +#define ICACHE (1<<0) /* flush instruction cache */ +#define DCACHE (1<<1) /* writeback and flush data cache */ +#define BCACHE (ICACHE|DCACHE) /* flush both caches */ + +#define CACHELINES 512 /* number of cachelines */ + +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +extern int sys_cacheflush(void *addr, int nbytes, int cache); + +#endif +#endif +#endif /* __ASM_MIPS_CACHECTL */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/delay.h linux/include/asm-mips/delay.h --- v1.1.81/linux/include/asm-mips/delay.h Mon Aug 15 12:24:19 1994 +++ linux/include/asm-mips/delay.h Fri Jan 13 20:42:03 1995 @@ -1,13 +1,17 @@ -#ifndef _MIPS_DELAY_H -#define _MIPS_DELAY_H +#ifndef __ASM_MIPS_DELAY_H +#define __ASM_MIPS_DELAY_H extern __inline__ void __delay(int loops) { - __asm__(".align 3\n" - "1:\tbeq\t$0,%0,1b\n\t" - "addiu\t%0,%0,-1\n\t" - : - :"d" (loops)); + __asm__ __volatile__ ( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "1:\tbne\t$0,%0,1b\n\t" + "subu\t%0,%0,1\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (loops) + :"0" (loops)); } /* @@ -24,10 +28,18 @@ { usecs *= 0x000010c6; /* 2**32 / 1000000 */ __asm__("mul\t%0,%0,%1" - :"=d" (usecs) - :"0" (usecs),"d" (loops_per_sec) - :"ax"); + :"=r" (usecs) + :"0" (usecs),"r" (loops_per_sec)); __delay(usecs); } -#endif /* defined(_MIPS_DELAY_H) */ +/* + * 64-bit integers means we don't have to worry about overflow as + * on some other architectures.. + */ +extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c) +{ + return (a*b)/c; +} + +#endif /* __ASM_MIPS_DELAY_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/dma.h linux/include/asm-mips/dma.h --- v1.1.81/linux/include/asm-mips/dma.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/dma.h Sun Jan 15 22:26:01 1995 @@ -0,0 +1,274 @@ +/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $ + * linux/include/asm/dma.h: Defines for using and allocating dma channels. + * Written by Hennus Bergman, 1992. + * High DMA channel support & info by Hannu Savolainen + * and John Boyd, Nov. 1992. + */ + +#ifndef __ASM_MIPS_DMA_H +#define __ASM_MIPS_DMA_H + +#include /* need byte IO */ + + +#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER +#define dma_outb outb_p +#else +#define dma_outb outb +#endif + +#define dma_inb inb + +/* + * NOTES about DMA transfers: + * + * controller 1: channels 0-3, byte operations, ports 00-1F + * controller 2: channels 4-7, word operations, ports C0-DF + * + * - ALL registers are 8 bits only, regardless of transfer size + * - channel 4 is not used - cascades 1 into 2. + * - channels 0-3 are byte - addresses/counts are for physical bytes + * - channels 5-7 are word - addresses/counts are for physical words + * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries + * - transfer count loaded to registers is 1 less than actual count + * - controller 2 offsets are all even (2x offsets for controller 1) + * - page registers for 5-7 don't use data bit 0, represent 128K pages + * - page registers for 0-3 use bit 0, represent 64K pages + * + * DMA transfers are limited to the lower 16MB of _physical_ memory. + * Note that addresses loaded into registers must be _physical_ addresses, + * not logical addresses (which may differ if paging is active). + * + * Address mapping for channels 0-3: + * + * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * P7 ... P0 A7 ... A0 A7 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Address mapping for channels 5-7: + * + * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) + * | ... | \ \ ... \ \ \ ... \ \ + * | ... | \ \ ... \ \ \ ... \ (not used) + * | ... | \ \ ... \ \ \ ... \ + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses + * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at + * the hardware level, so odd-byte transfers aren't possible). + * + * Transfer count (_not # bytes_) is limited to 64K, represented as actual + * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, + * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * + */ + +#define MAX_DMA_CHANNELS 8 + +/* The maximum address that we can perform a DMA transfer to on this platform */ +#define MAX_DMA_ADDRESS 0x1000000 + +/* The maximum address that we can perform a DMA transfer to on this platform */ +#define MAX_DMA_ADDRESS 0x1000000 + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG 0x08 /* command register (w) */ +#define DMA1_STAT_REG 0x08 /* status register (r) */ +#define DMA1_REQ_REG 0x09 /* request register (w) */ +#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ +#define DMA1_MODE_REG 0x0B /* mode register (w) */ +#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ +#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ +#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ + +#define DMA2_CMD_REG 0xD0 /* command register (w) */ +#define DMA2_STAT_REG 0xD0 /* status register (r) */ +#define DMA2_REQ_REG 0xD2 /* request register (w) */ +#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ +#define DMA2_MODE_REG 0xD6 /* mode register (w) */ +#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ +#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ +#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ + +#define DMA_ADDR_0 0x00 /* DMA address registers */ +#define DMA_ADDR_1 0x02 +#define DMA_ADDR_2 0x04 +#define DMA_ADDR_3 0x06 +#define DMA_ADDR_4 0xC0 +#define DMA_ADDR_5 0xC4 +#define DMA_ADDR_6 0xC8 +#define DMA_ADDR_7 0xCC + +#define DMA_CNT_0 0x01 /* DMA count registers */ +#define DMA_CNT_1 0x03 +#define DMA_CNT_2 0x05 +#define DMA_CNT_3 0x07 +#define DMA_CNT_4 0xC2 +#define DMA_CNT_5 0xC6 +#define DMA_CNT_6 0xCA +#define DMA_CNT_7 0xCE + +#define DMA_PAGE_0 0x87 /* DMA page registers */ +#define DMA_PAGE_1 0x83 +#define DMA_PAGE_2 0x81 +#define DMA_PAGE_3 0x82 +#define DMA_PAGE_5 0x8B +#define DMA_PAGE_6 0x89 +#define DMA_PAGE_7 0x8A + +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr, DMA1_MASK_REG); + else + dma_outb(dmanr & 3, DMA2_MASK_REG); +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr | 4, DMA1_MASK_REG); + else + dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(0, DMA1_CLEAR_FF_REG); + else + dma_outb(0, DMA2_CLEAR_FF_REG); +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + if (dmanr<=3) + dma_outb(mode | dmanr, DMA1_MODE_REG); + else + dma_outb(mode | (dmanr&3), DMA2_MODE_REG); +} + +/* Set only the page register bits of the transfer address. + * This is used for successive transfers when we know the contents of + * the lower 16 bits of the DMA current address register, but a 64k boundary + * may have been crossed. + */ +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +{ + switch(dmanr) { + case 0: + dma_outb(pagenr, DMA_PAGE_0); + break; + case 1: + dma_outb(pagenr, DMA_PAGE_1); + break; + case 2: + dma_outb(pagenr, DMA_PAGE_2); + break; + case 3: + dma_outb(pagenr, DMA_PAGE_3); + break; + case 5: + dma_outb(pagenr & 0xfe, DMA_PAGE_5); + break; + case 6: + dma_outb(pagenr & 0xfe, DMA_PAGE_6); + break; + case 7: + dma_outb(pagenr & 0xfe, DMA_PAGE_7); + break; + } +} + + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + set_dma_page(dmanr, a>>16); + if (dmanr <= 3) { + dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + } else { + dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + } +} + + +/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + } else { + dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + } +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE + : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + + /* using short to get 16-bit wrap around */ + unsigned short count; + + count = 1 + dma_inb(io_port); + count += dma_inb(io_port) << 8; + + return (dmanr<=3)? count : (count<<1); +} + + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + + +#endif /* __ASM_MIPS_DMA_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/head.h linux/include/asm-mips/head.h --- v1.1.81/linux/include/asm-mips/head.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/head.h Fri Jan 13 20:41:25 1995 @@ -0,0 +1,9 @@ +#ifndef __ASM_MIPS_HEAD_H +#define __ASM_MIPS_HEAD_H + +#include + +extern unsigned long swapper_pg_dir[1024]; +extern ulong IRQ_vectors[]; + +#endif /* __ASM_MIPS_HEAD_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/io.h linux/include/asm-mips/io.h --- v1.1.81/linux/include/asm-mips/io.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/io.h Sun Jan 15 23:05:43 1995 @@ -0,0 +1,241 @@ +#ifndef __ASM_MIPS_IO_H +#define __ASM_MIPS_IO_H + +#include +#include + +/* + * This file contains the definitions for the MIPS counterpart of the + * x86 in/out instructions. This heap of macros and C results in much + * better code than the approach of doing it in plain C, though that's + * probably not needed. + * + * Ralf + * + * This file contains the definitions for the x86 IO instructions + * inb/inw/inl/outb/outw/outl and the "string versions" of the same + * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" + * versions of the single-IO instructions (inb_p/inw_p/..). + * + * This file is not meant to be obfuscating: it's just complicated + * to (a) handle it all in a way that makes gcc able to optimize it + * as well as possible and (b) trying to avoid writing the same thing + * over and over again with slight variations and possibly making a + * mistake somewhere. + */ + +/* + * Thanks to James van Artsdalen for a better timing-fix than + * the two short jumps: using outb's to a nonexistent port seems + * to guarantee better timings even on fast machines. + * + * On the other hand, I'd like to be sure of a non-existent port: + * I feel a bit unsafe about using 0x80 (should be safe, though) + * + * Linus + */ + +#define __SLOW_DOWN_IO \ + __asm__ __volatile__( \ + "sb\t$0,0x80(%0)" \ + : : "r" (PORT_BASE)); + +#ifdef REALLY_SLOW_IO +#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; } +#else +#define SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + +/* + * Talk about misusing macros.. + */ + +#define __OUT1(s) \ +extern inline void __out##s(unsigned int value, unsigned int port) { + +#define __OUT2(m) \ +__asm__ __volatile__ ("s" #m "\t%0,%1(%2)" + +#define __OUT(m,s) \ +__OUT1(s) __OUT2(m) : : "r" (value), "i" (0), "r" (PORT_BASE+port)); } \ +__OUT1(s##c) __OUT2(m) : : "r" (value), "i" (port), "r" (PORT_BASE)); } \ +__OUT1(s##_p) __OUT2(m) : : "r" (value), "i" (0), "r" (PORT_BASE+port)); \ + SLOW_DOWN_IO; } \ +__OUT1(s##c_p) __OUT2(m) : : "r" (value), "i" (port), "r" (PORT_BASE)); \ + SLOW_DOWN_IO; } + +#define __IN1(s) \ +extern inline unsigned int __in##s(unsigned int port) { unsigned int _v; + +#define __IN2(m) \ +__asm__ __volatile__ ("l" #m "u\t%0,%1(%2)\n\t" + +#define __IN(m,s) \ +__IN1(s) __IN2(m) STR(FILL_LDS) : "=r" (_v) : "i" (0), "r" (PORT_BASE+port)); return _v; } \ +__IN1(s##c) __IN2(m) STR(FILL_LDS) : "=r" (_v) : "i" (port), "r" (PORT_BASE)); return _v; } \ +__IN1(s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (PORT_BASE+port)); SLOW_DOWN_IO; return _v; } \ +__IN1(s##c_p) __IN2(m) : "=r" (_v) : "i" (port), "r" (PORT_BASE)); SLOW_DOWN_IO; return _v; } + +#define __INS1(s) \ +extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) { + +#define __INS2(m) \ +__asm__ __volatile__ ( \ + ".set\tnoreorder\n\t" \ + ".set\tnoat\n" \ + "1:\tl" #m "u\t$1,%4(%5)\n\t" \ + "subu\t%1,%1,1\n\t" \ + "s" #m "\t$1,(%0)\n\t" \ + "bne\t$0,%1,1b\n\t" \ + "addiu\t%0,%0,%6\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" + +#define __INS(m,s,i) \ +__INS1(s) __INS2(m) \ + : "=r" (addr), "=r" (count) \ + : "0" (addr), "1" (count), "i" (0), "r" (PORT_BASE+port), "I" (i) \ + : "$1");} \ +__INS1(s##c) __INS2(m) \ + : "=r" (addr), "=r" (count) \ + : "0" (addr), "1" (count), "i" (port), "r" (PORT_BASE), "I" (i) \ + : "$1");} + +#define __OUTS1(s) \ +extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) { + +#define __OUTS2(m) \ +__asm__ __volatile__ ( \ + ".set\tnoreorder\n\t" \ + ".set\tnoat\n" \ + "1:\tl" #m "u\t$1,(%0)\n\t" \ + "subu\t%1,%1,1\n\t" \ + "s" #m "\t$1,%4(%5)\n\t" \ + "bne\t$0,%1,1b\n\t" \ + "addiu\t%0,%0,%6\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" + +#define __OUTS(m,s,i) \ +__OUTS1(s) __OUTS2(m) \ + : "=r" (addr), "=r" (count) \ + : "0" (addr), "1" (count), "i" (0), "r" (PORT_BASE+port), "I" (i) \ + : "$1");} \ +__OUTS1(s##c) __OUTS2(m) \ + : "=r" (addr), "=r" (count) \ + : "0" (addr), "1" (count), "i" (port), "r" (PORT_BASE), "I" (i) \ + : "$1");} + +__IN(b,b) +__IN(h,w) +__IN(w,l) + +__OUT(b,b) +__OUT(h,w) +__OUT(w,l) + +__INS(b,b,1) +__INS(h,w,2) +__INS(w,l,4) + +__OUTS(b,b,1) +__OUTS(h,w,2) +__OUTS(w,l,4) + +/* + * Note that due to the way __builtin_constant_p() works, you + * - can't use it inside a inline function (it will never be true) + * - you don't have to worry about side effects within the __builtin.. + */ +#define outb(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outbc((val),(port)) : \ + __outb((val),(port))) + +#define inb(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inbc(port) : \ + __inb(port)) + +#define outb_p(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outbc_p((val),(port)) : \ + __outb_p((val),(port))) + +#define inb_p(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inbc_p(port) : \ + __inb_p(port)) + +#define outw(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outwc((val),(port)) : \ + __outw((val),(port))) + +#define inw(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inwc(port) : \ + __inw(port)) + +#define outw_p(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outwc_p((val),(port)) : \ + __outw_p((val),(port))) + +#define inw_p(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inwc_p(port) : \ + __inw_p(port)) + +#define outl(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outlc((val),(port)) : \ + __outl((val),(port))) + +#define inl(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inlc(port) : \ + __inl(port)) + +#define outl_p(val,port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outlc_p((val),(port)) : \ + __outl_p((val),(port))) + +#define inl_p(port) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inlc_p(port) : \ + __inl_p(port)) + + +#define outsb(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outsbc((port),(addr),(count)) : \ + __outsb ((port),(addr),(count))) + +#define insb(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __insbc((port),(addr),(count)) : \ + __insb((port),(addr),(count))) + +#define outsw(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outswc((port),(addr),(count)) : \ + __outsw ((port),(addr),(count))) + +#define insw(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inswc((port),(addr),(count)) : \ + __insw((port),(addr),(count))) + +#define outsl(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __outslc((port),(addr),(count)) : \ + __outsl ((port),(addr),(count))) + +#define insl(port,addr,count) \ +((__builtin_constant_p((port)) && (port) < 32768) ? \ + __inslc((port),(addr),(count)) : \ + __insl((port),(addr),(count))) + +#endif /* __ASM_MIPS_IO_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/irq.h linux/include/asm-mips/irq.h --- v1.1.81/linux/include/asm-mips/irq.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/irq.h Fri Jan 13 20:39:49 1995 @@ -0,0 +1,18 @@ +/* + * include/asm-mips/irq.h + * + * 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 by Waldorf GMBH + * written by Ralf Baechle + * + */ +#ifndef __ASM_MIPS_IRQ_H +#define __ASM_MIPS_IRQ_H + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +#endif /* __ASM_MIPS_IRQ_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/mipsconfig.h linux/include/asm-mips/mipsconfig.h --- v1.1.81/linux/include/asm-mips/mipsconfig.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/mipsconfig.h Wed Jan 11 21:44:47 1995 @@ -0,0 +1,44 @@ +/* + * linux/include/asm-mips/mipsconfig.h + * + * 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 + * + */ +#ifndef __ASM_MIPS_MIPS_CONFIG_H +#define __ASM_MIPS_MIPS_CONFIG_H + +/* + * This is the virtual adress to which all ports are being mapped. + * Must be a value that can be load with a lui instruction. + */ +#define PORT_BASE 0xe0000000 + +/* #define NUMBER_OF_TLB_ENTRIES 48 */ /* see bootinfo.h -- Andy */ +#define NUMBER_OF_TLB_ENTRIES 48 + +/* + * Pagetables are 4MB mapped at 0xe3000000 + * Must be a value that can be load with a lui instruction. + */ +#define TLBMAP 0xe4000000 + +/* + * The virtual address where we'll map the pagetables + * For a base address of 0xe3000000 this is 0xe338c000 + * For a base address of 0xe4000000 this is 0xe4390000 + * FIXME: Gas misscomputes the following expression! +#define TLB_ROOT (TLBMAP + (TLBMAP >> (12-2))) + */ +#define TLB_ROOT 0xe4390000 + +/* + * This ASID is reserved for the swapper + */ +#define SWAPPER_ASID 0 + +#endif /* __ASM_MIPS_MIPS_CONFIG_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/mipsregs.h linux/include/asm-mips/mipsregs.h --- v1.1.81/linux/include/asm-mips/mipsregs.h Fri Aug 19 08:53:37 1994 +++ linux/include/asm-mips/mipsregs.h Fri Jan 13 18:02:45 1995 @@ -8,8 +8,8 @@ * Copyright (C) 1994 by Ralf Baechle */ -#ifndef _ASM_MIPS_MIPSREGS_H_ -#define _ASM_MIPS_MIPSREGS_H_ +#ifndef __ASM_MIPS_MIPSREGS_H +#define __ASM_MIPS_MIPSREGS_H /* * The following macros are especially useful for __asm__ @@ -24,6 +24,19 @@ #endif /* + * On the R2000/3000 load instructions are not interlocked - + * we therefore sometimes need to fill load delay slots with a nop + * which are useless for >=R4000. + * + * FIXME: Don't know about R6000 + */ +#if !defined (__R4000__) +#define FILL_LDS nop +#else +#define FILL_LDS +#endif + +/* * Coprocessor 0 register names */ #define CP0_INDEX $0 @@ -53,15 +66,15 @@ #define CP0_ERROREPC $30 /* - * Values for pagemask register + * Values for PageMask register */ -#define PM_4K 0x000000000 -#define PM_16K 0x000060000 -#define PM_64K 0x0001e0000 -#define PM_256K 0x0007e0000 -#define PM_1M 0x001fe0000 -#define PM_4M 0x007fe0000 -#define PM_16M 0x01ffe0000 +#define PM_4K 0x00000000 +#define PM_16K 0x00006000 +#define PM_64K 0x0001e000 +#define PM_256K 0x0007e000 +#define PM_1M 0x001fe000 +#define PM_4M 0x007fe000 +#define PM_16M 0x01ffe000 /* * Values used for computation of new tlb entries @@ -80,4 +93,83 @@ #define VPN(addr,pagesizeshift) ((addr) & ~((1 << (pagesizeshift))-1)) #define PFN(addr,pagesizeshift) (((addr) & ((1 << (pagesizeshift))-1)) << 6) -#endif /* _ASM_MIPS_MIPSREGS_H_ */ +/* + * Macros to access the system control copprocessor + */ +#define read_32bit_cp0_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + "mfc0\t%0,"STR(source) \ + : "=r" (__res)); \ + __res;}) + +#define read_64bit_cp0_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + "dmfc0\t%0,"STR(source) \ + : "=r" (__res)); \ + __res;}) + +#define write_32bit_cp0_register(register,value) \ + __asm__ __volatile__( \ + "mtc0\t%0,"STR(register) \ + : : "r" (value)); + +/* + * Inline code for use of the ll and sc instructions + * + * FIXME: This instruction is only available on MIPS ISA >=3. + * Since these operations are only being used for atomic operations + * the easiest workaround for the R[23]00 is to disable interrupts. + */ +#define load_linked(addr) \ +({ \ + unsigned int __res; \ + \ + __asm__ __volatile__( \ + "ll\t%0,(%1)" \ + : "=r" (__res) \ + : "r" ((unsigned int) (addr))); \ + \ + __res; \ +}) + +#define store_conditional(addr,value) \ +({ \ + int __res; \ + \ + __asm__ __volatile__( \ + "sc\t%0,(%2)" \ + : "=r" (__res) \ + : "0" (value), "r" (addr)); \ + \ + __res; \ +}) + +/* + * Bitfields in the cp0 status register + * + * Refer to MIPS R4600 manual, page 5-4 for explanation + */ +#define ST0_IE (1 << 0) +#define ST0_EXL (1 << 1) +#define ST0_ERL (1 << 2) +#define ST0_KSU (3 << 3) +#define ST0_UX (1 << 5) +#define ST0_SX (1 << 6) +#define ST0_KX (1 << 7) +#define ST0_IM (255 << 8) +#define ST0_DE (1 << 16) +#define ST0_CE (1 << 17) +#define ST0_CH (1 << 18) +#define ST0_SR (1 << 20) +#define ST0_BEV (1 << 22) +#define ST0_RE (1 << 25) +#define ST0_FR (1 << 26) +#define ST0_CU (15 << 28) +#define ST0_CU0 (1 << 28) +#define ST0_CU1 (1 << 29) +#define ST0_CU2 (1 << 30) +#define ST0_CU3 (1 << 31) + +#endif /* __ASM_MIPS_MIPSREGS_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/mm.h linux/include/asm-mips/mm.h --- v1.1.81/linux/include/asm-mips/mm.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/mm.h Sun Jan 15 22:17:57 1995 @@ -0,0 +1,58 @@ +#ifndef __ASM_MIPS_MM_H +#define __ASM_MIPS_MM_H + +#if defined (__KERNEL__) + +/* + * Note that we shift the lower 32bits of each EntryLo[01] entry + * 6 bits to the left. That way we can convert the PFN into the + * physical address by a single 'and' operation and gain 6 aditional + * bits for storing information which isn't present in a normal + * MIPS page table. + * I've also changed the naming of some bits so that they conform + * the i386 naming as much as possible. + * PAGE_USER isn't implemented in software yet. + */ +#define PAGE_PRESENT (1<<0) /* implemented in software */ +#define PAGE_COW (1<<1) /* implemented in software */ +#define PAGE_DIRTY (1<<2) /* implemented in software */ +#define PAGE_USER (1<<3) /* implemented in software */ +#define PAGE_UNUSED1 (1<<4) /* implemented in software */ +#define PAGE_UNUSED2 (1<<5) /* implemented in software */ +#define PAGE_GLOBAL (1<<6) +#define PAGE_ACCESSED (1<<7) /* The Mips valid bit */ +#define PAGE_RW (1<<8) /* The Mips dirty bit */ +#define CACHE_CACHABLE_NO_WA (0<<9) +#define CACHE_CACHABLE_WA (1<<9) +#define CACHE_UNCACHED (2<<9) +#define CACHE_CACHABLE_NONCOHERENT (3<<9) +#define CACHE_CACHABLE_CE (4<<9) +#define CACHE_CACHABLE_COW (5<<9) +#define CACHE_CACHABLE_CUW (6<<9) +#define CACHE_MASK (7<<9) + +#define PAGE_PRIVATE (PAGE_PRESENT | PAGE_ACCESSED | PAGE_DIRTY | PAGE_RW | \ + PAGE_COW | CACHE_CACHABLE_NO_WA) +#define PAGE_SHARED (PAGE_PRESENT | PAGE_ACCESSED | PAGE_DIRTY | PAGE_RW | \ + CACHE_CACHABLE_NO_WA) +#define PAGE_COPY (PAGE_PRESENT | PAGE_ACCESSED | PAGE_COW | \ + CACHE_CACHABLE_NO_WA) +#define PAGE_READONLY (PAGE_PRESENT | PAGE_ACCESSED | CACHE_CACHABLE_NO_WA) +#define PAGE_TABLE (PAGE_PRESENT | PAGE_ACCESSED | PAGE_DIRTY | PAGE_RW | \ + CACHE_CACHABLE_NO_WA) + +#ifndef __ASSEMBLY__ + +#include + +extern unsigned long invalid_pg_table[1024]; + +/* + * memory.c & swap.c + */ +extern void mem_init(unsigned long start_mem, unsigned long end_mem); +#endif /* !defined (__ASSEMBLY__) */ + +#endif /* defined (__KERNEL__) */ + +#endif /* __ASM_MIPS_MM_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/page.h linux/include/asm-mips/page.h --- v1.1.81/linux/include/asm-mips/page.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/page.h Sun Jan 15 23:20:08 1995 @@ -0,0 +1,55 @@ +#ifndef __ASM_MIPS_PAGE_H +#define __ASM_MIPS_PAGE_H + +#include + +#ifndef __ASSEMBLY__ +#define invalidate() tlbflush(); +extern asmlinkage void tlbflush(void); +#endif + + /* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PGDIR_SHIFT 22 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) + +#ifdef __KERNEL__ + + /* number of bits that fit into a memory pointer */ +#define BITS_PER_PTR (8*sizeof(unsigned long)) + /* to mask away the intra-page address bits */ +#define PAGE_MASK (~(PAGE_SIZE-1)) + /* to mask away the intra-page address bits */ +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + /* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + /* to align the pointer to a pointer address */ +#define PTR_MASK (~(sizeof(void*)-1)) + + /* sizeof(void*)==1<> 22) + (unsigned long *) (tsk)->tss.pg_dir) + +/* to find an entry in a page-table */ +#define PAGE_PTR(address) \ +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) + +/* the no. of pointers that fit on a page */ +#define PTRS_PER_PAGE (PAGE_SIZE/sizeof(void*)) + +/* to set the page-dir */ +#define SET_PAGE_DIR(tsk,pgdir) \ +do { \ + (tsk)->tss.pg_dir = (unsigned long) (pgdir); \ + if ((tsk) == current) \ + invalidate(); \ +} while (0) + +#endif /* __KERNEL__ */ + +#endif /* __ASM_MIPS_PAGE_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/processor.h linux/include/asm-mips/processor.h --- v1.1.81/linux/include/asm-mips/processor.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/processor.h Sun Jan 15 22:37:05 1995 @@ -0,0 +1,219 @@ +/* + * include/asm-mips/processor.h + * + * Copyright (C) 1994 Waldorf Electronics + * written by Ralf Baechle + */ + +#ifndef __ASM_MIPS_PROCESSOR_H +#define __ASM_MIPS_PROCESSOR_H + +#if !defined (__ASSEMBLY__) +#include + +/* + * System setup and hardware bug flags.. + */ +extern char wait_available; /* only available on R4[26]00 */ + +extern unsigned long intr_count; +extern unsigned long event; + +#if defined (__R4000__) + +#define start_bh_atomic() \ +__asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + ".set\tnoat\n\t" \ + "ll\t$1,(%0)\n" \ + "1:\taddiu\t$1,$1,1\n\t" \ + "sc\t$1,(%0)\n\t" \ + "beqzl\t$1,1b\n\t" \ + "ll\t$1,(%0)\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" \ + : /* no outputs */ \ + : "r" (&intr_count)); + +#define end_bh_atomic() \ +__asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + ".set\tnoat\n\t" \ + "ll\t$1,(%0)\n" \ + "1:\tsubu\t$1,$1,1\n\t" \ + "sc\t$1,(%0)\n\t" \ + "beqzl\t$1,1b\n\t" \ + "ll\t$1,(%0)\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" \ + : /* no outputs */ \ + : "r" (&intr_count)); + +#else /* !defined (__R4000__) */ + +#define start_bh_atomic() \ +{int flags; save_flags(flags); cli(); intr_count++; restore_flags(flags)} + +#define end_bh_atomic() \ +{int flags; save_flags(flags); cli(); intr_count--; restore_flags(flags)} + +#endif + +/* + * Bus types (default is ISA, but people can check others with these..) + * MCA_bus hardcoded to 0 for now. + * + * This needs to be extended since MIPS systems are being delivered with + * numerous different types of bus systems. + */ +extern int EISA_bus; +#define MCA_bus 0 + +/* + * MIPS has no problems with write protection + */ +#define wp_works_ok 1 + +/* + * User space process size: 2GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +#define TASK_SIZE 0x80000000 + +/* + * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. + */ +#define IO_BITMAP_SIZE 32 + +#define NUM_FPU_REGS 32 + +struct mips_fpu_hard_struct { + double fp_regs[NUM_FPU_REGS]; + unsigned int control; +}; + +/* + * FIXME: no fpu emulator yet (but who cares anyway?) + */ +struct mips_fpu_soft_struct { + long dummy; + }; + +union mips_fpu_union { + struct mips_fpu_hard_struct hard; + struct mips_fpu_soft_struct soft; +}; + +#define INIT_FPU { \ + 0, \ +} + +/* + * If you change thread_struct remember to change the #defines below too! + */ +struct thread_struct { + /* + * saved main processor registers + */ + unsigned long reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23; + unsigned long reg28, reg29, reg30, reg31; + /* + * saved cp0 stuff + */ + unsigned long cp0_status; + /* + * saved fpu/fpu emulator stuff + */ + union mips_fpu_union fpu; + /* + * Other stuff associated with the process + */ + unsigned long cp0_badvaddr; + unsigned long error_code; + unsigned long trap_no; + unsigned long ksp; /* Top of kernel stack */ + unsigned long fs; /* "Segment" pointer */ + unsigned long pg_dir; /* L1 page table pointer */ +}; + +#endif /* !defined (__ASSEMBLY__) */ + +/* + * If you change the #defines remember to change thread_struct above too! + */ +#define TOFF_REG16 0 +#define TOFF_REG17 (TOFF_REG16+4) +#define TOFF_REG18 (TOFF_REG17+4) +#define TOFF_REG19 (TOFF_REG18+4) +#define TOFF_REG20 (TOFF_REG19+4) +#define TOFF_REG21 (TOFF_REG20+4) +#define TOFF_REG22 (TOFF_REG21+4) +#define TOFF_REG23 (TOFF_REG22+4) +#define TOFF_REG28 (TOFF_REG23+4) +#define TOFF_REG29 (TOFF_REG28+4) +#define TOFF_REG30 (TOFF_REG29+4) +#define TOFF_REG31 (TOFF_REG30+4) +#define TOFF_CP0_STATUS (TOFF_REG31+4) +/* + * Pad for 8 byte boundary! + */ +#define TOFF_FPU (((TOFF_CP0_STATUS+4)+(8-1))&~(8-1)) +#define TOFF_CP0_BADVADDR (TOFF_FPU+264) +#define TOFF_ERROR_CODE (TOFF_CP0_BADVADDR+4) +#define TOFF_TRAP_NO (TOFF_ERROR_CODE+4) +#define TOFF_KSP (TOFF_TRAP_NO+4) +#define TOFF_FS (TOFF_KSP+4) +#define TOFF_PG_DIR (TOFF_FS+4) + +#if !defined (__ASSEMBLY__) + +#define INIT_TSS { \ + /* \ + * saved main processor registers \ + */ \ + 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, \ + /* \ + * saved cp0 stuff \ + */ \ + 0, \ + /* \ + * saved fpu/fpu emulator stuff \ + */ \ + INIT_FPU, \ + /* \ + * Other stuff associated with the process\ + */ \ + 0, 0, 0, (((unsigned long)init_kernel_stack)+4096-8), \ + KERNEL_DS, (unsigned long) swapper_pg_dir \ +} + +#ifdef __KERNEL__ + +/* + * switch_to(n) should switch tasks to task nr n, first + * checking that n isn't the current task, in which case it does nothing. + */ +asmlinkage void resume(struct task_struct *tsk, int offset); + +#define switch_to(n) \ + resume(n, ((int)(&((struct task_struct *)0)->tss))) + +/* + * Does the process account for user or for system time? + */ +#if defined (__R4000__) + +#define USES_USER_TIME(regs) (!((regs)->cp0_status & 0x18)) + +#else /* !defined (__R4000__) */ + +#error "#define USES_USER_TIME(regs)!" + +#endif /* !defined (__R4000__) */ + +#endif /* __KERNEL__ */ + +#endif /* !defined (__ASSEMBLY__) */ + +#endif /* __ASM_MIPS_PROCESSOR_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/ptrace.h linux/include/asm-mips/ptrace.h --- v1.1.81/linux/include/asm-mips/ptrace.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/ptrace.h Fri Jan 13 23:35:52 1995 @@ -0,0 +1,81 @@ +/* + * linux/include/asm-mips/ptrace.h + * + * machine dependend structs and defines to help the user use + * the ptrace system call. + */ +#ifndef __ASM_MIPS_PTRACE_H +#define __ASM_MIPS_PTRACE_H + +/* + * use ptrace (3 or 6, pid, PT_EXCL, data); to read or write + * the processes registers. + * + * This defines/structures corrospond to the register layout on stack - + * if the order here is changed, it needs to be updated in + * arch/mips/fork.c:copy_process, asm/mips/signal.c:do_signal, + * asm-mips/ptrace.c, include/asm-mips/ptrace.h. + */ + +#include + +/* + * This struct defines the way the registers are stored on the + * stack during a system call/exception. As usual the registers + * k0/k1 aren't being saved. + */ +struct pt_regs { + /* + * Pad bytes for argument save space on the stack + */ + unsigned long pad0[FR_REG1/sizeof(unsigned long)]; + + /* + * saved main processor registers + */ + long reg1, reg2, reg3, reg4, reg5, reg6, reg7; + long reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15; + long reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23; + long reg24, reg25, reg28, reg29, reg30, reg31; + + /* + * Saved special registers + */ + long lo; + long hi; + + /* + * saved cp0 registers + */ + unsigned long cp0_status; + unsigned long cp0_epc; + unsigned long cp0_cause; + + /* + * Some goodies... + */ + unsigned long interrupt; + long orig_reg2; +}; + +#ifdef __KERNEL__ +/* + * Does the process account for user or for system time? + */ +#if defined (__R4000__) + +#define user_mode(regs) (!((regs)->cp0_status & 0x18)) + +#else /* !defined (__R4000__) */ + +#error "#define user_mode(regs) for R3000!" + +#endif /* !defined (__R4000__) */ +#endif /* __KERNEL */ + +/* + * This function computes the interrupt number from the stack frame + */ +#define pt_regs2irq(p) ((int) ((struct pt_regs *)p)->interrupt) + +#endif /* __ASM_MIPS_PTRACE_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/regdef.h linux/include/asm-mips/regdef.h --- v1.1.81/linux/include/asm-mips/regdef.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/regdef.h Fri Jan 13 20:38:36 1995 @@ -0,0 +1,50 @@ +/* + * include/asm-mips/regdefs.h + * + * 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 by Ralf Baechle + */ + +#ifndef __ASM_MIPS_REGSDEFS_H +#define __ASM_MIPS_REGSDEFS_H + +/* + * Symbolic register names + */ +#define zero $0 /* wired zero */ +#define AT $1 /* assembler temp (uprcase, because ".set at") */ +#define v0 $2 /* return value */ +#define v1 $3 +#define a0 $4 /* argument registers */ +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 /* caller saved */ +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define s0 $16 /* callee saved */ +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 /* caller saved */ +#define t9 $25 +#define k0 $26 /* kernel scratch */ +#define k1 $27 +#define gp $28 /* global pointer */ +#define sp $29 /* stack pointer */ +#define fp $30 /* frame pointer */ +#define ra $31 /* return address */ + +#endif /* __ASM_MIPS_REGSDEFS_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/segment.h linux/include/asm-mips/segment.h --- v1.1.81/linux/include/asm-mips/segment.h Sun Nov 27 20:19:54 1994 +++ linux/include/asm-mips/segment.h Sat Jan 14 15:59:50 1995 @@ -8,84 +8,85 @@ * Copyright (C) 1994 by Ralf Baechle * */ +#ifndef __ASM_MIPS_SEGMENT_H +#define __ASM_MIPS_SEGMENT_H -#ifndef _ASM_MIPS_SEGMENT_H_ -#define _ASM_MIPS_SEGMENT_H_ - -static inline unsigned char get_user_byte(const char * addr) -{ - register unsigned char _v; +/* + * Memory segments (32bit kernel mode addresses) + */ +#define KUSEG 0x00000000 +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 +#define KSEG2 0xc0000000 +#define KSEG3 0xe0000000 - __asm__ ("lbu\t%0,%1":"=r" (_v):"r" (*addr)); +/* + * returns the kernel segment base of a given address + * Address space is a scarce resource on a R3000, so + * emulate the Intel segment braindamage... + */ +#define KSEGX(a) (a & 0xe0000000) - return _v; -} +#define KERNEL_CS KERNELBASE +#define KERNEL_DS KERNEL_CS -#define get_fs_byte(addr) get_user_byte((char *)(addr)) +#define USER_CS 0x00000000 +#define USER_DS USER_CS -static inline unsigned short get_user_word(const short *addr) -{ - unsigned short _v; +#ifndef __ASSEMBLY__ - __asm__ ("lhu\t%0,%1":"=r" (_v):"r" (*addr)); +/* + * This variable is defined in arch/mips/kernel/head.S. + */ +extern unsigned long segment_fs; - return _v; +#define get_fs_byte(addr) get_user_byte((char *)(addr)) +static inline unsigned char get_user_byte(const char *addr) +{ + return *(const char *)(((unsigned long)addr)+segment_fs); } #define get_fs_word(addr) get_user_word((short *)(addr)) - -static inline unsigned long get_user_long(const int *addr) +static inline unsigned short get_user_word(const short *addr) { - unsigned long _v; - - __asm__ ("lwu\t%0,%1":"=r" (_v):"r" (*addr)); \ - return _v; + return *(const short *)(((unsigned long)addr)+segment_fs); } #define get_fs_long(addr) get_user_long((int *)(addr)) - -static inline unsigned long get_user_dlong(const int *addr) +static inline unsigned long get_user_long(const int *addr) { - unsigned long _v; - - __asm__ ("ld\t%0,%1":"=r" (_v):"r" (*addr)); \ - return _v; + return *(const int *)(((unsigned long)addr)+segment_fs); } -#define get_fs_dlong(addr) get_user_dlong((int *)(addr)) - -static inline void put_user_byte(char val,char *addr) +#define get_fs_dlong(addr) get_user_dlong((long long *)(addr)) +static inline unsigned long get_user_dlong(const long long *addr) { -__asm__ ("sb\t%0,%1": /* no outputs */ :"r" (val),"r" (*addr)); + return *(const long long *)(((unsigned long)addr)+segment_fs); } #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) - -static inline void put_user_word(short val,short * addr) +static inline void put_user_byte(char val,char *addr) { -__asm__ ("sh\t%0,%1": /* no outputs */ :"r" (val),"r" (*addr)); + *(char *)(((unsigned long)addr)+segment_fs) = val; } #define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) - -static inline void put_user_long(unsigned long val,int * addr) +static inline void put_user_word(short val,short * addr) { -__asm__ ("sw\t%0,%1": /* no outputs */ :"r" (val),"r" (*addr)); + *(short *)(((unsigned long)addr)+segment_fs) = val; } #define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) - -static inline void put_user_dlong(unsigned long val,int * addr) +static inline void put_user_long(unsigned long val,int * addr) { -__asm__ ("sd\t%0,%1": /* no outputs */ :"r" (val),"r" (*addr)); + *(int *)(((unsigned long)addr)+segment_fs) = val; } #define put_fs_dlong(x,addr) put_user_dlong((x),(int *)(addr)) - -/* - * These following two variables are defined in mips/head.S. - */ -extern unsigned long segment_fs; +static inline void put_user_dlong(unsigned long val,long long * addr) +{ + *(long long *)(((unsigned long)addr)+segment_fs) = val; +} static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n) { @@ -101,7 +102,7 @@ ".set\tat\n\t" ".set\treorder" : /* no outputs */ - :"d" (n),"d" (((long) to)| segment_fs),"d" ((long) from) + :"r" (n),"r" (((long) to)| segment_fs),"r" ((long) from) :"$1"); } @@ -152,7 +153,7 @@ ".set\tat\n\t" ".set\treorder" : /* no outputs */ - :"d" (n),"d" ((long) to),"d" (((long) from | segment_fs)) + :"r" (n),"r" ((long) to),"r" (((long) from | segment_fs)) :"$1","memory"); } @@ -214,4 +215,6 @@ segment_fs = val; } -#endif /* _ASM_MIPS_SEGMENT_H_ */ +#endif + +#endif /* __ASM_MIPS_SEGMENT_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/signal.h linux/include/asm-mips/signal.h --- v1.1.81/linux/include/asm-mips/signal.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/signal.h Fri Jan 13 20:38:02 1995 @@ -0,0 +1,20 @@ +#ifndef __ASM_MIPS_SIGNAL_H +#define __ASM_MIPS_SIGNAL_H + +#ifdef __KERNEL__ + +struct sigcontext_struct { + unsigned long sc_at, sc_v0, sc_v1, sc_a0, sc_a1, sc_a2, sc_a3; + unsigned long sc_t0, sc_t1, sc_t2, sc_t3, sc_t4, sc_t5, sc_t6, sc_t7; + unsigned long sc_s0, sc_s1, sc_s2, sc_s3, sc_s4, sc_s5, sc_s6, sc_s7; + unsigned long sc_t8, sc_t9, sc_gp, sc_sp, sc_fp, sc_ra; + + unsigned long sc_epc; + unsigned long sc_cause; + + unsigned long oldmask; +}; + +#endif + +#endif /* __ASM_MIPS_SIGNAL_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/slots.h linux/include/asm-mips/slots.h --- v1.1.81/linux/include/asm-mips/slots.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/slots.h Fri Jan 13 20:37:41 1995 @@ -0,0 +1,17 @@ +/* + * include/asm-mips/slots.h + * + * Copyright (C) 1994 by Waldorf Electronics + * Written by Ralf Baechle + */ +#ifndef __ASM_MIPS_SLOTS_H +#define __ASM_MIPS_SLOTS_H + +/* + * SLOTSPACE is the address to which the physical address 0 + * of the Slotspace is mapped by the chipset in the main CPU's + * address space. + */ +#define SLOTSPACE 0xe1000000 + +#endif /* __ASM_MIPS_SLOTS_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/stackframe.h linux/include/asm-mips/stackframe.h --- v1.1.81/linux/include/asm-mips/stackframe.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/stackframe.h Fri Jan 13 20:37:30 1995 @@ -0,0 +1,194 @@ +/* + * include/asm-mips/stackframe.h + * + * Copyright (C) 1994, 1995 Waldorf Electronics + * written by Ralf Baechle + */ + +#ifndef __ASM_MIPS_STACKFRAME_H +#define __ASM_MIPS_STACKFRAME_H + +/* + * Stack layout for all exceptions: + * + * ptrace needs to have all regs on the stack. + * if the order here is changed, it needs to be + * updated in asm/mips/fork.c:copy_process, asm/mips/signal.c:do_signal, + * asm-mips/ptrace.c, include/asm-mips/ptrace.h + * and asm-mips/ptrace + */ + +/* + * Offsets into the Interrupt stackframe. + * The first 20 bytes are reserved for the usual MIPS calling sequence + */ +#define FR_REG1 20 +#define FR_REG2 ((FR_REG1) + 4) +#define FR_REG3 ((FR_REG2) + 4) +#define FR_REG4 ((FR_REG3) + 4) +#define FR_REG5 ((FR_REG4) + 4) +#define FR_REG6 ((FR_REG5) + 4) +#define FR_REG7 ((FR_REG6) + 4) +#define FR_REG8 ((FR_REG7) + 4) +#define FR_REG9 ((FR_REG8) + 4) +#define FR_REG10 ((FR_REG9) + 4) +#define FR_REG11 ((FR_REG10) + 4) +#define FR_REG12 ((FR_REG11) + 4) +#define FR_REG13 ((FR_REG12) + 4) +#define FR_REG14 ((FR_REG13) + 4) +#define FR_REG15 ((FR_REG14) + 4) +#define FR_REG16 ((FR_REG15) + 4) +#define FR_REG17 ((FR_REG16) + 4) +#define FR_REG18 ((FR_REG17) + 4) +#define FR_REG19 ((FR_REG18) + 4) +#define FR_REG20 ((FR_REG19) + 4) +#define FR_REG21 ((FR_REG20) + 4) +#define FR_REG22 ((FR_REG21) + 4) +#define FR_REG23 ((FR_REG22) + 4) +#define FR_REG24 ((FR_REG23) + 4) +#define FR_REG25 ((FR_REG24) + 4) + +/* + * $26 (k0) and $27 (k1) not saved + */ +#define FR_REG28 ((FR_REG25) + 4) +#define FR_REG29 ((FR_REG28) + 4) +#define FR_REG30 ((FR_REG29) + 4) +#define FR_REG31 ((FR_REG30) + 4) + +/* + * Saved special registers + */ +#define FR_LO ((FR_REG31) + 4) +#define FR_HI ((FR_LO) + 4) + +/* + * Saved cp0 registers follow + */ +#define FR_STATUS ((FR_HI) + 4) +#define FR_EPC ((FR_STATUS) + 4) +#define FR_CAUSE ((FR_EPC) + 4) + +/* + * Some goodies... + */ +#define FR_INTERRUPT ((FR_CAUSE) + 4) +#define FR_ORIG_REG2 ((FR_INTERRUPT) + 4) + +/* + * Size of stack frame + */ +#define FR_SIZE ((FR_ORIG_REG2) + 4) + +#define SAVE_ALL \ + mfc0 k0,CP0_STATUS; \ + andi k0,0x18; /* extract KSU bits */ \ + beqz k0,1f; \ + move k1,sp; \ + /* \ + * Called from user mode, new stack \ + */ \ + lui k1,%hi(_kernelsp); \ + lw k1,%lo(_kernelsp)(k1); \ +1: move k0,sp; \ + subu sp,k1,FR_SIZE; \ + sw k0,FR_REG29(sp); \ + sw $2,FR_REG2(sp); \ + sw $2,FR_ORIG_REG2(sp); \ + mfc0 v0,CP0_STATUS; \ + sw v0,FR_STATUS(sp); \ + mfc0 v0,CP0_CAUSE; \ + sw v0,FR_CAUSE(sp); \ + mfc0 v0,CP0_EPC; \ + sw v0,FR_EPC(sp); \ + mfhi v0; \ + sw v0,FR_HI(sp); \ + mflo v0; \ + sw v0,FR_LO(sp); \ + sw $1,FR_REG1(sp); \ + sw $3,FR_REG3(sp); \ + sw $4,FR_REG4(sp); \ + sw $5,FR_REG5(sp); \ + sw $6,FR_REG6(sp); \ + sw $7,FR_REG7(sp); \ + sw $8,FR_REG8(sp); \ + sw $9,FR_REG9(sp); \ + sw $10,FR_REG10(sp); \ + sw $11,FR_REG11(sp); \ + sw $12,FR_REG12(sp); \ + sw $13,FR_REG13(sp); \ + sw $14,FR_REG14(sp); \ + sw $15,FR_REG15(sp); \ + sw $16,FR_REG16(sp); \ + sw $17,FR_REG17(sp); \ + sw $18,FR_REG18(sp); \ + sw $19,FR_REG19(sp); \ + sw $20,FR_REG20(sp); \ + sw $21,FR_REG21(sp); \ + sw $22,FR_REG22(sp); \ + sw $23,FR_REG23(sp); \ + sw $24,FR_REG24(sp); \ + sw $25,FR_REG25(sp); \ + sw $28,FR_REG28(sp); \ + sw $30,FR_REG30(sp); \ + sw $31,FR_REG31(sp) + +#define RESTORE_ALL \ + lw v1,FR_EPC(sp); \ + lw v0,FR_HI(sp); \ + mtc0 v1,CP0_EPC; \ + lw v1,FR_LO(sp); \ + mthi v0; \ + lw v0,FR_STATUS(sp); \ + mtlo v1; \ + mtc0 v0,CP0_STATUS; \ + lw $31,FR_REG31(sp); \ + lw $30,FR_REG30(sp); \ + lw $28,FR_REG28(sp); \ + lw $25,FR_REG25(sp); \ + lw $24,FR_REG24(sp); \ + lw $23,FR_REG23(sp); \ + lw $22,FR_REG22(sp); \ + lw $21,FR_REG21(sp); \ + lw $20,FR_REG20(sp); \ + lw $19,FR_REG19(sp); \ + lw $18,FR_REG18(sp); \ + lw $17,FR_REG17(sp); \ + lw $16,FR_REG16(sp); \ + lw $15,FR_REG15(sp); \ + lw $14,FR_REG14(sp); \ + lw $13,FR_REG13(sp); \ + lw $12,FR_REG12(sp); \ + lw $11,FR_REG11(sp); \ + lw $10,FR_REG10(sp); \ + lw $9,FR_REG9(sp); \ + lw $8,FR_REG8(sp); \ + lw $7,FR_REG7(sp); \ + lw $6,FR_REG6(sp); \ + lw $5,FR_REG5(sp); \ + lw $4,FR_REG4(sp); \ + lw $3,FR_REG3(sp); \ + lw $2,FR_REG2(sp); \ + lw $1,FR_REG1(sp); \ + lw sp,FR_REG29(sp); /* Deallocate stack */ \ + eret + +/* + * Move to kernel mode and disable interrupts + */ +#define CLI \ + mfc0 k0,CP0_STATUS; \ + ori k0,k0,0x1f; \ + xori k0,k0,0x1f; \ + mtc0 k0,CP0_STATUS + +/* + * Move to kernel mode and enable interrupts + */ +#define STI \ + mfc0 k0,CP0_STATUS; \ + ori k0,k0,0x1f; \ + xori k0,k0,0x1e; \ + mtc0 k0,CP0_STATUS + +#endif /* __ASM_MIPS_STACKFRAME_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/string.h linux/include/asm-mips/string.h --- v1.1.81/linux/include/asm-mips/string.h Mon Aug 15 10:54:23 1994 +++ linux/include/asm-mips/string.h Sat Jan 14 01:15:15 1995 @@ -5,15 +5,16 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1994 by Ralf Baechle + * Copyright (c) 1994, 1995 Waldorf Electronics + * written by Ralf Baechle */ -#ifndef _ASM_MIPS_STRING_H_ -#define _ASM_MIPS_STRING_H_ +#ifndef __ASM_MIPS_STRING_H +#define __ASM_MIPS_STRING_H -#define __USE_PORTABLE_STRINGS_H_ +#include -extern inline char * strcpy(char * dest,const char *src) +extern __inline__ char * strcpy(char * dest, const char *src) { char *xdest = dest; @@ -23,18 +24,18 @@ "1:\tlbu\t$1,(%1)\n\t" "addiu\t%1,%1,1\n\t" "sb\t$1,(%0)\n\t" - "bne\t$0,$1,1b\n\t" + "bnez\t$1,1b\n\t" "addiu\t%0,%0,1\n\t" ".set\tat\n\t" ".set\treorder" - : "=d" (dest), "=d" (src) + : "=r" (dest), "=r" (src) : "0" (dest), "1" (src) : "$1","memory"); return xdest; } -extern inline char * strncpy(char *dest, const char *src, size_t n) +extern __inline__ char * strncpy(char *dest, const char *src, size_t n) { char *xdest = dest; @@ -45,26 +46,23 @@ ".set\tnoreorder\n\t" ".set\tnoat\n" "1:\tlbu\t$1,(%1)\n\t" - "addiu\t%2,%2,-1\n\t" + "subu\t%2,%2,1\n\t" "sb\t$1,(%0)\n\t" - "beq\t$0,$1,2f\n\t" + "beqz\t$1,2f\n\t" "addiu\t%0,%0,1\n\t" - "bne\t$0,%2,1b\n\t" + "bnez\t%2,1b\n\t" "addiu\t%1,%1,1\n" "2:\n\t" ".set\tat\n\t" ".set\treorder\n\t" - : "=d" (dest), "=d" (src), "=d" (n) + : "=r" (dest), "=r" (src), "=r" (n) : "0" (dest), "1" (src), "2" (n) : "$1","memory"); return dest; } -#define __USE_PORTABLE_strcat -#define __USE_PORTABLE_strncat - -extern inline int strcmp(const char * cs,const char * ct) +extern __inline__ int strcmp(const char * cs, const char * ct) { int __res; @@ -76,8 +74,9 @@ "addiu\t%0,%0,1\n\t" "bne\t$1,%2,2f\n\t" "addiu\t%1,%1,1\n\t" - "bne\t$0,%2,1b\n\t" - "lbu\t%2,(%0)\n" + "bnez\t%2,1b\n\t" + "lbu\t%2,(%0)\n\t" + STR(FILL_LDS) "\n\t" "move\t%2,$1\n" "2:\tsub\t%2,%2,$1\n" "3:\t.set\tat\n\t" @@ -89,7 +88,7 @@ return __res; } -extern inline int strncmp(const char * cs,const char * ct,size_t count) +extern __inline__ int strncmp(const char * cs, const char * ct, size_t count) { char __res; @@ -97,12 +96,12 @@ ".set\tnoreorder\n\t" ".set\tnoat\n" "1:\tlbu\t%3,(%0)\n\t" - "beq\t$0,%2,2f\n\t" + "beqz\t%2,2f\n\t" "lbu\t$1,(%1)\n\t" "addiu\t%2,%2,-1\n\t" "bne\t$1,%3,3f\n\t" "addiu\t%0,%0,1\n\t" - "bne\t$0,%3,1b\n\t" + "bnez\t%3,1b\n\t" "addiu\t%1,%1,1\n" "2:\tmove\t%3,$1\n" "3:\tsub\t%3,%3,$1\n\t" @@ -115,13 +114,7 @@ return __res; } -#define __USE_PORTABLE_strchr -#define __USE_PORTABLE_strlen -#define __USE_PORTABLE_strspn -#define __USE_PORTABLE_strpbrk -#define __USE_PORTABLE_strtok - -extern inline void * memset(void * s,char c,size_t count) +extern __inline__ void * memset(void * s, int c, size_t count) { void *xs = s; @@ -130,18 +123,17 @@ __asm__ __volatile__( ".set\tnoreorder\n" "1:\tsb\t%3,(%0)\n\t" - "addiu\t%1,%1,-1\n\t" - "bne\t$0,%1,1b\n\t" - "addiu\t%3,%3,1\n\t" + "bne\t%0,%1,1b\n\t" + "addiu\t%0,%0,1\n\t" ".set\treorder" - : "=d" (s), "=d" (count) - : "0" (s), "d" (c), "1" (count) + : "=r" (s), "=r" (count) + : "0" (s), "r" (c), "1" (s + count - 1) : "memory"); return xs; } -extern inline void * memcpy(void * to, const void * from, size_t n) +extern __inline__ void * memcpy(void * to, const void * from, size_t n) { void *xto = to; @@ -153,18 +145,18 @@ "1:\tlbu\t$1,(%1)\n\t" "addiu\t%1,%1,1\n\t" "sb\t$1,(%0)\n\t" - "addiu\t%2,%2,-1\n\t" - "bne\t$0,%2,1b\n\t" + "subu\t%2,%2,1\n\t" + "bnez\t%2,1b\n\t" "addiu\t%0,%0,1\n\t" ".set\tat\n\t" ".set\treorder" - : "=d" (to), "=d" (from), "=d" (n) + : "=r" (to), "=r" (from), "=r" (n) : "0" (to), "1" (from), "2" (n) : "$1","memory" ); return xto; } -extern inline void * memmove(void * dest,const void * src, size_t n) +extern __inline__ void * memmove(void * dest,const void * src, size_t n) { void *xdest = dest; @@ -178,12 +170,12 @@ "1:\tlbu\t$1,(%1)\n\t" "addiu\t%1,%1,1\n\t" "sb\t$1,(%0)\n\t" - "addiu\t%2,%2,-1\n\t" - "bne\t$0,%2,1b\n\t" + "subu\t%2,%2,1\n\t" + "bnez\t%2,1b\n\t" "addiu\t%0,%0,1\n\t" ".set\tat\n\t" ".set\treorder" - : "=d" (dest), "=d" (src), "=d" (n) + : "=r" (dest), "=r" (src), "=r" (n) : "0" (dest), "1" (src), "2" (n) : "$1","memory" ); else @@ -191,19 +183,38 @@ ".set\tnoreorder\n\t" ".set\tnoat\n" "1:\tlbu\t$1,-1(%1)\n\t" - "addiu\t%1,%1,-1\n\t" + "subu\t%1,%1,1\n\t" "sb\t$1,-1(%0)\n\t" - "addiu\t%2,%2,-1\n\t" - "bne\t$0,%2,1b\n\t" - "addiu\t%0,%0,-1\n\t" + "subu\t%2,%2,1\n\t" + "bnez\t%2,1b\n\t" + "subu\t%0,%0,1\n\t" ".set\tat\n\t" ".set\treorder" - : "=d" (dest), "=d" (src), "=d" (n) + : "=r" (dest), "=r" (src), "=r" (n) : "0" (dest+n), "1" (src+n), "2" (n) : "$1","memory" ); return xdest; } -#define __USE_PORTABLE_memcmp +extern __inline__ void * memscan(void * addr, int c, size_t size) +{ + if (!size) + return addr; + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n" + "1:\tbeq\t$0,%1,2f\n\t" + "lbu\t$1,(%0)\n\t" + "subu\t%1,%1,1\n\t" + "bnez\t%1,1b\n\t" + "addiu\t%0,%0,1\n\t" + ".set\tat\n\t" + ".set\treorder\n" + "2:" + : "=r" (addr), "=r" (size) + : "0" (addr), "1" (size), "r" (c) + : "$1"); + + return addr; +} -#endif /* _ASM_MIPS_STRING_H_ */ +#endif /* __ASM_MIPS_STRING_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/system.h linux/include/asm-mips/system.h --- v1.1.81/linux/include/asm-mips/system.h Sun Nov 27 20:19:54 1994 +++ linux/include/asm-mips/system.h Fri Jan 13 20:37:06 1995 @@ -8,63 +8,196 @@ * Copyright (C) 1994 by Ralf Baechle */ -#ifndef _ASM_MIPS_SYSTEM_H_ -#define _ASM_MIPS_SYSTEM_H_ +#ifndef __ASM_MIPS_SYSTEM_H +#define __ASM_MIPS_SYSTEM_H +#include #include -#include +#include +#include /* - * move_to_user_mode() doesn't switch to user mode on the mips, since - * that would run us into problems: The kernel is located at virtual - * address 0x80000000. If we now would switch over to user mode, we - * we would immediately get an address error exception. - * Anyway - we don't have problems with a task running in kernel mode, - * as long it's code is foolproof. + * (Currently empty to support debugging) */ -#define move_to_user_mode() +#define move_to_user_mode() \ +__asm__ __volatile__ ( \ + ".set\tnoreorder\n\t" \ + ".set\tnoat\n\t" \ + "la\t$1,1f\n\t" \ + "subu\t$1,$1,%0\n\t" \ + "jr\t$1\n\t" \ + "mfc0\t$1,$12\n\t" \ + "1:ori\t$1,0x00\n\t" \ + "mtc0\t$1,$12\n\t" \ + "subu\t$29,%0\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" \ + : /* no outputs */ \ + : "r" (KERNELBASE)); +#if defined (__R4000__) #define sti() \ -__asm__ __volatile__( \ +__asm__ __volatile__( \ + ".set\tnoat\n\t" \ "mfc0\t$1,"STR(CP0_STATUS)"\n\t" \ - "ori\t$1,$1,1\n\t" \ + "ori\t$1,$1,0x1f\n\t" \ + "xori\t$1,$1,0x1e\n\t" \ "mtc0\t$1,"STR(CP0_STATUS)"\n\t" \ - : /* no outputs */ \ - : /* no inputs */ \ - : "$1","memory") + ".set\tat" \ + : /* no outputs */ \ + : /* no inputs */ \ + : "$1") #define cli() \ -__asm__ __volatile__( \ +__asm__ __volatile__( \ + ".set\tnoat\n\t" \ "mfc0\t$1,"STR(CP0_STATUS)"\n\t" \ - "srl\t$1,$1,1\n\t" \ - "sll\t$1,$1,1\n\t" \ + "ori\t$1,$1,1\n\t" \ + "xori\t$1,$1,1\n\t" \ "mtc0\t$1,"STR(CP0_STATUS)"\n\t" \ - : /* no outputs */ \ - : /* no inputs */ \ - : "$1","memory") + ".set\tat" \ + : /* no outputs */ \ + : /* no inputs */ \ + : "$1") +#else /* !defined (__R4000__) */ +/* + * Cheese - I don't have a R3000 manual + */ +#error "Yikes - write cli()/sti() macros for R3000!" +#endif /* !defined (__R4000__) */ #define nop() __asm__ __volatile__ ("nop") -#define save_flags(x) \ -__asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t%0,$12\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - : "=r" (x) \ - : /* no inputs */ \ - : "memory") - -#define restore_flags(x) \ -__asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - "mtc0\t%0,$12\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - : /* no output */ \ - : "r" (x) \ - : "memory") +#define save_flags(x) \ +__asm__ __volatile__( \ + "mfc0\t%0,$12" \ + : "=r" (x)) \ + +#define restore_flags(x) \ +__asm__ __volatile__( \ + "mtc0\t%0,$12" \ + : /* no output */ \ + : "r" (x)) \ + +extern inline unsigned long xchg_u8(char * m, unsigned long val) +{ + unsigned long flags, retval; + + save_flags(flags); + sti(); + retval = *m; + *m = val; + restore_flags(flags); + + return retval; +} + +extern inline unsigned long xchg_u16(short * m, unsigned long val) +{ + unsigned long flags, retval; + + save_flags(flags); + sti(); + retval = *m; + *m = val; + restore_flags(flags); + + return retval; +} + +/* + * For 32 and 64 bit operands we can take advantage of ll and sc. + * The later isn't currently being used. + */ +extern inline unsigned long xchg_u32(int * m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "ll\t%0,(%1)\n" + "1:\tmove\t$1,%2\n\t" + "sc\t$1,(%1)\n\t" + "beqzl\t%3,1b\n\t" + "ll\t%0,(%1)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (val), "=r" (m), "=r" (dummy) + : "1" (*m), "2" (val)); + + return val; +} + +extern inline unsigned long xchg_u64(long * m, unsigned long val) +{ + unsigned long dummy; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "lld\t%0,(%1)\n" + "1:\tmove\t$1,%2\n\t" + "scd\t$1,(%1)\n\t" + "beqzl\t%3,1b\n\t" + "ll\t%0,(%1)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (val), "=r" (m), "=r" (dummy) + : "1" (*m), "2" (val)); + + return val; +} + +#if 0 +extern inline int tas(char * m) +{ + return xchg_u8(m,1); +} +#endif + +extern inline void * xchg_ptr(void * m, void * val) +{ + return (void *) xchg_u32(m, (unsigned long) val); +} + +extern ulong IRQ_vectors[256]; +extern ulong exception_handlers[256]; + +#define set_intr_gate(n,addr) \ + IRQ_vectors[n] = (ulong) (addr) + +#define set_except_vector(n,addr) \ + exception_handlers[n] = (ulong) (addr) + +/* + * atomic exchange of one word + */ +#if defined (__R4000__) +#define atomic_exchange(m,r) \ + __asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + "ll\t%0,(%2)\n" \ + "1:\tmove\t$8,%1\n\t" \ + "sc\t$8,(%2)\n\t" \ + "beql\t$0,$8,1b\n\t" \ + "ll\t%0,(%2)\n\t" \ + ".set\treorder" \ + : "=r" (r) \ + : "r" (r), "r" (&(m)) \ + : "$8","memory") +#else +#define atomic_exchange(m,r) \ + { \ + unsigned long flags; \ + unsigned long tmp; \ + save_flags(flags); \ + cli(); \ + tmp = (m); \ + (m) = (r); \ + (r) = tmp; \ + restore_flags(flags); \ + } +#endif -#endif /* _ASM_MIPS_SYSTEM_H_ */ +#endif /* __ASM_MIPS_SYSTEM_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/types.h linux/include/asm-mips/types.h --- v1.1.81/linux/include/asm-mips/types.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-mips/types.h Tue Jan 10 03:34:06 1995 @@ -0,0 +1,93 @@ +#ifndef __ASM_MIPS_TYPES_H +#define __ASM_MIPS_TYPES_H + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned long size_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef long ssize_t; +#endif + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef long ptrdiff_t; +#endif + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if ((~0UL) == 0xffffffff) + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +#else + +typedef __signed__ long __s64; +typedef unsigned long __u64; + +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef __signed char s8; +typedef unsigned char u8; + +typedef __signed short s16; +typedef unsigned short u16; + +typedef __signed long s32; +typedef unsigned long u32; + +#if ((~0UL) == 0xffffffff) + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long s64; +typedef unsigned long long u64; +#endif + +#else + +typedef __signed__ long s64; +typedef unsigned long u64; + +#endif + +#endif /* __KERNEL__ */ + +/* + * These definitions double the definitions from . + */ +#undef __FDELT +#define __FDELT(d) ((d) / __NFDBITS) +#undef __FDMASK +#define __FDMASK(d) (1 << ((d) % __NFDBITS)) +#undef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#undef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#undef __FD_ISSET +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) + +#endif /* __ASM_MIPS_TYPES_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-mips/unistd.h linux/include/asm-mips/unistd.h --- v1.1.81/linux/include/asm-mips/unistd.h Mon Aug 15 10:54:24 1994 +++ linux/include/asm-mips/unistd.h Thu Jan 12 00:54:19 1995 @@ -1,18 +1,25 @@ -#ifndef _ASM_MIPS_UNISTD_H_ -#define _ASM_MIPS_UNISTD_H_ +#ifndef __ASM_MIPS_UNISTD_H +#define __ASM_MIPS_UNISTD_H + +#ifdef __KERNEL__ + +#include +/* + * Ugly kludge to enforce 32bit mode proof code. + * Access errno via USEG, not KSEGx for internal kernel syscalls + */ +#define errno (*(int *)((unsigned long)&errno - KERNELBASE)) + +#endif /* __KERNEL__ */ /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ type name(void) \ { \ -register long __res; \ -__asm__ volatile (".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ - "syscall\n\t" \ - : "=d" (__res) \ - : "i" (__NR_##name) \ - : "$1"); \ +register long __res __asm__ ("$2"); \ +__asm__ volatile ("syscall" \ + : "=r" (__res) \ + : "0" (__NR_##name)); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -22,15 +29,12 @@ #define _syscall1(type,name,atype,a) \ type name(atype a) \ { \ -register long __res; \ -__asm__ volatile ("move\t$2,%2\n\t" \ - ".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ +register long __res __asm__ ("$2"); \ +__asm__ volatile ("move\t$4,%2\n\t" \ "syscall" \ - : "=d" (__res) \ - : "i" (__NR_##name),"d" ((long)(a)) \ - : "$1","$2"); \ + : "=r" (__res) \ + : "0" (__NR_##name),"r" ((long)(a)) \ + : "$4"); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -40,17 +44,14 @@ #define _syscall2(type,name,atype,a,btype,b) \ type name(atype a,btype b) \ { \ -register long __res; \ -__asm__ volatile ("move\t$2,%2\n\t" \ - "move\t$3,%3\n\t" \ - ".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ +register long __res __asm__ ("$2"); \ +__asm__ volatile ("move\t$4,%2\n\t" \ + "move\t$5,%3\n\t" \ "syscall" \ - : "=d" (__res) \ - : "i" (__NR_##name),"d" ((long)(a)), \ - "d" ((long)(b))); \ - : "$1","$2","$3"); \ + : "=r" (__res) \ + : "0" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b))); \ + : "$4","$5"); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ @@ -60,19 +61,16 @@ #define _syscall3(type,name,atype,a,btype,b,ctype,c) \ type name (atype a, btype b, ctype c) \ { \ -register long __res; \ -__asm__ volatile ("move\t$2,%2\n\t" \ - "move\t$3,%3\n\t" \ - "move\t$4,%4\n\t" \ - ".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ +register long __res __asm__ ("$2"); \ +__asm__ volatile ("move\t$4,%2\n\t" \ + "move\t$5,%3\n\t" \ + "move\t$6,%4\n\t" \ "syscall" \ - : "=d" (__res) \ - : "i" (__NR_##name),"d" ((long)(a)), \ - "d" ((long)(b)), \ - "d" ((long)(c)) \ - : "$1","$2","$3","$4"); \ + : "=r" (__res) \ + : "0" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b)), \ + "r" ((long)(c)) \ + : "$4","$5","$6"); \ if (__res>=0) \ return (type) __res; \ errno=-__res; \ @@ -82,22 +80,19 @@ #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ type name (atype a, btype b, ctype c, dtype d) \ { \ -register long __res; \ +register long __res __asm__ ("$2"); \ __asm__ volatile (".set\tnoat\n\t" \ - "move\t$2,%2\n\t" \ - "move\t$3,%3\n\t" \ - "move\t$4,%4\n\t" \ - "move\t$5,%5\n\t" \ - ".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ + "move\t$4,%2\n\t" \ + "move\t$5,%3\n\t" \ + "move\t$6,%4\n\t" \ + "move\t$7,%5\n\t" \ "syscall" \ - : "=d" (__res) \ - : "i" (__NR_##name),"d" ((long)(a)), \ - "d" ((long)(b)), \ - "d" ((long)(c)), \ - "d" ((long)(d)) \ - : "$1","$2","$3","$4","$5"); \ + : "=r" (__res) \ + : "0" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b)), \ + "r" ((long)(c)), \ + "r" ((long)(d)) \ + : "$4","$5","$6","$7"); \ if (__res>=0) \ return (type) __res; \ errno=-__res; \ @@ -107,28 +102,25 @@ #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ type name (atype a,btype b,ctype c,dtype d,etype e) \ { \ -register long __res; \ +register long __res __asm__ ("$2"); \ __asm__ volatile (".set\tnoat\n\t" \ - "move\t$2,%2\n\t" \ - "move\t$3,%3\n\t" \ - "move\t$4,%4\n\t" \ - "move\t$5,%5\n\t" \ - "move\t$6,%6\n\t" \ - ".set\tnoat\n\t" \ - "li\t$1,%1\n\t" \ - ".set\tat\n\t" \ + "move\t$4,%2\n\t" \ + "move\t$5,%3\n\t" \ + "move\t$6,%4\n\t" \ + "move\t$7,%5\n\t" \ + "move\t$3,%6\n\t" \ "syscall" \ - : "=d" (__res) \ - : "i" (__NR_##name),"d" ((long)(a)), \ - "d" ((long)(b)), \ - "d" ((long)(c)), \ - "d" ((long)(d)), \ - "d" ((long)(e)) \ - : "$1","$2","$3","$4","$5","$6"); \ + : "=r" (__res) \ + : "0" (__NR_##name),"r" ((long)(a)), \ + "r" ((long)(b)), \ + "r" ((long)(c)), \ + "r" ((long)(d)), \ + "r" ((long)(e)) \ + : "$3","$4","$5","$6","$7"); \ if (__res>=0) \ return (type) __res; \ errno=-__res; \ return -1; \ } -#endif /* _ASM_MIPS_UNISTD_H_ */ +#endif /* __ASM_MIPS_UNISTD_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-sparc/dma.h linux/include/asm-sparc/dma.h --- v1.1.81/linux/include/asm-sparc/dma.h Mon Jan 9 07:22:10 1995 +++ linux/include/asm-sparc/dma.h Mon Jan 16 07:27:37 1995 @@ -8,7 +8,10 @@ * Copyright (C) David S. Miller (davem@caip.rutgers.edu) */ +#include /* for invalidate's, etc. */ + #define MAX_DMA_CHANNELS 8 +#define MAX_DMA_ADDRESS 0x0 #ifndef _ASM_SPARC_DMA_H #define _ASM_SPARC_DMA_H diff -u --recursive --new-file v1.1.81/linux/include/asm-sparc/page.h linux/include/asm-sparc/page.h --- v1.1.81/linux/include/asm-sparc/page.h Wed Jan 11 21:14:29 1995 +++ linux/include/asm-sparc/page.h Mon Jan 16 07:27:37 1995 @@ -40,8 +40,8 @@ * Much thought must go into this code. (davem@caip.rutgers.edu) */ -#define PAGE_DIR_OFFSET(base, address) ((void *) 0) -#define PAGE_PTR(address) ((void *) 0) +#define PAGE_DIR_OFFSET(base, address) ((unsigned long *) 0) +#define PAGE_PTR(address) ((unsigned long) 0) #define PTRS_PER_PAGE (64) /* 64 pte's per phys_seg */ /* Bitfields within a Sparc sun4c PTE (page table entry). */ @@ -123,6 +123,15 @@ return ctx; } + +/* to set the page-dir + * + * On the Sparc this is a nop for now. It will set the proper segmap + * in the real implementation. + */ + +#define SET_PAGE_DIR(tsk,pgdir) + #endif /* !(__ASSEMBLY__) */ diff -u --recursive --new-file v1.1.81/linux/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h --- v1.1.81/linux/include/asm-sparc/processor.h Wed Jan 11 21:14:29 1995 +++ linux/include/asm-sparc/processor.h Mon Jan 16 07:27:37 1995 @@ -9,10 +9,16 @@ /* * Bus types */ -extern int EISA_bus; +#define EISA_bus 1 #define MCA_bus 0 /* + * Write Protection works right in supervisor mode on the Sparc + */ + +#define wp_works_ok 1 + +/* * User space process size: 3GB. This is hardcoded into a few places, * so don't change it unless you know what you are doing. * @@ -135,7 +141,7 @@ "ld %1,%0\n\t" "sub %0,1,%0\n\t" "st %0,%1\n\t" - "wr %2, 0x0, %2\n\t" + "wr %2, 0x0, %%psr\n\t" : "=r" (dummy), "=m" (intr_count) : "0" (0), "r" (psr=0)); } diff -u --recursive --new-file v1.1.81/linux/include/asm-sparc/unistd.h linux/include/asm-sparc/unistd.h --- v1.1.81/linux/include/asm-sparc/unistd.h Mon Jan 2 15:26:45 1995 +++ linux/include/asm-sparc/unistd.h Mon Jan 16 07:27:37 1995 @@ -4,7 +4,9 @@ /* * System calls under the Sparc. * - * This is work in progress. + * Don't be scared by the ugly clobbers, it is the only way I can + * think of right now to force the arguments into fixed registers + * before the trap into the system call with gcc 'asm' statements. * * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) */ @@ -13,32 +15,113 @@ #define _syscall0(type,name) \ type name(void) \ { \ +long __res; \ +__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ + "t 0xa\n\t" \ + : "=r" (__res) \ + : "0" (__NR_##name) \ + : "o0"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ } #define _syscall1(type,name,type1,arg1) \ type name(type1 arg1) \ { \ +long __res; \ +__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ + "or %%g0, %1, %%o1\n\t" \ + "t 0xa\n\t" \ + : "=r" (__res), "=r" ((long)(arg1)) \ + : "0" (__NR_##name),"1" ((long)(arg1)) \ + : "o0", "o1"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ } #define _syscall2(type,name,type1,arg1,type2,arg2) \ type name(type1 arg1,type2 arg2) \ { \ +long __res; \ +__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ + "or %%g0, %1, %%o1\n\t" \ + "or %%g0, %2, %%o2\n\t" \ + "t 0xa\n\t" \ + : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(args)) \ + : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)) \ + : "o0", "o1", "o2"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ } #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ type name(type1 arg1,type2 arg2,type3 arg3) \ { \ +long __res; \ +__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ + "or %%g0, %1, %%o1\n\t" \ + "or %%g0, %2, %%o2\n\t" \ + "or %%g0, %3, %%o3\n\t" \ + "t 0xa\n\t" \ + : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \ + "=r" ((long)(arg3)) \ + : "0" (__NR_##name), "1" ((long)(arg1)), "2" ((long)(arg2)), \ + "3" ((long)(arg3)) \ + : "o0", "o1", "o2", "o3"); \ +if (__res>=0) \ + return (type) __res; \ +errno=-__res; \ +return -1; \ } #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ { \ +long __res; \ +__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ + "or %%g0, %1, %%o1\n\t" \ + "or %%g0, %2, %%o2\n\t" \ + "or %%g0, %3, %%o3\n\t" \ + "or %%g0, %4, %%o4\n\t" \ + "t 0xa\n\t" \ + : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \ + "=r" ((long)(arg3)), "=r" ((long)(arg4)) \ + : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \ + "3" ((long)(arg3)),"4" ((long)(arg4)) \ + : "o0", "o1", "o2", "o3", "o4"); \ +if (__res>=0) \ + return (type) __res; \ +errno=-__res; \ +return -1; \ } #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ type5,arg5) \ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ { \ +long __res; \ +__asm__ volatile ("or %%g0, %0, %%o0\n\t" \ + "or %%g0, %1, %%o1\n\t" \ + "or %%g0, %2, %%o2\n\t" \ + "or %%g0, %3, %%o3\n\t" \ + "or %%g0, %4, %%o4\n\t" \ + "or %%g0, %5, %%o5\n\t" \ + "t 0xa\n\t" \ + : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \ + "=r" ((long)(arg3)), "=r" ((long)(arg4)), "=r" ((long)(arg5)) \ + : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \ + "3" ((long)(arg3)),"4" ((long)(arg4)),"5" ((long)(arg5)) \ + : "o0", "o1", "o2", "o3", "o4", "o5"); \ +if (__res>=0) \ + return (type) __res; \ +errno=-__res; \ +return -1; \ } -#endif /* _ALPHA_UNISTD_H */ +#endif /* _SPARC_UNISTD_H */ diff -u --recursive --new-file v1.1.81/linux/include/asm-sparc/vac-ops.h linux/include/asm-sparc/vac-ops.h --- v1.1.81/linux/include/asm-sparc/vac-ops.h Fri Jan 13 10:12:23 1995 +++ linux/include/asm-sparc/vac-ops.h Mon Jan 16 07:27:37 1995 @@ -1,9 +1,16 @@ +#ifndef _SPARC_VAC_OPS_H +#define _SPARC_VAC_OPS_H + /* vac-ops.h: Inline assembly routines to do operations on the Sparc VAC (virtual address cache). Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu) */ +extern void flush_vac_context(void); +extern void flush_vac_segment(unsigned int foo_segment); +extern void flush_vac_page(unsigned int foo_addr); + /* enable_vac() enables the virtual address cache. It returns 0 on success, 1 on failure. */ @@ -72,3 +79,4 @@ __asm__ __volatile__("sta %%g0, [%0] 0xd" : : "r" (addr)); } +#endif /* !(_SPARC_VAC_OPS_H) */ diff -u --recursive --new-file v1.1.81/linux/include/linux/lp.h linux/include/linux/lp.h --- v1.1.81/linux/include/linux/lp.h Wed Jan 11 21:14:29 1995 +++ linux/include/linux/lp.h Sun Jan 15 00:55:50 1995 @@ -99,16 +99,24 @@ char *lp_buffer; }; +/* + * The following constants describe the various signals of the printer port + * hardware. Note that the hardware inverts some signals and that some + * signals are active low. An example is LP_STROBE, which must be programmed + * with 1 for being active and 0 for being inactive, because the strobe signal + * gets inverted, but it is also active low. + */ + /* * bit defines for 8255 status port * base + 1 * accessed with LP_S(minor), which gets the byte... */ -#define LP_PBUSY 0x80 /* active low */ -#define LP_PACK 0x40 /* active low */ -#define LP_POUTPA 0x20 -#define LP_PSELECD 0x10 -#define LP_PERRORP 0x08 /* active low*/ +#define LP_PBUSY 0x80 /* inverted input, active high */ +#define LP_PACK 0x40 /* unchanged input, active low */ +#define LP_POUTPA 0x20 /* unchanged input, active high */ +#define LP_PSELECD 0x10 /* unchanged input, active high */ +#define LP_PERRORP 0x08 /* unchanged input, active low */ /* * defines for 8255 control port @@ -116,10 +124,10 @@ * accessed with LP_C(minor) */ #define LP_PINTEN 0x10 -#define LP_PSELECP 0x08 -#define LP_PINITP 0x04 /* active low */ -#define LP_PAUTOLF 0x02 -#define LP_PSTROBE 0x01 +#define LP_PSELECP 0x08 /* inverted output, active low */ +#define LP_PINITP 0x04 /* unchanged output, active low */ +#define LP_PAUTOLF 0x02 /* inverted output, active low */ +#define LP_PSTROBE 0x01 /* inverted output, active low */ /* * the value written to ports to test existence. PC-style ports will diff -u --recursive --new-file v1.1.81/linux/include/linux/mm.h linux/include/linux/mm.h --- v1.1.81/linux/include/linux/mm.h Fri Jan 13 10:12:23 1995 +++ linux/include/linux/mm.h Mon Jan 16 07:17:38 1995 @@ -83,20 +83,14 @@ void (*sync)(struct vm_area_struct *area, unsigned long, size_t, unsigned int flags); void (*advise)(struct vm_area_struct *area, unsigned long, size_t, unsigned int advise); unsigned long (*nopage)(struct vm_area_struct * area, unsigned long address, - unsigned long page, int error_code); + unsigned long page, int write_access); unsigned long (*wppage)(struct vm_area_struct * area, unsigned long address, unsigned long page); void (*swapout)(struct vm_area_struct *, unsigned long, unsigned long *); unsigned long (*swapin)(struct vm_area_struct *, unsigned long, unsigned long); }; -extern unsigned long __bad_page(void); -extern unsigned long __bad_pagetable(void); -extern unsigned long __zero_page(void); - -#define BAD_PAGETABLE __bad_pagetable() -#define BAD_PAGE __bad_page() -#define ZERO_PAGE __zero_page() +extern mem_map_t * mem_map; /* planning stage.. */ #define P_DIRTY 0x0001 @@ -172,14 +166,11 @@ extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, int mask); extern int zeromap_page_range(unsigned long from, unsigned long size, int mask); -extern void do_wp_page(struct vm_area_struct * vma, unsigned long address, - unsigned long error_code); -extern void do_no_page(struct vm_area_struct * vma, unsigned long address, - unsigned long error_code); +extern void do_wp_page(struct vm_area_struct * vma, unsigned long address, int write_access); +extern void do_no_page(struct vm_area_struct * vma, unsigned long address, int write_access); extern unsigned long paging_init(unsigned long start_mem, unsigned long end_mem); -extern void mem_init(unsigned long low_start_mem, - unsigned long start_mem, unsigned long end_mem); +extern void mem_init(unsigned long start_mem, unsigned long end_mem); extern void show_mem(void); extern void oom(struct task_struct * task); extern void si_meminfo(struct sysinfo * val); @@ -214,26 +205,6 @@ extern unsigned long high_memory; -#define MAP_NR(addr) ((addr) >> PAGE_SHIFT) -#define MAP_PAGE_RESERVED (1<<15) - -extern unsigned short * mem_map; - -#define PAGE_PRESENT 0x001 -#define PAGE_RW 0x002 -#define PAGE_USER 0x004 -#define PAGE_PWT 0x008 /* 486 only - not used currently */ -#define PAGE_PCD 0x010 /* 486 only - not used currently */ -#define PAGE_ACCESSED 0x020 -#define PAGE_DIRTY 0x040 -#define PAGE_COW 0x200 /* implemented in software (one of the AVL bits) */ - -#define PAGE_PRIVATE (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED | PAGE_COW) -#define PAGE_SHARED (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED) -#define PAGE_COPY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED | PAGE_COW) -#define PAGE_READONLY (PAGE_PRESENT | PAGE_USER | PAGE_ACCESSED) -#define PAGE_TABLE (PAGE_PRESENT | PAGE_RW | PAGE_USER | PAGE_ACCESSED) - #define GFP_BUFFER 0x00 #define GFP_ATOMIC 0x01 #define GFP_USER 0x02 @@ -272,7 +243,7 @@ extern inline unsigned long in_swap_cache(unsigned long addr) { - return swap_cache[addr >> PAGE_SHIFT]; + return swap_cache[MAP_NR(addr)]; } extern inline long find_in_swap_cache (unsigned long addr) @@ -282,7 +253,7 @@ #ifdef SWAP_CACHE_INFO swap_cache_find_total++; #endif - entry = (unsigned long) xchg_ptr(swap_cache + (addr >> PAGE_SHIFT), NULL); + entry = (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), NULL); #ifdef SWAP_CACHE_INFO if (entry) swap_cache_find_success++; @@ -297,7 +268,7 @@ #ifdef SWAP_CACHE_INFO swap_cache_del_total++; #endif - entry = (unsigned long) xchg_ptr(swap_cache + (addr >> PAGE_SHIFT), NULL); + entry = (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), NULL); if (entry) { #ifdef SWAP_CACHE_INFO swap_cache_del_success++; diff -u --recursive --new-file v1.1.81/linux/include/linux/param.h linux/include/linux/param.h --- v1.1.81/linux/include/linux/param.h Wed Dec 1 14:44:15 1993 +++ linux/include/linux/param.h Mon Jan 16 07:17:38 1995 @@ -1,20 +1,6 @@ #ifndef _LINUX_PARAM_H #define _LINUX_PARAM_H -#ifndef HZ -#define HZ 100 -#endif - -#define EXEC_PAGESIZE 4096 - -#ifndef NGROUPS -#define NGROUPS 32 -#endif - -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ +#include #endif diff -u --recursive --new-file v1.1.81/linux/include/linux/pci.h linux/include/linux/pci.h --- v1.1.81/linux/include/linux/pci.h Fri Jan 13 16:57:06 1995 +++ linux/include/linux/pci.h Sun Jan 15 21:55:47 1995 @@ -160,7 +160,7 @@ char *class_name; }; -#define PCI_CLASS_NUM 27 +#define PCI_CLASS_NUM 28 #define PCI_CLASS_TYPE { \ {PCI_CLASS_NOT_DEFINED, "Old unidentified device"}, \ {PCI_CLASS_NOT_DEFINED_VGA, "Old VGA controller"}, \ @@ -217,6 +217,7 @@ #define PCI_VENDOR_ID_UMC 0x1060 #define PCI_DEVICE_ID_UMC_UM8881F 0x8881 +#define PCI_DEVICE_ID_UMC_UM8891A 0x0891 #define PCI_DEVICE_ID_UMC_UM8886F 0x8886 #define PCI_DEVICE_ID_UMC_UM8673F 0x0101 @@ -232,6 +233,7 @@ #define PCI_DEVICE_ID_INTEL_82424 0x0483 #define PCI_DEVICE_ID_INTEL_82375 0x0482 #define PCI_DEVICE_ID_INTEL_82434 0x04a3 +#define PCI_DEVICE_ID_INTEL_82430 0x0486 #define PCI_VENDOR_ID_SMC 0x1042 #define PCI_DEVICE_ID_SMC_37C665 0x1000 @@ -245,7 +247,9 @@ #define PCI_DEVICE_ID_WEITEK_P9100 0x9100 #define PCI_VENDOR_ID_CIRRUS 0x1013 -#define PCI_DEVICE_ID_CIRRUS_5434 0x00A4 +#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00A4 +#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00A8 +#define PCI_DEVICE_ID_CIRRUS_6729 0x1100 #define PCI_VENDOR_ID_BUSLOGIC 0x104B #define PCI_DEVICE_ID_BUSLOGIC_946C 0x0140 @@ -257,22 +261,41 @@ #define PCI_DEVICE_ID_ALI_M1435 0x1435 #define PCI_VENDOR_ID_TSENG 0x100c -#define PCI_DEVICE_ID_TSENG_W32P 0x3205 +#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 +#define PCI_DEVICE_ID_TSENG_W32P_5 0x3205 #define PCI_VENDOR_ID_CMD 0x1095 #define PCI_DEVICE_ID_CMD_640 0x0640 +#define PCI_VENDOR_ID_VISION 0x1098 +#define PCI_DEVICE_ID_VISION_QD8500 0x0001 + +#define PCI_VENDOR_ID_AMD 0x1022 +#define PCI_DEVICE_ID_AMD_LANCE 0x2000 + +#define PCI_VENDOR_ID_VLSI 0x1004 +#define PCI_DEVICE_ID_VLSI_82C593 0x0006 + +#define PCI_VENDOR_ID_AL 0x1005 +#define PCI_DEVICE_ID_AL_2301 0x2301 + +#define PCI_VENDOR_ID_SYMPHONY 0x1c1c +#define PCI_DEVICE_ID_SYMPHONY_101 0x0001 + +#define PCI_VENDOR_ID_TRIDENT 0x1023 +#define PCI_DEVICE_ID_TRIDENT_9420 0x9420 + struct pci_vendor_type { unsigned short vendor_id; char *vendor_name; }; -#define PCI_VENDOR_NUM 18 +#define PCI_VENDOR_NUM 24 #define PCI_VENDOR_TYPE { \ {PCI_VENDOR_ID_NCR, "NCR"}, \ {PCI_VENDOR_ID_ADAPTEC, "Adaptec"}, \ - {PCI_VENDOR_ID_DPT, "DPT"}, \ + {PCI_VENDOR_ID_DPT, "DPT"}, \ {PCI_VENDOR_ID_S3, "S3 Inc."}, \ {PCI_VENDOR_ID_OPTI, "OPTI"}, \ {PCI_VENDOR_ID_UMC, "UMC"}, \ @@ -288,52 +311,146 @@ {PCI_VENDOR_ID_ALI, "ALI"}, \ {PCI_VENDOR_ID_TSENG, "Tseng'Lab"}, \ {PCI_VENDOR_ID_CMD, "CMD"}, \ - {0, ""} \ + {PCI_VENDOR_ID_VISION, "Vision"}, \ + {PCI_VENDOR_ID_AMD, "AMD"}, \ + {PCI_VENDOR_ID_VLSI, "VLSI"}, \ + {PCI_VENDOR_ID_AL, "Advance Logic"}, \ + {PCI_VENDOR_ID_SYMPHONY, "Symphony"}, \ + {PCI_VENDOR_ID_TRIDENT, "Trident"} \ } + +/* Optimisation pointer is a offset of an item into the array */ +/* BRIDGE_MAPPING_TYPE. 0xff indicates that the device is not a PCI */ +/* bridge, or that we don't know for the moment how to configure it. */ +/* I'm trying to do my best so that the kernel stays small. */ +/* Different chipset can have same optimisation structure. i486 and */ +/* pentium chipsets from the same manufacturer usually have the same */ +/* structure */ + struct pci_device_type { + unsigned char bridge_id; unsigned short vendor_id; unsigned short device_id; char *device_name; }; -#define PCI_DEVICE_NUM 34 +#define PCI_DEVICE_NUM 45 #define PCI_DEVICE_TYPE { \ - {PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, "53c810"}, \ - {PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C815, "53c815"}, \ - {PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C820, "53c820"}, \ - {PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C825, "53c825"}, \ - {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_2940, "2940"}, \ - {PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, "SmartCache/Raid"}, \ - {PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_864_1, "Vision 864-P"}, \ - {PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_864_2, "Vision 864-P"}, \ - {PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_928, "Vision 928-P"}, \ - {PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_964, "Vision 964-P"}, \ - {PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_811, "Trio64"}, \ - {PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C822, "82C822"}, \ - {PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, "82C621"}, \ - {PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8881F, "UM8881F"}, \ - {PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886F, "UM8886F"}, \ - {PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F, "UM8673F"}, \ - {PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, "DC21040"}, \ - {PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, "DC21040"}, \ - {PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI, "DEFPA"}, \ - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, "82378IB"}, \ - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, "82424ZX"}, \ - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, "82375EB"}, \ - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82434, "82434LX"}, \ - {PCI_VENDOR_ID_SMC, PCI_DEVICE_ID_SMC_37C665, "FDC 37C665"}, \ - {PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_M32, "Mach 32"}, \ - {PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_M64, "Mach 64"}, \ - {PCI_VENDOR_ID_WEITEK, PCI_DEVICE_ID_WEITEK_P9000, "P9000"}, \ - {PCI_VENDOR_ID_WEITEK, PCI_DEVICE_ID_WEITEK_P9100, "P9100"}, \ - {PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5434, "GD 5434"}, \ - {PCI_VENDOR_ID_BUSLOGIC,PCI_DEVICE_ID_BUSLOGIC_946C, "946C"}, \ - {PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128, "Imagine 128"}, \ - {PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_M1435, "M1435"}, \ - {PCI_VENDOR_ID_TSENG, PCI_DEVICE_ID_TSENG_W32P, "ET4000W32P"}, \ - {PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640, "640A"}, \ - {0,0,"UNKNOWN DEVICE.PLEASE FIND OUT AND MAIL POTTER@CAO-VLSI.IBP.FR"} \ + {0xff, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, "53c810"}, \ + {0xff, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C815, "53c815"}, \ + {0xff, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C820, "53c820"}, \ + {0xff, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C825, "53c825"}, \ + {0xff, PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_2940, "2940"}, \ + {0xff, PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, "SmartCache/Raid"}, \ + {0xff, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_864_1, "Vision 864-P"}, \ + {0xff, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_864_2, "Vision 864-P"}, \ + {0xff, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_928, "Vision 928-P"}, \ + {0xff, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_964, "Vision 964-P"}, \ + {0xff, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_811, "Trio64"}, \ + {0x02, PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C822, "82C822"}, \ + {0xff, PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, "82C621"}, \ + {0xff, PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8881F, "UM8881F"}, \ + {0x01, PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8891A, "UM8891A"}, \ + {0xff, PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886F, "UM8886F"}, \ + {0xff, PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F, "UM8673F"}, \ + {0xff, PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, "DC21040"}, \ + {0xff, PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, "DC21040"}, \ + {0xff, PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI, "DEFPA"}, \ + {0xff, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, "82378IB"}, \ + {0x00, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, "82424ZX Saturn"}, \ + {0xff, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, "82375EB"}, \ + {0x00, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82434, "82434LX Mercury/Netpune"}, \ + {0xff, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82430, "82430ZX Aries"}, \ + {0xff, PCI_VENDOR_ID_SMC, PCI_DEVICE_ID_SMC_37C665, "FDC 37C665"}, \ + {0xff, PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_M32, "Mach 32"}, \ + {0xff, PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_M64, "Mach 64"}, \ + {0xff, PCI_VENDOR_ID_WEITEK, PCI_DEVICE_ID_WEITEK_P9000, "P9000"}, \ + {0xff, PCI_VENDOR_ID_WEITEK, PCI_DEVICE_ID_WEITEK_P9100, "P9100"}, \ + {0xff, PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5434_4, "GD 5434"}, \ + {0xff, PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5434_8, "GD 5434"}, \ + {0xff, PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6729, "CL 6729"}, \ + {0xff, PCI_VENDOR_ID_BUSLOGIC,PCI_DEVICE_ID_BUSLOGIC_946C, "946C"}, \ + {0xff, PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128, "Imagine 128"}, \ + {0xff, PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_M1435, "M1435"}, \ + {0xff, PCI_VENDOR_ID_TSENG, PCI_DEVICE_ID_TSENG_W32P_2, "ET4000W32P"}, \ + {0xff, PCI_VENDOR_ID_TSENG, PCI_DEVICE_ID_TSENG_W32P_5, "ET4000W32P"}, \ + {0xff, PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640, "640A"}, \ + {0xff, PCI_VENDOR_ID_VISION, PCI_DEVICE_ID_VISION_QD8500, "QD-8500PCI"}, \ + {0xff, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, "79C970"}, \ + {0xff, PCI_VENDOR_ID_VLSI, PCI_DEVICE_ID_VLSI_82C593, "82C593-FC1"}, \ + {0xff, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_2301, "2301"}, \ + {0xff, PCI_VENDOR_ID_SYMPHONY, PCI_DEVICE_ID_SYMPHONY_101, "82C101"}, \ + {0xff, PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_9420, "TG 9420"} \ +} + +/* An item of this structure has the following meaning */ +/* For each optimisation, the register adress, the mask */ +/* and value to write to turn it on. */ +/* There are 5 optimizations for the moment : */ +/* Cache L2 write back best than write through */ +/* Posted Write for CPU to PCI enable */ +/* Posted Write for CPU to MEMORY enable */ +/* Posted Write for PCI to MEMORY enable */ +/* PCI Burst enable */ + +/* Half of the bios I've meet don't allow you to turn */ +/* that on, and you can gain more than 15% on graphic */ +/* accesses using those optimisations... */ + +struct optimisation_type { + char *type; + char *off; + char *on; +}; + +#define OPTIMISATION_NUM 5 +#define OPTIMISATION_TYPE { \ + {"Cache L2","write trough","write back"}, \ + {"CPU-PCI posted write","off","on"}, \ + {"CPU-Memory posted write","off","on"}, \ + {"PCI-Memory posted write","off","on"}, \ + {"PCI burst","off","on"} \ +} + +struct bridge_mapping_type { + unsigned char adress; + unsigned char mask; + unsigned char value; +}; + +/* Intel Neptune/Mercury/Saturn */ +/* If the Internal cache is Write back, */ +/* the L2 cache must be write through ! */ +/* I've to check out how to control that */ +/* for the moment, we won't touch the cache*/ +/* UMC 8891A Pentium chipset */ +/* Why did you think UMC was cheaper ?? */ +/* OPTI 82C822 */ +/* This is a dummy entry for my tests. */ +/* I have this chipset and no docs.... */ + +/* I'am gathering docs. If you can help...... */ + +#define BRIDGE_MAPPING_NUM 3 +#define BRIDGE_MAPPING_TYPE { \ + {0x0 ,0x02 ,0x02 }, \ + {0x53 ,0x02 ,0x02 }, \ + {0x53 ,0x01 ,0x01 }, \ + {0x54 ,0x01 ,0x01 }, \ + {0x54 ,0x02 ,0x02 }, \ +\ + {0x50 ,0x10 ,0x00 }, \ + {0x51 ,0x40 ,0x40 }, \ + {0x0 ,0x0 ,0x0 }, \ + {0x0 ,0x0 ,0x0 }, \ + {0x0 ,0x0 ,0x0 }, \ +\ + {0x0 ,0x1 ,0x1 }, \ + {0x0 ,0x2 ,0x0 }, \ + {0x0 ,0x0 ,0x0 }, \ + {0x0 ,0x0 ,0x0 }, \ + {0x0 ,0x0 ,0x0 } \ } diff -u --recursive --new-file v1.1.81/linux/include/linux/sched.h linux/include/linux/sched.h --- v1.1.81/linux/include/linux/sched.h Mon Jan 9 07:22:11 1995 +++ linux/include/linux/sched.h Mon Jan 16 07:17:38 1995 @@ -9,7 +9,7 @@ * #define DEBUG */ -#define HZ 100 +#include /* for HZ */ extern unsigned long intr_count; extern unsigned long event; @@ -261,7 +261,8 @@ extern int send_sig(unsigned long sig,struct task_struct * p,int priv); extern int in_group_p(gid_t grp); -extern int request_irq(unsigned int irq,void (*handler)(int), unsigned long flags, const char *device); +extern int request_irq(unsigned int irq,void (*handler)(int, struct pt_regs *), + unsigned long flags, const char *device); extern void free_irq(unsigned int irq); extern unsigned long copy_thread(int, unsigned long, struct task_struct *, struct pt_regs *); diff -u --recursive --new-file v1.1.81/linux/include/linux/signal.h linux/include/linux/signal.h --- v1.1.81/linux/include/linux/signal.h Sun Oct 9 11:50:06 1994 +++ linux/include/linux/signal.h Mon Jan 16 07:17:38 1995 @@ -1,7 +1,7 @@ #ifndef _LINUX_SIGNAL_H #define _LINUX_SIGNAL_H -typedef unsigned int sigset_t; /* 32 bits */ +typedef unsigned long sigset_t; /* at least 32 bits */ #define _NSIG 32 #define NSIG _NSIG @@ -29,14 +29,14 @@ #define SIGTSTP 20 #define SIGTTIN 21 #define SIGTTOU 22 -#define SIGIO 23 -#define SIGPOLL SIGIO -#define SIGURG SIGIO +#define SIGURG 23 #define SIGXCPU 24 #define SIGXFSZ 25 #define SIGVTALRM 26 #define SIGPROF 27 #define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO /* #define SIGLOST 29 */ @@ -72,36 +72,13 @@ struct sigaction { __sighandler_t sa_handler; sigset_t sa_mask; - int sa_flags; + unsigned long sa_flags; void (*sa_restorer)(void); }; #ifdef __KERNEL__ -struct sigcontext_struct { - unsigned short gs, __gsh; - unsigned short fs, __fsh; - unsigned short es, __esh; - unsigned short ds, __dsh; - unsigned long edi; - unsigned long esi; - unsigned long ebp; - unsigned long esp; - unsigned long ebx; - unsigned long edx; - unsigned long ecx; - unsigned long eax; - unsigned long trapno; - unsigned long err; - unsigned long eip; - unsigned short cs, __csh; - unsigned long eflags; - unsigned long esp_at_signal; - unsigned short ss, __ssh; - unsigned long i387; - unsigned long oldmask; - unsigned long cr2; -}; +#include #endif diff -u --recursive --new-file v1.1.81/linux/include/linux/xia_fs.h linux/include/linux/xia_fs.h --- v1.1.81/linux/include/linux/xia_fs.h Wed Dec 1 14:44:15 1993 +++ linux/include/linux/xia_fs.h Sun Jan 15 21:50:22 1995 @@ -62,6 +62,8 @@ char d_name[_XIAFS_NAME_LEN+1]; }; +#ifdef __KERNEL__ + extern int xiafs_lookup(struct inode * dir,const char * name, int len, struct inode ** result); extern int xiafs_create(struct inode * dir,const char * name, int len, int mode, @@ -103,6 +105,8 @@ extern struct inode_operations xiafs_file_inode_operations; extern struct inode_operations xiafs_dir_inode_operations; extern struct inode_operations xiafs_symlink_inode_operations; + +#endif /* __KERNEL__ */ #endif /* _XIA_FS_H */ diff -u --recursive --new-file v1.1.81/linux/init/main.c linux/init/main.c --- v1.1.81/linux/init/main.c Fri Jan 13 16:57:06 1995 +++ linux/init/main.c Mon Jan 16 07:17:38 1995 @@ -68,7 +68,6 @@ extern int console_loglevel; -extern char empty_zero_page[PAGE_SIZE]; extern void init(void); extern void init_IRQ(void); extern void init_modules(void); @@ -114,35 +113,22 @@ #endif /* - * 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)) - -/* * Boot command-line arguments */ #define MAX_INIT_ARGS 8 #define MAX_INIT_ENVS 8 -#define COMMAND_LINE ((char *) (PARAM+2048)) -#define COMMAND_LINE_SIZE 256 extern void time_init(void); -static unsigned long memory_start = 0; /* After mem_init, stores the */ - /* amount of free user memory */ +static unsigned long memory_start = 0; static unsigned long memory_end = 0; -static unsigned long low_memory_start = 0; static char term[21]; int rows, cols; +int ramdisk_size; +int root_mountflags = 0; + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", term, NULL, }; @@ -152,15 +138,6 @@ static char * argv[] = { "-/bin/sh",NULL }; static char * envp[] = { "HOME=/usr/root", term, NULL }; -struct drive_info_struct { char dummy[32]; } drive_info; -struct screen_info screen_info; - -unsigned char aux_device_present; -int ramdisk_size; -int root_mountflags = 0; - -static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char *get_options(char *str, int *ints) { char *cur = str; @@ -379,62 +356,17 @@ envp_init[envs+1] = NULL; } -static void copy_options(char * to, char * from) -{ - char c = ' '; - int len = 0; - - 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'; -} - extern void check_bugs(void); +extern void setup_arch(char **, unsigned long *, unsigned long *); asmlinkage void start_kernel(void) { + char * command_line; /* * Interrupts are still disabled. Do necessary setups, then * enable them */ - 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; - copy_options(command_line,COMMAND_LINE); -#ifdef CONFIG_MAX_16M - if (memory_end > 16*1024*1024) - memory_end = 16*1024*1024; -#endif - if (MOUNT_ROOT_RDONLY) - root_mountflags |= MS_RDONLY; - if ((unsigned long)&end >= (1024*1024)) { - memory_start = (unsigned long) &end; - low_memory_start = PAGE_SIZE; - } else { - memory_start = 1024*1024; - low_memory_start = (unsigned long) &end; - } - low_memory_start = PAGE_ALIGN(low_memory_start); + setup_arch(&command_line, &memory_start, &memory_end); memory_start = paging_init(memory_start,memory_end); trap_init(); init_IRQ(); @@ -466,7 +398,7 @@ memory_start = inode_init(memory_start,memory_end); memory_start = file_table_init(memory_start,memory_end); memory_start = name_cache_init(memory_start,memory_end); - mem_init(low_memory_start,memory_start,memory_end); + mem_init(memory_start,memory_end); buffer_init(); time_init(); sock_init(); diff -u --recursive --new-file v1.1.81/linux/kernel/Makefile linux/kernel/Makefile --- v1.1.81/linux/kernel/Makefile Fri Jan 13 10:12:24 1995 +++ linux/kernel/Makefile Mon Jan 16 07:17:38 1995 @@ -16,7 +16,7 @@ .c.o: $(CC) $(CFLAGS) -c $< -OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o vsprintf.o sys.o \ +OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \ module.o ksyms.o exit.o signal.o itimer.o info.o time.o softirq.o \ resource.o diff -u --recursive --new-file v1.1.81/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v1.1.81/linux/kernel/ksyms.c Fri Jan 13 16:57:07 1995 +++ linux/kernel/ksyms.c Mon Jan 16 07:17:38 1995 @@ -46,6 +46,7 @@ #include extern char floppy_track_buffer[]; extern void set_device_ro(int dev,int flag); +extern struct file_operations * get_blkfops(unsigned int); extern void *sys_call_table; @@ -162,6 +163,7 @@ X(set_device_ro), X(bmap), X(sync_dev), + X(get_blkfops), /* Module creation of serial units */ X(register_serial), diff -u --recursive --new-file v1.1.81/linux/kernel/sched.c linux/kernel/sched.c --- v1.1.81/linux/kernel/sched.c Fri Jan 13 10:12:24 1995 +++ linux/kernel/sched.c Mon Jan 16 07:17:38 1995 @@ -531,7 +531,7 @@ * irq uses this to decide if it should update the user or system * times. */ -static void do_timer(struct pt_regs * regs) +static void do_timer(int irq, struct pt_regs * regs) { unsigned long mask; struct timer_struct *tp; @@ -766,11 +766,6 @@ bh_base[TIMER_BH].routine = timer_bh; bh_base[TQUEUE_BH].routine = tqueue_bh; bh_base[IMMEDIATE_BH].routine = immediate_bh; - if (sizeof(struct sigaction) != 16) - panic("Struct sigaction MUST be 16 bytes"); - outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ - outb_p(LATCH & 0xff , 0x40); /* LSB */ - outb(LATCH >> 8 , 0x40); /* MSB */ - if (request_irq(TIMER_IRQ,(void (*)(int)) do_timer, 0, "timer") != 0) + if (request_irq(TIMER_IRQ, do_timer, 0, "timer") != 0) panic("Could not allocate timer IRQ!"); } diff -u --recursive --new-file v1.1.81/linux/kernel/vsprintf.c linux/kernel/vsprintf.c --- v1.1.81/linux/kernel/vsprintf.c Mon Oct 24 07:55:12 1994 +++ linux/kernel/vsprintf.c Thu Jan 1 02:00:00 1970 @@ -1,309 +0,0 @@ -/* - * linux/kernel/vsprintf.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ -/* - * Wirzenius wrote this portably, Torvalds fucked it up :-) - */ - -#include -#include -#include -#include - -unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) -{ - unsigned long result = 0,value; - - if (!base) { - base = 10; - if (*cp == '0') { - base = 8; - cp++; - if ((*cp == 'x') && isxdigit(cp[1])) { - cp++; - base = 16; - } - } - } - while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) - ? toupper(*cp) : *cp)-'A'+10) < base) { - result = result*base + value; - cp++; - } - if (endp) - *endp = (char *)cp; - return result; -} - -/* we use this so that we can do without the ctype library */ -#define is_digit(c) ((c) >= '0' && (c) <= '9') - -static int skip_atoi(const char **s) -{ - int i=0; - - while (is_digit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} - -#define ZEROPAD 1 /* pad with zero */ -#define SIGN 2 /* unsigned/signed long */ -#define PLUS 4 /* show plus */ -#define SPACE 8 /* space if plus */ -#define LEFT 16 /* left justified */ -#define SPECIAL 32 /* 0x */ -#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ - -#define do_div(n,base) ({ \ -int __res; \ -__res = ((unsigned long) n) % (unsigned) base; \ -n = ((unsigned long) n) / (unsigned) base; \ -__res; }) - -static char * number(char * str, long num, int base, int size, int precision - ,int type) -{ - char c,sign,tmp[36]; - const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; - int i; - - if (type & LARGE) - digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - if (type & LEFT) - type &= ~ZEROPAD; - if (base < 2 || base > 36) - return 0; - c = (type & ZEROPAD) ? '0' : ' '; - sign = 0; - if (type & SIGN) { - if (num < 0) { - sign = '-'; - num = -num; - size--; - } else if (type & PLUS) { - sign = '+'; - size--; - } else if (type & SPACE) { - sign = ' '; - size--; - } - } - if (type & SPECIAL) { - if (base == 16) - size -= 2; - else if (base == 8) - size--; - } - i = 0; - if (num == 0) - tmp[i++]='0'; - else while (num != 0) - tmp[i++] = digits[do_div(num,base)]; - if (i > precision) - precision = i; - size -= precision; - if (!(type&(ZEROPAD+LEFT))) - while(size-->0) - *str++ = ' '; - if (sign) - *str++ = sign; - if (type & SPECIAL) - if (base==8) - *str++ = '0'; - else if (base==16) { - *str++ = '0'; - *str++ = digits[33]; - } - if (!(type & LEFT)) - while (size-- > 0) - *str++ = c; - while (i < precision--) - *str++ = '0'; - while (i-- > 0) - *str++ = tmp[i]; - while (size-- > 0) - *str++ = ' '; - return str; -} - -int vsprintf(char *buf, const char *fmt, va_list args) -{ - int len; - unsigned long num; - int i, base; - char * str; - char *s; - - int flags; /* flags to number() */ - - int field_width; /* width of output field */ - int precision; /* min. # of digits for integers; max - number of chars for from string */ - int qualifier; /* 'h', 'l', or 'L' for integer fields */ - - for (str=buf ; *fmt ; ++fmt) { - if (*fmt != '%') { - *str++ = *fmt; - continue; - } - - /* process flags */ - flags = 0; - repeat: - ++fmt; /* this also skips first '%' */ - switch (*fmt) { - case '-': flags |= LEFT; goto repeat; - case '+': flags |= PLUS; goto repeat; - case ' ': flags |= SPACE; goto repeat; - case '#': flags |= SPECIAL; goto repeat; - case '0': flags |= ZEROPAD; goto repeat; - } - - /* get field width */ - field_width = -1; - if (is_digit(*fmt)) - field_width = skip_atoi(&fmt); - else if (*fmt == '*') { - ++fmt; - /* it's the next argument */ - field_width = va_arg(args, int); - if (field_width < 0) { - field_width = -field_width; - flags |= LEFT; - } - } - - /* get the precision */ - precision = -1; - if (*fmt == '.') { - ++fmt; - if (is_digit(*fmt)) - precision = skip_atoi(&fmt); - else if (*fmt == '*') { - ++fmt; - /* it's the next argument */ - precision = va_arg(args, int); - } - if (precision < 0) - precision = 0; - } - - /* get the conversion qualifier */ - qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { - qualifier = *fmt; - ++fmt; - } - - /* default base */ - base = 10; - - switch (*fmt) { - case 'c': - if (!(flags & LEFT)) - while (--field_width > 0) - *str++ = ' '; - *str++ = (unsigned char) va_arg(args, int); - while (--field_width > 0) - *str++ = ' '; - continue; - - case 's': - s = va_arg(args, char *); - if (!s) - s = ""; - len = strlen(s); - if (precision < 0) - precision = len; - else if (len > precision) - len = precision; - - if (!(flags & LEFT)) - while (len < field_width--) - *str++ = ' '; - for (i = 0; i < len; ++i) - *str++ = *s++; - while (len < field_width--) - *str++ = ' '; - continue; - - case 'p': - if (field_width == -1) { - field_width = 2*sizeof(void *); - flags |= ZEROPAD; - } - str = number(str, - (unsigned long) va_arg(args, void *), 16, - field_width, precision, flags); - continue; - - - case 'n': - if (qualifier == 'l') { - long * ip = va_arg(args, long *); - *ip = (str - buf); - } else { - int * ip = va_arg(args, int *); - *ip = (str - buf); - } - continue; - - /* integer number formats - set up the flags and "break" */ - case 'o': - base = 8; - break; - - case 'X': - flags |= LARGE; - case 'x': - base = 16; - break; - - case 'd': - case 'i': - flags |= SIGN; - case 'u': - break; - - default: - if (*fmt != '%') - *str++ = '%'; - if (*fmt) - *str++ = *fmt; - else - --fmt; - continue; - } - if (qualifier == 'l') - num = va_arg(args, unsigned long); - else if (qualifier == 'h') - if (flags & SIGN) - num = va_arg(args, short); - else - num = va_arg(args, unsigned short); - else if (flags & SIGN) - num = va_arg(args, int); - else - num = va_arg(args, unsigned int); - str = number(str, num, base, field_width, precision, flags); - } - *str = '\0'; - return str-buf; -} - -int sprintf(char * buf, const char *fmt, ...) -{ - va_list args; - int i; - - va_start(args, fmt); - i=vsprintf(buf,fmt,args); - va_end(args); - return i; -} - diff -u --recursive --new-file v1.1.81/linux/lib/Makefile linux/lib/Makefile --- v1.1.81/linux/lib/Makefile Mon Jan 9 07:22:12 1995 +++ linux/lib/Makefile Mon Jan 16 07:17:38 1995 @@ -14,7 +14,7 @@ $(CC) $(CFLAGS) -c $< OBJS = ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o \ - execve.o wait.o string.o + execve.o wait.o string.o vsprintf.o lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) diff -u --recursive --new-file v1.1.81/linux/lib/string.c linux/lib/string.c --- v1.1.81/linux/lib/string.c Fri Jan 13 10:12:24 1995 +++ linux/lib/string.c Mon Jan 16 07:17:38 1995 @@ -168,6 +168,16 @@ return s; } +char * bcopy(const char * src, char * dest, int count) +{ + char *tmp = dest; + + while (count--) + *tmp++ = *src++; + + return dest; +} + void * memcpy(void * dest,const void *src,size_t count) { char *tmp = (char *) dest, *s = (char *) src; diff -u --recursive --new-file v1.1.81/linux/lib/vsprintf.c linux/lib/vsprintf.c --- v1.1.81/linux/lib/vsprintf.c Thu Jan 1 02:00:00 1970 +++ linux/lib/vsprintf.c Mon Jan 16 07:17:39 1995 @@ -0,0 +1,309 @@ +/* + * linux/lib/vsprintf.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + */ + +#include +#include +#include +#include + +unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) +{ + unsigned long result = 0,value; + + if (!base) { + base = 10; + if (*cp == '0') { + base = 8; + cp++; + if ((*cp == 'x') && isxdigit(cp[1])) { + cp++; + base = 16; + } + } + } + while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) + ? toupper(*cp) : *cp)-'A'+10) < base) { + result = result*base + value; + cp++; + } + if (endp) + *endp = (char *)cp; + return result; +} + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const char **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + +#define do_div(n,base) ({ \ +int __res; \ +__res = ((unsigned long) n) % (unsigned) base; \ +n = ((unsigned long) n) / (unsigned) base; \ +__res; }) + +static char * number(char * str, long num, int base, int size, int precision + ,int type) +{ + char c,sign,tmp[36]; + const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; + int i; + + if (type & LARGE) + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if (num < 0) { + sign = '-'; + num = -num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + if (type & SPECIAL) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + i = 0; + if (num == 0) + tmp[i++]='0'; + else while (num != 0) + tmp[i++] = digits[do_div(num,base)]; + if (i > precision) + precision = i; + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) + if (base==8) + *str++ = '0'; + else if (base==16) { + *str++ = '0'; + *str++ = digits[33]; + } + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + return str; +} + +int vsprintf(char *buf, const char *fmt, va_list args) +{ + int len; + unsigned long num; + int i, base; + char * str; + char *s; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + continue; + + case 's': + s = va_arg(args, char *); + if (!s) + s = ""; + len = strlen(s); + if (precision < 0) + precision = len; + else if (len > precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; + + case 'p': + if (field_width == -1) { + field_width = 2*sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + continue; + + + case 'n': + if (qualifier == 'l') { + long * ip = va_arg(args, long *); + *ip = (str - buf); + } else { + int * ip = va_arg(args, int *); + *ip = (str - buf); + } + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'X': + flags |= LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + if (qualifier == 'l') + num = va_arg(args, unsigned long); + else if (qualifier == 'h') + if (flags & SIGN) + num = va_arg(args, short); + else + num = va_arg(args, unsigned short); + else if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + str = number(str, num, base, field_width, precision, flags); + } + *str = '\0'; + return str-buf; +} + +int sprintf(char * buf, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=vsprintf(buf,fmt,args); + va_end(args); + return i; +} + diff -u --recursive --new-file v1.1.81/linux/mm/memory.c linux/mm/memory.c --- v1.1.81/linux/mm/memory.c Fri Jan 13 10:12:24 1995 +++ linux/mm/memory.c Mon Jan 16 07:17:39 1995 @@ -60,7 +60,7 @@ #define copy_page(from,to) memcpy((void *) to, (void *) from, PAGE_SIZE) -unsigned short * mem_map = NULL; +mem_map_t * mem_map = NULL; #define CODE_SPACE(addr,p) ((addr) < (p)->end_code) @@ -540,7 +540,7 @@ * in better assembly code.. The "default" path will see no jumps at all. */ void do_wp_page(struct vm_area_struct * vma, unsigned long address, - unsigned long error_code) + int write_access) { unsigned long *pde, pte, old_page, prot; unsigned long new_page; @@ -780,7 +780,7 @@ * It should be >1 if there are other tasks sharing this inode. */ static int share_page(struct vm_area_struct * area, unsigned long address, - unsigned long error_code, unsigned long newpage) + int write_access, unsigned long newpage) { struct inode * inode; unsigned long offset; @@ -792,7 +792,7 @@ return 0; /* do we need to copy or can we just share? */ give_page = 0; - if ((area->vm_page_prot & PAGE_COW) && (error_code & PAGE_RW)) { + if ((area->vm_page_prot & PAGE_COW) && write_access) { if (!newpage) return 0; give_page = newpage; @@ -882,7 +882,7 @@ } void do_no_page(struct vm_area_struct * vma, unsigned long address, - unsigned long error_code) + int write_access) { unsigned long page, entry, prot; @@ -907,7 +907,7 @@ return; } page = get_free_page(GFP_KERNEL); - if (share_page(vma, address, error_code, page)) { + if (share_page(vma, address, write_access, page)) { ++vma->vm_task->mm->min_flt; ++vma->vm_task->mm->rss; return; @@ -925,16 +925,17 @@ * to copy, not share the page even if sharing is possible. It's * essentially an early COW detection ("moo at 5 AM"). */ - page = vma->vm_ops->nopage(vma, address, page, (error_code & PAGE_RW) && (prot & PAGE_COW)); - if (share_page(vma, address, error_code, 0)) { + page = vma->vm_ops->nopage(vma, address, page, write_access && (prot & PAGE_COW)); + if (share_page(vma, address, write_access, 0)) { free_page(page); return; } /* * This silly early PAGE_DIRTY setting removes a race - * due to the bad i386 page protection. + * due to the bad i386 page protection. But it's valid + * for other architectures too. */ - if (error_code & PAGE_RW) { + if (write_access) { prot |= PAGE_DIRTY; /* can't be COW-shared: see "no_share" above */ } else if ((prot & PAGE_COW) && mem_map[MAP_NR(page)] > 1) prot &= ~PAGE_RW; diff -u --recursive --new-file v1.1.81/linux/mm/mprotect.c linux/mm/mprotect.c --- v1.1.81/linux/mm/mprotect.c Fri Jan 13 10:12:24 1995 +++ linux/mm/mprotect.c Mon Jan 16 07:17:39 1995 @@ -16,8 +16,6 @@ #include #include -#define CHG_MASK (PAGE_MASK | PAGE_ACCESSED | PAGE_DIRTY | PAGE_PWT | PAGE_PCD) - static void change_protection(unsigned long start, unsigned long end, int prot) { unsigned long *page_table, *dir; @@ -43,7 +41,7 @@ do { page = *page_table; if (page & PAGE_PRESENT) - *page_table = (page & CHG_MASK) | prot; + *page_table = (page & PAGE_CHG_MASK) | prot; ++page_table; } while (--offset); } diff -u --recursive --new-file v1.1.81/linux/mm/swap.c linux/mm/swap.c --- v1.1.81/linux/mm/swap.c Fri Jan 13 10:12:24 1995 +++ linux/mm/swap.c Mon Jan 16 07:17:39 1995 @@ -78,7 +78,7 @@ swap_cache_add_total++; #endif if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) { - entry = (unsigned long) xchg_ptr(swap_cache + (addr >> PAGE_SHIFT), (void *) entry); + entry = (unsigned long) xchg_ptr(swap_cache + MAP_NR(addr), (void *) entry); if (entry) { printk("swap_cache: replacing non-NULL entry\n"); } @@ -97,7 +97,7 @@ mem_start = (mem_start + 15) & ~15; swap_cache = (unsigned long *) mem_start; - swap_cache_size = mem_end >> PAGE_SHIFT; + swap_cache_size = MAP_NR(mem_end); memset(swap_cache, 0, swap_cache_size * sizeof (unsigned long)); return (unsigned long) (swap_cache + swap_cache_size); } @@ -547,7 +547,7 @@ */ static inline void free_pages_ok(unsigned long addr, unsigned long order) { - unsigned long index = addr >> (PAGE_SHIFT + 1 + order); + unsigned long index = MAP_NR(addr) >> (1 + order); unsigned long mask = PAGE_MASK << order; addr &= mask; @@ -583,7 +583,7 @@ { if (addr < high_memory) { unsigned long flag; - unsigned short * map = mem_map + MAP_NR(addr); + mem_map_t * map = mem_map + MAP_NR(addr); if (*map) { if (!(*map & MAP_PAGE_RESERVED)) { save_flags(flag); @@ -624,7 +624,7 @@ static inline int mark_used(unsigned long addr, unsigned long order) { - return change_bit(addr >> (PAGE_SHIFT+1+order), free_area_map[order]); + return change_bit(MAP_NR(addr) >> (1+order), free_area_map[order]); } #define EXPAND(addr,low,high) \ @@ -1017,7 +1017,7 @@ */ unsigned long free_area_init(unsigned long start_mem, unsigned long end_mem) { - unsigned short * p; + mem_map_t * p; unsigned long mask = PAGE_MASK; int i; @@ -1025,12 +1025,12 @@ * select nr of pages we try to keep free for important stuff * with a minimum of 16 pages. This is totally arbitrary */ - i = end_mem >> (PAGE_SHIFT+6); + i = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT+6); if (i < 16) i = 16; min_free_pages = i; start_mem = init_swap_cache(start_mem, end_mem); - mem_map = (unsigned short *) start_mem; + mem_map = (mem_map_t *) start_mem; p = mem_map + MAP_NR(end_mem); start_mem = (unsigned long) p; while (p > mem_map) @@ -1041,8 +1041,9 @@ free_area_list[i].prev = free_area_list[i].next = &free_area_list[i]; mask += mask; end_mem = (end_mem + ~mask) & mask; - bitmap_size = end_mem >> (PAGE_SHIFT + i); + bitmap_size = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT + i); bitmap_size = (bitmap_size + 7) >> 3; + bitmap_size = (bitmap_size + sizeof(unsigned long) - 1) & ~(sizeof(unsigned long)-1); free_area_map[i] = (unsigned char *) start_mem; memset((void *) start_mem, 0, bitmap_size); start_mem += bitmap_size; diff -u --recursive --new-file v1.1.81/linux/net/inet/Makefile linux/net/inet/Makefile --- v1.1.81/linux/net/inet/Makefile Mon Jan 9 07:22:12 1995 +++ linux/net/inet/Makefile Mon Jan 16 07:17:39 1995 @@ -56,7 +56,7 @@ else inet.o: - echo | $(AS) -o inet.o + $(AR) rcs inet.o endif diff -u --recursive --new-file v1.1.81/linux/net/inet/sock.c linux/net/inet/sock.c --- v1.1.81/linux/net/inet/sock.c Mon Jan 9 07:22:13 1995 +++ linux/net/inet/sock.c Mon Jan 16 07:17:39 1995 @@ -522,8 +522,10 @@ void release_sock(struct sock *sk) { - struct sk_buff *skb; unsigned long flags; +#ifdef CONFIG_INET + struct sk_buff *skb; +#endif if (!sk->prot) return;