]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.30pre4 2.3.30pre4
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:28:54 +0000 (15:28 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:28:54 +0000 (15:28 -0500)
177 files changed:
Documentation/vm/locking
arch/alpha/kernel/Makefile
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/core_mcpcia.c
arch/alpha/kernel/core_tsunami.c
arch/alpha/kernel/fpreg.c [deleted file]
arch/alpha/kernel/irq.c
arch/alpha/kernel/pci.c
arch/alpha/kernel/pci_impl.h
arch/alpha/kernel/process.c
arch/alpha/kernel/proto.h
arch/alpha/kernel/setup.c
arch/alpha/kernel/smp.c
arch/alpha/kernel/sys_alcor.c
arch/alpha/kernel/sys_cabriolet.c
arch/alpha/kernel/sys_dp264.c
arch/alpha/kernel/sys_eb64p.c
arch/alpha/kernel/sys_eiger.c
arch/alpha/kernel/sys_jensen.c
arch/alpha/kernel/sys_miata.c
arch/alpha/kernel/sys_mikasa.c
arch/alpha/kernel/sys_nautilus.c
arch/alpha/kernel/sys_noritake.c
arch/alpha/kernel/sys_rawhide.c
arch/alpha/kernel/sys_ruffian.c
arch/alpha/kernel/sys_rx164.c
arch/alpha/kernel/sys_sable.c
arch/alpha/kernel/sys_sio.c
arch/alpha/kernel/sys_sx164.c
arch/alpha/kernel/sys_takara.c
arch/alpha/kernel/traps.c
arch/alpha/lib/Makefile
arch/alpha/lib/fpreg.c [new file with mode: 0644]
arch/alpha/math-emu/Makefile
arch/alpha/math-emu/fp-emul.c [deleted file]
arch/alpha/math-emu/fp-emul.h [deleted file]
arch/alpha/math-emu/ieee-math.c [deleted file]
arch/alpha/math-emu/ieee-math.h [deleted file]
arch/alpha/math-emu/math.c [new file with mode: 0644]
arch/alpha/math-emu/sfp-util.h [new file with mode: 0644]
arch/alpha/mm/init.c
arch/arm/Makefile
arch/arm/kernel/bios32.c
arch/arm/kernel/ecard.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/fiq.c
arch/arm/kernel/ioport.c
arch/arm/kernel/process.c
arch/arm/kernel/setup.c
arch/arm/kernel/traps.c
arch/arm/mm/init.c
arch/arm/mm/mm-armv.c
arch/arm/mm/proc-arm2,3.S
arch/arm/mm/proc-arm6,7.S
arch/arm/mm/proc-sa110.S
arch/i386/kernel/i386_ksyms.c
arch/i386/kernel/smp.c
arch/i386/mm/init.c
arch/m68k/atari/stram.c
arch/ppc/Makefile
arch/ppc/coffboot/Makefile
arch/ppc/coffboot/chrpmain.c [new file with mode: 0644]
arch/ppc/coffboot/coffcrt0.S [new file with mode: 0644]
arch/ppc/coffboot/coffmain.c [new file with mode: 0644]
arch/ppc/coffboot/crt0.S
arch/ppc/coffboot/misc.S
arch/ppc/coffboot/mknote.c [new file with mode: 0644]
arch/ppc/coffboot/no_initrd.c [new file with mode: 0644]
arch/ppc/coffboot/piggyback.c [new file with mode: 0644]
arch/ppc/coffboot/start.c
arch/ppc/config.in
arch/ppc/configs/common_defconfig
arch/ppc/defconfig
arch/ppc/kernel/align.c
arch/ppc/kernel/entry.S
arch/ppc/kernel/gemini_setup.c
arch/ppc/kernel/head.S
arch/ppc/kernel/misc.S
arch/ppc/kernel/open_pic.c
arch/ppc/kernel/pci.c
arch/ppc/kernel/pmac_nvram.c
arch/ppc/kernel/pmac_pci.c
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/kernel/setup.c
arch/ppc/kernel/smp.c
arch/ppc/lib/checksum.S
arch/ppc/mm/init.c
arch/ppc/mm/mem_pieces.h
arch/ppc/xmon/privinst.h
arch/ppc/xmon/start.c
arch/ppc/xmon/xmon.c
arch/sparc/math-emu/math.c
arch/sparc/math-emu/sfp-machine.h [deleted file]
arch/sparc64/math-emu/math.c
arch/sparc64/math-emu/sfp-machine.h [deleted file]
drivers/acorn/char/serial-atomwide.c
drivers/acorn/char/serial-card.c
drivers/acorn/char/serial-dualsp.c
drivers/block/ide-cd.c
drivers/block/md.c
drivers/block/sl82c105.c
drivers/cdrom/cdrom.c
drivers/char/lp.c
drivers/char/serial.c
drivers/misc/acpi.c
drivers/net/de4x5.c
drivers/net/hp100.c
drivers/pci/pci.c
drivers/pnp/isapnp.c
drivers/pnp/isapnp_proc.c
drivers/scsi/aic7xxx.c
drivers/scsi/qlogicisp.c
drivers/scsi/u14-34f.c
drivers/sound/sonicvibes.c
drivers/sound/waveartist.c
drivers/usb/mouse.c
drivers/video/Config.in
drivers/video/acornfb.c
drivers/video/atafb.c
drivers/video/cyber2000fb.c
drivers/video/cyber2000fb.h
drivers/video/dnfb.c
drivers/video/fbcon.c
drivers/video/fbmem.c
drivers/video/hpfb.c
fs/buffer.c
fs/ext2/acl.c
fs/ext2/balloc.c
fs/ext2/bitmap.c
fs/ext2/dir.c
fs/ext2/file.c
fs/ext2/fsync.c
fs/ext2/ialloc.c
fs/ext2/inode.c
fs/ext2/ioctl.c
fs/ext2/namei.c
fs/ext2/symlink.c
fs/ext2/truncate.c
fs/filesystems.c
fs/ncpfs/dir.c
include/asm-alpha/core_tsunami.h
include/asm-alpha/fpu.h
include/asm-alpha/machvec.h
include/asm-alpha/mmu_context.h
include/asm-alpha/sfp-machine.h [new file with mode: 0644]
include/asm-arm/arch-cl7500/system.h
include/asm-arm/arch-ebsa110/system.h
include/asm-arm/arch-ebsa285/system.h
include/asm-arm/arch-sa1100/system.h
include/asm-i386/highmem.h
include/asm-i386/spinlock.h
include/asm-ppc/bootinfo.h
include/asm-ppc/pgalloc.h
include/asm-ppc/pgtable.h
include/asm-ppc/resource.h
include/asm-ppc/unistd.h
include/asm-sparc/sfp-machine.h [new file with mode: 0644]
include/asm-sparc64/sfp-machine.h [new file with mode: 0644]
include/linux/acpi.h
include/linux/cdrom.h
include/linux/fb.h
include/linux/sched.h
include/linux/swap.h
include/math-emu/double.h
include/math-emu/extended.h
include/math-emu/op-2.h
include/math-emu/op-common.h
include/math-emu/quad.h
include/math-emu/single.h
include/math-emu/soft-fp.h
include/video/fbcon.h
ipc/shm.c
mm/highmem.c
mm/memory.c
mm/page_io.c
mm/swap_state.c
mm/swapfile.c

index 20921f6e4ebbe826de8a66c7008e3eafdfd27126..0e4e503ae7acced15f150ef09bd5a3c270bb5c9d 100644 (file)
@@ -85,3 +85,24 @@ The current implementation of the vmlist lock uses the page_table_lock,
 which is also the spinlock that page stealers use to protect changes to
 the victim process' ptes. Thus we have a reduction in the total number
 of locks. 
+
+swap_list_lock/swap_device_lock
+-------------------------------
+The swap devices are chained in priority order from the "swap_list" header. 
+The "swap_list" is used for the round-robin swaphandle allocation strategy.
+The #free swaphandles is maintained in "nr_swap_pages". These two together
+are protected by the swap_list_lock. 
+
+The swap_device_lock, which is per swap device, protects the reference 
+counts on the corresponding swaphandles, maintained in the "swap_map"
+array, and the "highest_bit" and "lowest_bit" fields.
+
+Both of these are spinlocks, and are never acquired from intr level. The
+locking heirarchy is swap_list_lock -> swap_device_lock.
+
+To prevent races between swap space deletion or async readahead swapins
+deciding whether a swap handle is being used, ie worthy of being read in
+from disk, and an unmap -> swap_free making the handle unused, the swap
+delete and readahead code grabs a temp reference on the swaphandle to
+prevent warning messages from swap_duplicate <- read_swap_cache_async.
+
index 4f7c411b0ab52cdda7a68b198f3920915bd2b07d..9210ae57c10be5dc1491f8433ead5bed42919807 100644 (file)
@@ -14,7 +14,7 @@
 
 O_TARGET := kernel.o
 O_OBJS   := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \
-           ptrace.o time.o fpreg.o semaphore.o
+           ptrace.o time.o semaphore.o
 OX_OBJS  := alpha_ksyms.o
 
 
index c8224cbd3cbd791732e57c328d27a35e139741ad..ef8be067c2a837d3613e40b3e29aa24c8dba84cd 100644 (file)
@@ -103,7 +103,9 @@ EXPORT_SYMBOL(hwrpb);
 EXPORT_SYMBOL(wrusp);
 EXPORT_SYMBOL(start_thread);
 EXPORT_SYMBOL(alpha_read_fp_reg);
+EXPORT_SYMBOL(alpha_read_fp_reg_s);
 EXPORT_SYMBOL(alpha_write_fp_reg);
+EXPORT_SYMBOL(alpha_write_fp_reg_s);
 
 /* In-kernel system calls.  */
 EXPORT_SYMBOL(kernel_thread);
index a66cde26eccde24782b29f68e91636c894b007d7..b4fe2884980a5b2020fc33b6feccbe5f6645f9b2 100644 (file)
@@ -205,7 +205,7 @@ mk_conf_addr(struct pci_dev *dev, int where, struct pci_controler *hose,
 static int
 mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
 {
-       struct pci_controler *hose = dev->sysdata ? : probing_hose;
+       struct pci_controler *hose = dev->sysdata;
        unsigned long addr, w;
        unsigned char type1;
 
@@ -221,7 +221,7 @@ mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
 static int
 mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
 {
-       struct pci_controler *hose = dev->sysdata ? : probing_hose;
+       struct pci_controler *hose = dev->sysdata;
        unsigned long addr, w;
        unsigned char type1;
 
@@ -237,7 +237,7 @@ mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
 static int
 mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
-       struct pci_controler *hose = dev->sysdata ? : probing_hose;
+       struct pci_controler *hose = dev->sysdata;
        unsigned long addr;
        unsigned char type1;
 
@@ -252,7 +252,7 @@ mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 static int
 mcpcia_write_config(struct pci_dev *dev, int where, u32 value, long mask)
 {
-       struct pci_controler *hose = dev->sysdata ? : probing_hose;
+       struct pci_controler *hose = dev->sysdata;
        unsigned long addr;
        unsigned char type1;
 
index de77e508af55d17db7a1bae4de7468fb7c82e2ca..dab4e173309c85db2f0a9ebebcea9aa230920585 100644 (file)
 
 int TSUNAMI_bootcpu;
 
+static struct 
+{
+       unsigned long wsba[4];
+       unsigned long wsm[4];
+       unsigned long tba[4];
+} saved_pchip[2];
+
 /*
  * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
  * One plausible explanation is that the I/O controller does not properly
@@ -84,7 +91,7 @@ static int
 mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
             unsigned char *type1)
 {
-       struct pci_controler *hose = dev->sysdata ? : probing_hose;
+       struct pci_controler *hose = dev->sysdata;
        unsigned long addr;
        u8 bus = dev->bus->number;
        u8 device_fn = dev->devfn;
@@ -264,7 +271,7 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
        hose->index = index;
 
        hose->io_space->start = TSUNAMI_IO(index) - TSUNAMI_IO_BIAS;
-       hose->io_space->end = hose->io_space->start + 0xffff;
+       hose->io_space->end = hose->io_space->start + TSUNAMI_IO_SPACE - 1;
        hose->io_space->name = pci_io_names[index];
        hose->io_space->flags = IORESOURCE_IO;
 
@@ -278,6 +285,27 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
        if (request_resource(&iomem_resource, hose->mem_space) < 0)
                printk(KERN_ERR "Failed to request MEM on hose %d\n", index);
 
+       /*
+        * Save the existing PCI window translations.  SRM will 
+        * need them when we go to reboot.
+        */
+
+       saved_pchip[index].wsba[0] = pchip->wsba[0].csr;
+       saved_pchip[index].wsm[0] = pchip->wsm[0].csr;
+       saved_pchip[index].tba[0] = pchip->tba[0].csr;
+
+       saved_pchip[index].wsba[1] = pchip->wsba[1].csr;
+       saved_pchip[index].wsm[1] = pchip->wsm[1].csr;
+       saved_pchip[index].tba[1] = pchip->tba[1].csr;
+
+       saved_pchip[index].wsba[2] = pchip->wsba[2].csr;
+       saved_pchip[index].wsm[2] = pchip->wsm[2].csr;
+       saved_pchip[index].tba[2] = pchip->tba[2].csr;
+
+       saved_pchip[index].wsba[3] = pchip->wsba[3].csr;
+       saved_pchip[index].wsm[3] = pchip->wsm[3].csr;
+       saved_pchip[index].tba[3] = pchip->tba[3].csr;
+
        /*
         * Set up the PCI->physical memory translation windows.
         * For now, windows 1,2 and 3 are disabled.  In the future,
@@ -352,6 +380,34 @@ tsunami_init_arch(void)
                tsunami_init_one_pchip(TSUNAMI_pchip1, 1);
 }
 
+static void
+tsunami_kill_one_pchip(tsunami_pchip *pchip, int index)
+{
+       pchip->wsba[0].csr = saved_pchip[index].wsba[0];
+       pchip->wsm[0].csr = saved_pchip[index].wsm[0];
+       pchip->tba[0].csr = saved_pchip[index].tba[0];
+
+       pchip->wsba[1].csr = saved_pchip[index].wsba[1];
+       pchip->wsm[1].csr = saved_pchip[index].wsm[1];
+       pchip->tba[1].csr = saved_pchip[index].tba[1];
+
+       pchip->wsba[2].csr = saved_pchip[index].wsba[2];
+       pchip->wsm[2].csr = saved_pchip[index].wsm[2];
+       pchip->tba[2].csr = saved_pchip[index].tba[2];
+
+       pchip->wsba[3].csr = saved_pchip[index].wsba[3];
+       pchip->wsm[3].csr = saved_pchip[index].wsm[3];
+       pchip->tba[3].csr = saved_pchip[index].tba[3];
+}
+
+void
+tsunami_kill_arch(int mode)
+{
+       tsunami_kill_one_pchip(TSUNAMI_pchip0, 0);
+       if (TSUNAMI_cchip->csc.csr & 1L<<14)
+               tsunami_kill_one_pchip(TSUNAMI_pchip1, 1);
+}
+
 static inline void
 tsunami_pci_clr_err_1(tsunami_pchip *pchip)
 {
diff --git a/arch/alpha/kernel/fpreg.c b/arch/alpha/kernel/fpreg.c
deleted file mode 100644 (file)
index 0bd8b9f..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * arch/alpha/kernel/fpreg.c
- *
- * (C) Copyright 1998 Linus Torvalds
- */
-
-#if defined(__alpha_cix__) || defined(__alpha_fix__)
-#define STT(reg,val)  asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
-#else
-#define STT(reg,val)  asm volatile ("stt $f"#reg",%0" : "=m"(val));
-#endif
-
-unsigned long
-alpha_read_fp_reg (unsigned long reg)
-{
-       unsigned long val;
-
-       switch (reg) {
-             case  0: STT( 0, val); break;
-             case  1: STT( 1, val); break;
-             case  2: STT( 2, val); break;
-             case  3: STT( 3, val); break;
-             case  4: STT( 4, val); break;
-             case  5: STT( 5, val); break;
-             case  6: STT( 6, val); break;
-             case  7: STT( 7, val); break;
-             case  8: STT( 8, val); break;
-             case  9: STT( 9, val); break;
-             case 10: STT(10, val); break;
-             case 11: STT(11, val); break;
-             case 12: STT(12, val); break;
-             case 13: STT(13, val); break;
-             case 14: STT(14, val); break;
-             case 15: STT(15, val); break;
-             case 16: STT(16, val); break;
-             case 17: STT(17, val); break;
-             case 18: STT(18, val); break;
-             case 19: STT(19, val); break;
-             case 20: STT(20, val); break;
-             case 21: STT(21, val); break;
-             case 22: STT(22, val); break;
-             case 23: STT(23, val); break;
-             case 24: STT(24, val); break;
-             case 25: STT(25, val); break;
-             case 26: STT(26, val); break;
-             case 27: STT(27, val); break;
-             case 28: STT(28, val); break;
-             case 29: STT(29, val); break;
-             case 30: STT(30, val); break;
-             case 31: STT(31, val); break;
-       }
-       return val;
-}
-
-#if defined(__alpha_cix__) || defined(__alpha_fix__)
-#define LDT(reg,val)  asm volatile ("itoft %0,$f"#reg : : "r"(val));
-#else
-#define LDT(reg,val)  asm volatile ("ldt $f"#reg",%0" : : "m"(val));
-#endif
-
-void
-alpha_write_fp_reg (unsigned long reg, unsigned long val)
-{
-       switch (reg) {
-             case  0: LDT( 0, val); break;
-             case  1: LDT( 1, val); break;
-             case  2: LDT( 2, val); break;
-             case  3: LDT( 3, val); break;
-             case  4: LDT( 4, val); break;
-             case  5: LDT( 5, val); break;
-             case  6: LDT( 6, val); break;
-             case  7: LDT( 7, val); break;
-             case  8: LDT( 8, val); break;
-             case  9: LDT( 9, val); break;
-             case 10: LDT(10, val); break;
-             case 11: LDT(11, val); break;
-             case 12: LDT(12, val); break;
-             case 13: LDT(13, val); break;
-             case 14: LDT(14, val); break;
-             case 15: LDT(15, val); break;
-             case 16: LDT(16, val); break;
-             case 17: LDT(17, val); break;
-             case 18: LDT(18, val); break;
-             case 19: LDT(19, val); break;
-             case 20: LDT(20, val); break;
-             case 21: LDT(21, val); break;
-             case 22: LDT(22, val); break;
-             case 23: LDT(23, val); break;
-             case 24: LDT(24, val); break;
-             case 25: LDT(25, val); break;
-             case 26: LDT(26, val); break;
-             case 27: LDT(27, val); break;
-             case 28: LDT(28, val); break;
-             case 29: LDT(29, val); break;
-             case 30: LDT(30, val); break;
-             case 31: LDT(31, val); break;
-       }
-}
index 6cf40835e77e9032165fd784239e8e40904683cd..86c58359da550d1762eec5fc5bf74ed007eb722e 100644 (file)
@@ -392,8 +392,6 @@ static void *previous_irqholder = NULL;
 
 static void show(char * str, void *where);
 
-#define SYNC_OTHER_CPUS(x)     udelay((x)+1);
-
 static inline void
 wait_on_irq(int cpu, void *where)
 {
@@ -414,7 +412,6 @@ wait_on_irq(int cpu, void *where)
 
                /* Duh, we have to loop. Release the lock to avoid deadlocks */
                spin_unlock(&global_irq_lock);
-               mb();
 
                for (;;) {
                        if (!--count) {
@@ -422,7 +419,7 @@ wait_on_irq(int cpu, void *where)
                                count = MAXCOUNT;
                        }
                        __sti();
-                       SYNC_OTHER_CPUS(cpu);
+                       udelay(1); /* make sure to run pending irqs */
                        __cli();
 
                        if (atomic_read(&global_irq_count))
index 313631b10e02441ae01e6ad177da45ebeb95fe80..4fb054e3825c088b0a05e3c9aedca71694b1d6e3 100644 (file)
@@ -40,7 +40,6 @@ const char pci_hae0_name[] = "HAE0";
  */
 
 struct pci_controler *hose_head, **hose_tail = &hose_head;
-struct pci_controler *probing_hose;
 
 /*
  * Quirks.
@@ -213,13 +212,12 @@ pcibios_fixup_bus(struct pci_bus *bus)
 {
        /* Propogate hose info into the subordinate devices.  */
 
-       struct pci_controler *hose = probing_hose;
+       struct pci_controler *hose = (struct pci_controler *) bus->sysdata;
        struct pci_dev *dev;
 
        bus->resource[0] = hose->io_space;
        bus->resource[1] = hose->mem_space;
        for (dev = bus->devices; dev; dev = dev->sibling) {
-               dev->sysdata = hose;
                if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
                        pcibios_fixup_device_resources(dev, bus);
        }
@@ -297,13 +295,11 @@ common_init_pci(void)
        for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
                hose->first_busno = next_busno;
                hose->last_busno = 0xff;
-               probing_hose = hose;
                bus = pci_scan_bus(next_busno, alpha_mv.pci_ops, hose);
                hose->bus = bus;
                next_busno = hose->last_busno = bus->subordinate;
                next_busno += 1;
        }
-       probing_hose = NULL;
 
        pci_assign_unassigned_resources(alpha_mv.min_io_address,
                                        alpha_mv.min_mem_address);
index a0c1587d5d70e26feb0f1f15ca1f8355f5a92ced..b46fb998023bc7b3cba3573568ca642593fbae58 100644 (file)
@@ -125,7 +125,6 @@ static inline u8 bridge_swizzle(u8 pin, u8 slot)
 
 /* The hose list.  */
 extern struct pci_controler *hose_head, **hose_tail;
-extern struct pci_controler *probing_hose;
 
 extern void common_init_pci(void);
 extern u8 common_swizzle(struct pci_dev *, u8 *);
index 7b3a7beaf63001a05c28fdeda75e952cd49e2529..e80282155d5df8b54a75a410ec2c872dac36051a 100644 (file)
@@ -94,8 +94,8 @@ cpu_idle(void)
        }
 }
 
-void
-common_kill_arch (int mode, char *restart_cmd)
+static void
+common_shutdown(int mode, char *restart_cmd)
 {
        /* The following currently only has any effect on SRM.  We should
           fix MILO to understand it.  Should be pretty easy.  Also we can
@@ -144,6 +144,9 @@ common_kill_arch (int mode, char *restart_cmd)
        rtc_kill_pit();
 #endif
 
+       if (alpha_mv.kill_arch)
+               alpha_mv.kill_arch(mode);
+
        if (!alpha_using_srm && mode != LINUX_REBOOT_CMD_RESTART) {
                /* Unfortunately, since MILO doesn't currently understand
                   the hwrpb bits above, we can't reliably halt the 
@@ -160,21 +163,23 @@ common_kill_arch (int mode, char *restart_cmd)
 void
 machine_restart(char *restart_cmd)
 {
-       alpha_mv.kill_arch(LINUX_REBOOT_CMD_RESTART, restart_cmd);
+       common_shutdown(LINUX_REBOOT_CMD_RESTART, restart_cmd);
 }
 
 void
 machine_halt(void)
 {
-       alpha_mv.kill_arch(LINUX_REBOOT_CMD_HALT, NULL);
+       common_shutdown(LINUX_REBOOT_CMD_HALT, NULL);
 }
 
-void machine_power_off(void)
+void
+machine_power_off(void)
 {
-       alpha_mv.kill_arch(LINUX_REBOOT_CMD_POWER_OFF, NULL);
+       common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL);
 }
 
-void show_regs(struct pt_regs * regs)
+void
+show_regs(struct pt_regs * regs)
 {
        printk("\nps: %04lx pc: [<%016lx>]\n", regs->ps, regs->pc);
        printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1);
@@ -195,7 +200,8 @@ void show_regs(struct pt_regs * regs)
 /*
  * Re-start a thread when doing execve()
  */
-void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
+void
+start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
 {
        set_fs(USER_DS);
        regs->pc = pc;
@@ -206,11 +212,13 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
 /*
  * Free current thread data structures etc..
  */
-void exit_thread(void)
+void
+exit_thread(void)
 {
 }
 
-void flush_thread(void)
+void
+flush_thread(void)
 {
        /* Arrange for each exec'ed process to start off with a clean slate
           with respect to the FPU.  This is all exceptions disabled.  Note
@@ -221,7 +229,8 @@ void flush_thread(void)
        wrfpcr(FPCR_DYN_NORMAL | FPCR_INVD | FPCR_DZED | FPCR_OVFD | FPCR_INED);
 }
 
-void release_thread(struct task_struct *dead_task)
+void
+release_thread(struct task_struct *dead_task)
 {
 }
 
@@ -234,15 +243,17 @@ void release_thread(struct task_struct *dead_task)
  * Notice that "fork()" is implemented in terms of clone,
  * with parameters (SIGCHLD, 0).
  */
-int alpha_clone(unsigned long clone_flags, unsigned long usp,
-               struct switch_stack * swstack)
+int
+alpha_clone(unsigned long clone_flags, unsigned long usp,
+           struct switch_stack * swstack)
 {
        if (!usp)
                usp = rdusp();
        return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1));
 }
 
-int alpha_vfork(struct switch_stack * swstack)
+int
+alpha_vfork(struct switch_stack * swstack)
 {
        return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
                        (struct pt_regs *) (swstack+1));
@@ -259,8 +270,9 @@ int alpha_vfork(struct switch_stack * swstack)
  * for a kernel fork().
  */
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
-       struct task_struct * p, struct pt_regs * regs)
+int
+copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+           struct task_struct * p, struct pt_regs * regs)
 {
        extern void ret_from_sys_call(void);
        extern void ret_from_smp_fork(void);
@@ -298,7 +310,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
 /*
  * fill in the user structure for a core dump..
  */
-void dump_thread(struct pt_regs * pt, struct user * dump)
+void
+dump_thread(struct pt_regs * pt, struct user * dump)
 {
        /* switch stack follows right below pt_regs: */
        struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
@@ -355,7 +368,8 @@ void dump_thread(struct pt_regs * pt, struct user * dump)
        memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
 }
 
-int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
+int
+dump_fpu(struct pt_regs * regs, elf_fpregset_t *r)
 {
        /* switch stack follows right below pt_regs: */
        struct switch_stack * sw = ((struct switch_stack *) regs) - 1;
@@ -373,7 +387,8 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
  *
  * Don't do this at home.
  */
-asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+asmlinkage int
+sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
        unsigned long a3, unsigned long a4, unsigned long a5,
        struct pt_regs regs)
 {
@@ -400,7 +415,8 @@ extern void scheduling_functions_end_here(void);
 #define first_sched    ((unsigned long) scheduling_functions_start_here)
 #define last_sched     ((unsigned long) scheduling_functions_end_here)
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long
+get_wchan(struct task_struct *p)
 {
        unsigned long schedule_frame;
        unsigned long pc;
index f7579f79e96dc8b455235df55d6d5b8dffb8b10a..3efbdda08406d61e5cf8c89c1c0bac851a5e9053 100644 (file)
@@ -56,6 +56,7 @@ extern void t2_machine_check(u64, u64, struct pt_regs *);
 /* core_tsunami.c */
 extern struct pci_ops tsunami_pci_ops;
 extern void tsunami_init_arch(void);
+extern void tsunami_kill_arch(int);
 extern void tsunami_machine_check(u64, u64, struct pt_regs *);
 
 /* setup.c */
@@ -110,7 +111,6 @@ extern void entUna(void);
 extern void entDbg(void);
 
 /* process.c */
-extern void common_kill_arch (int mode, char *reboot_cmd);
 extern void cpu_idle(void) __attribute__((noreturn));
 
 /* ptrace.c */
index aede98e87479cd892482f6dbb6077458d509f47c..3a1fb94a358c80b9ba536becad1d3ad56eaac859 100644 (file)
@@ -327,6 +327,28 @@ setup_memory(void)
        }
 #endif /* CONFIG_BLK_DEV_INITRD */
 }
+
+int __init page_is_ram(unsigned long pfn)
+{
+       struct memclust_struct * cluster;
+       struct memdesc_struct * memdesc;
+       int i;
+
+       memdesc = (struct memdesc_struct *) (hwrpb->mddt_offset + (unsigned long) hwrpb);
+       for_each_mem_cluster(memdesc, cluster, i)
+       {
+               if (pfn >= cluster->start_pfn  &&
+                   pfn < cluster->start_pfn + cluster->numpages)
+               {
+                       if (cluster->usage & 3)
+                               return 0;
+                       else
+                               return 1;
+               }
+       }
+
+       return 0;
+}
 #undef PFN_UP
 #undef PFN_DOWN
 #undef PFN_PHYS
index 30c9915d628b01564e26d063b6a4ba896d6255b0..a1beba5be236d74256771c3938f9e3d98bafc400 100644 (file)
@@ -396,6 +396,16 @@ started:
        return 0;
 }
 
+static int __init fork_by_hand(void)
+{
+       struct pt_regs regs;
+       /*
+        * don't care about the regs settings since
+        * we'll never reschedule the forked task.
+        */
+       return do_fork(CLONE_VM|CLONE_PID, 0, &regs);
+}
+
 /*
  * Bring one cpu online.
  */
@@ -409,18 +419,25 @@ smp_boot_one_cpu(int cpuid, int cpunum)
           to kernel_thread is irrelevant -- it's going to start where
           HWRPB.CPU_restart says to start.  But this gets all the other
           task-y sort of data structures set up like we wish.  */
-       kernel_thread((void *)__smp_callin, NULL, CLONE_PID|CLONE_VM);
+       /*
+        * We can't use kernel_thread since we must avoid to
+        * reschedule the child.
+        */
+       if (fork_by_hand() < 0)
+               panic("failed fork for CPU %d", cpuid);
 
         idle = init_task.prev_task;
         if (!idle)
-                panic("No idle process for CPU %d", cpunum);
-        del_from_runqueue(idle);
-        init_tasks[cpunum] = idle;
-        idle->processor = cpuid;
+                panic("No idle process for CPU %d", cpuid);
 
-       /* Schedule the first task manually.  */
-       /* ??? Ingo, what is this?  */
-       idle->has_cpu = 1;
+       idle->processor = cpuid;
+       __cpu_logical_map[cpunum] = cpuid;
+       cpu_number_map[cpuid] = cpunum;
+       idle->has_cpu = 1; /* we schedule the first task manually */
+       del_from_runqueue(idle);
+       unhash_process(idle);
+       init_tasks[cpunum] = idle;
 
        DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n",
              cpuid, idle->state, idle->flags));
@@ -442,13 +459,18 @@ smp_boot_one_cpu(int cpuid, int cpunum)
                barrier();
        }
 
+       /* we must invalidate our stuff as we failed to boot the CPU */
+       __cpu_logical_map[cpunum] = -1;
+       cpu_number_map[cpuid] = -1;
+
+       /* the idle task is local to us so free it as we don't use it */
+       free_task_struct(idle);
+
        printk(KERN_ERR "SMP: Processor %d is stuck.\n", cpuid);
        return -1;
 
 alive:
        /* Another "Red Snapper". */
-       cpu_number_map[cpuid] = cpunum;
-       __cpu_logical_map[cpunum] = cpuid;
        return 0;
 }
 
@@ -581,16 +603,6 @@ smp_commence(void)
        mb();
 }
 
-/*
- * Only broken Intel needs this, thus it should not even be
- * referenced globally.
- */
-
-void __init
-initialize_secondary(void)
-{
-}
-
 \f
 extern void update_one_process(struct task_struct *p, unsigned long ticks,
                               unsigned long user, unsigned long system,
index fbc1b99babe493ab558d58e041b9de48b259d221..684e9edec71d870da4114e9c134ce30d7131d28d 100644 (file)
@@ -176,15 +176,13 @@ alcor_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 }
 
 static void
-alcor_kill_arch(int mode, char *reboot_cmd)
+alcor_kill_arch(int mode)
 {
        /* Who said DEC engineer's have no sense of humor? ;-)  */
        if (alpha_using_srm) {
                *(vuip) GRU_RESET = 0x0000dead;
                mb();
        }
-
-       common_kill_arch(mode, reboot_cmd);
 }
 
 
index 244759d1f2ac52413df376455525c37892e7b46c..d79913e8220ce83ca6bd1de7a12e5d8bc571321c 100644 (file)
@@ -269,7 +269,7 @@ struct alpha_machine_vector cabriolet_mv __initmv = {
        init_irq:               cabriolet_init_irq,
        init_pit:               common_init_pit,
        init_pci:               cabriolet_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
        pci_map_irq:            cabriolet_map_irq,
        pci_swizzle:            common_swizzle,
 };
index 86ff4bd2b00d50982284fdeb32b7ff98b73c634e..26e97a8ae3a772f7b4e476f5759d71b7f2aca3d6 100644 (file)
@@ -427,7 +427,7 @@ struct alpha_machine_vector dp264_mv __initmv = {
        init_irq:               dp264_init_irq,
        init_pit:               common_init_pit,
        init_pci:               dp264_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              tsunami_kill_arch,
        pci_map_irq:            dp264_map_irq,
        pci_swizzle:            common_swizzle,
 };
@@ -454,7 +454,7 @@ struct alpha_machine_vector monet_mv __initmv = {
        init_irq:               dp264_init_irq,
        init_pit:               common_init_pit,
        init_pci:               monet_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              tsunami_kill_arch,
        pci_map_irq:            monet_map_irq,
        pci_swizzle:            monet_swizzle,
 };
@@ -480,7 +480,7 @@ struct alpha_machine_vector webbrick_mv __initmv = {
        init_irq:               dp264_init_irq,
        init_pit:               common_init_pit,
        init_pci:               common_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              tsunami_kill_arch,
        pci_map_irq:            webbrick_map_irq,
        pci_swizzle:            common_swizzle,
 };
@@ -506,7 +506,7 @@ struct alpha_machine_vector clipper_mv __initmv = {
        init_irq:               clipper_init_irq,
        init_pit:               common_init_pit,
        init_pci:               common_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              tsunami_kill_arch,
        pci_map_irq:            clipper_map_irq,
        pci_swizzle:            common_swizzle,
 };
index 09e0b0def8314b0d633ba58f56f843a8f9839628..4f15ec4f153e7f7fe06aa301f58f9448b89ea591 100644 (file)
@@ -183,7 +183,7 @@ struct alpha_machine_vector eb64p_mv __initmv = {
        init_irq:               eb64p_init_irq,
        init_pit:               common_init_pit,
        init_pci:               common_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
        pci_map_irq:            eb64p_map_irq,
        pci_swizzle:            common_swizzle,
 };
index b6d6d0de46da3461f19f3f4c09b3d0fc70e1c774..07dbed7302eb537bbd1df629650f9931728ad711 100644 (file)
@@ -208,7 +208,7 @@ struct alpha_machine_vector eiger_mv __initmv = {
        init_irq:               eiger_init_irq,
        init_pit:               common_init_pit,
        init_pci:               common_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              tsunami_kill_arch,
        pci_map_irq:            eiger_map_irq,
        pci_swizzle:            eiger_swizzle,
 };
index 0380574a8e7a4a3ecc9e92aecdcfa7fb241d8981..9923213318919384373c9530ea1c03069c7e4a9a 100644 (file)
@@ -140,6 +140,6 @@ struct alpha_machine_vector jensen_mv __initmv = {
        init_irq:               jensen_init_irq,
        init_pit:               common_init_pit,
        init_pci:               NULL,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
 };
 ALIAS_MV(jensen)
index 0bea4e3dd579676c005b4f21e843a8c314f935a7..4e5dd14b936335d1f95cb055c9fc4f7e745d532b 100644 (file)
@@ -274,14 +274,13 @@ miata_init_pci(void)
 }
 
 static void
-miata_kill_arch (int mode, char *reboot_cmd)
+miata_kill_arch(int mode)
 {
        /* Who said DEC engineers have no sense of humor? ;-)  */
        if (alpha_using_srm) {
                *(vuip) PYXIS_RESET = 0x0000dead;
                mb();
        }
-       common_kill_arch(mode, reboot_cmd);
 }
 
 
index 0c08d9fc0b8590f5a377385b982e0e13df54d1c6..c93bcec4510d3f14bb2ec9722ee1572d04de4135 100644 (file)
@@ -194,7 +194,7 @@ struct alpha_machine_vector mikasa_mv __initmv = {
        init_irq:               mikasa_init_irq,
        init_pit:               common_init_pit,
        init_pci:               common_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
        pci_map_irq:            mikasa_map_irq,
        pci_swizzle:            common_swizzle,
 };
index 710b23585936dd29ccd3812a5482c3f6c6387635..92d2ec681ccc46b23460fc23541e8dd63e10f569 100644 (file)
@@ -87,29 +87,16 @@ nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 }
 
 void
-nautilus_kill_arch (int mode, char *restart_cmd)
+nautilus_kill_arch(int mode)
 {
        u8 tmp;
 
-#ifdef CONFIG_RTC
-       rtc_kill_pit();
-#endif
-
-       switch(mode) {
-        case LINUX_REBOOT_CMD_HALT:
-               printk("Press Reset bottun");
-               break;
-       case LINUX_REBOOT_CMD_RESTART:
+       if (mode == LINUX_REBOOT_CMD_RESTART) {
                pcibios_read_config_byte(0, 0x38, 0x43, &tmp);
                pcibios_write_config_byte(0, 0x38, 0x43, tmp | 0x80);
                outb(1, 0x92);
                outb(0, 0x92);
-               printk("Press Reset button");
-               break;
-        case LINUX_REBOOT_CMD_POWER_OFF:
        }
-
-       while (1);
 }
 
 /* Machine check handler code
index adce91de2c0d145aa559d974a55af0d9cc19b861..5a97b5e2c226beabb1c8195aa19875177471bf8b 100644 (file)
@@ -254,7 +254,7 @@ struct alpha_machine_vector noritake_mv __initmv = {
        init_irq:               noritake_init_irq,
        init_pit:               common_init_pit,
        init_pci:               common_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
        pci_map_irq:            noritake_map_irq,
        pci_swizzle:            noritake_swizzle,
 };
index 8d3f229ec89d3a48949224f69a5fc30df98f57cb..89bac964485740c02050e7fc28c01eaa02ed99fd 100644 (file)
@@ -200,7 +200,7 @@ struct alpha_machine_vector rawhide_mv __initmv = {
        init_irq:               rawhide_init_irq,
        init_pit:               common_init_pit,
        init_pci:               common_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
        pci_map_irq:            rawhide_map_irq,
        pci_swizzle:            common_swizzle,
 };
index f303a825526e5265f49c48085ac0c8ebb3361775..7d4aeedd4ab390011ab38b4add8e5e1d3d2cdc91 100644 (file)
@@ -212,15 +212,14 @@ ruffian_init_pit (void)
 }
 
 static void
-ruffian_kill_arch (int mode, char *reboot_cmd)
+ruffian_kill_arch (int mode)
 {
 #if 0
-       /* this only causes re-entry to ARCSBIOS */
+       /* This only causes re-entry to ARCSBIOS */
        /* Perhaps this works for other PYXIS as well?  */
        *(vuip) PYXIS_RESET = 0x0000dead;
        mb();
 #endif
-       common_kill_arch(mode, reboot_cmd);
 }
 
 static int __init
index c6a4ac5b3a655ece4c99b2aac0ffeab7bcda953a..0a13bb8f3f30a458a60783d1d1edb99d16d4679c 100644 (file)
@@ -229,7 +229,7 @@ struct alpha_machine_vector rx164_mv __initmv = {
        init_irq:               rx164_init_irq,
        init_pit:               common_init_pit,
        init_pci:               common_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
        pci_map_irq:            rx164_map_irq,
        pci_swizzle:            common_swizzle,
 };
index 86b1d83718e17cb4408cc631aae52f503172ea6a..327167d47ad5b2062491f51de1f7d4ffe597c514 100644 (file)
@@ -248,7 +248,7 @@ struct alpha_machine_vector sable_mv __initmv = {
        init_irq:               sable_init_irq,
        init_pit:               common_init_pit,
        init_pci:               common_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
        pci_map_irq:            sable_map_irq,
        pci_swizzle:            common_swizzle,
 
index 14fa44e349e45c6aad06bc6a469e7c548ef52fd2..ade418eaf57871a2a7e3100723c0dc5417df9c2a 100644 (file)
@@ -325,7 +325,7 @@ struct alpha_machine_vector alphabook1_mv __initmv = {
        init_irq:               sio_init_irq,
        init_pit:               common_init_pit,
        init_pci:               alphabook1_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
        pci_map_irq:            noname_map_irq,
        pci_swizzle:            common_swizzle,
 
index a8c7698fb602c5e29906432bb1bbfaf8994ce2ff..63a09544a30bd7cacd637170b062f8ad710799b7 100644 (file)
@@ -211,7 +211,7 @@ struct alpha_machine_vector sx164_mv __initmv = {
        init_irq:               sx164_init_irq,
        init_pit:               common_init_pit,
        init_pci:               sx164_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
        pci_map_irq:            sx164_map_irq,
        pci_swizzle:            common_swizzle,
 };
index 7b1864cfab4c95597d84fe7c0d3de000dcdad0b7..4ca18d70d3eb9a7331d0b66ca9884edd1ae2c856 100644 (file)
@@ -244,7 +244,7 @@ struct alpha_machine_vector takara_mv __initmv = {
        init_irq:               takara_init_irq,
        init_pit:               common_init_pit,
        init_pci:               takara_init_pci,
-       kill_arch:              common_kill_arch,
+       kill_arch:              NULL,
        pci_map_irq:            takara_map_irq,
        pci_swizzle:            takara_swizzle,
 };
index 59f021a77591845cb262b00a5b906a2d112e2457..36b0cc43a07b2483c34fbc4f94e252d225ed3394 100644 (file)
@@ -113,7 +113,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
 }
 
 #ifndef CONFIG_MATHEMU
-static long dummy_emul() { return 0; }
+static long dummy_emul(void) { return 0; }
 long (*alpha_fp_emul_imprecise)(struct pt_regs *regs, unsigned long writemask)
   = (void *)dummy_emul;
 long (*alpha_fp_emul) (unsigned long pc)
index f550ba7cb0ea053274ee1a1410e4222074a03f9d..a224f84bb040b28602ce46fd99ee325a321be17b 100644 (file)
@@ -7,7 +7,7 @@ OBJS  = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
        strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \
        strchr.o strrchr.o memchr.o \
        copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \
-       csum_ipv6_magic.o strcasecmp.o semaphore.o \
+       csum_ipv6_magic.o strcasecmp.o semaphore.o fpreg.o \
        srm_dispatch.o srm_fixup.o srm_puts.o srm_printk.o
 
 lib.a: $(OBJS)
diff --git a/arch/alpha/lib/fpreg.c b/arch/alpha/lib/fpreg.c
new file mode 100644 (file)
index 0000000..c09d257
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * arch/alpha/lib/fpreg.c
+ *
+ * (C) Copyright 1998 Linus Torvalds
+ */
+
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#define STT(reg,val)  asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
+#else
+#define STT(reg,val)  asm volatile ("stt $f"#reg",%0" : "=m"(val));
+#endif
+
+unsigned long
+alpha_read_fp_reg (unsigned long reg)
+{
+       unsigned long val;
+
+       switch (reg) {
+             case  0: STT( 0, val); break;
+             case  1: STT( 1, val); break;
+             case  2: STT( 2, val); break;
+             case  3: STT( 3, val); break;
+             case  4: STT( 4, val); break;
+             case  5: STT( 5, val); break;
+             case  6: STT( 6, val); break;
+             case  7: STT( 7, val); break;
+             case  8: STT( 8, val); break;
+             case  9: STT( 9, val); break;
+             case 10: STT(10, val); break;
+             case 11: STT(11, val); break;
+             case 12: STT(12, val); break;
+             case 13: STT(13, val); break;
+             case 14: STT(14, val); break;
+             case 15: STT(15, val); break;
+             case 16: STT(16, val); break;
+             case 17: STT(17, val); break;
+             case 18: STT(18, val); break;
+             case 19: STT(19, val); break;
+             case 20: STT(20, val); break;
+             case 21: STT(21, val); break;
+             case 22: STT(22, val); break;
+             case 23: STT(23, val); break;
+             case 24: STT(24, val); break;
+             case 25: STT(25, val); break;
+             case 26: STT(26, val); break;
+             case 27: STT(27, val); break;
+             case 28: STT(28, val); break;
+             case 29: STT(29, val); break;
+             case 30: STT(30, val); break;
+             case 31: STT(31, val); break;
+       }
+       return val;
+}
+
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#define LDT(reg,val)  asm volatile ("itoft %0,$f"#reg : : "r"(val));
+#else
+#define LDT(reg,val)  asm volatile ("ldt $f"#reg",%0" : : "m"(val));
+#endif
+
+void
+alpha_write_fp_reg (unsigned long reg, unsigned long val)
+{
+       switch (reg) {
+             case  0: LDT( 0, val); break;
+             case  1: LDT( 1, val); break;
+             case  2: LDT( 2, val); break;
+             case  3: LDT( 3, val); break;
+             case  4: LDT( 4, val); break;
+             case  5: LDT( 5, val); break;
+             case  6: LDT( 6, val); break;
+             case  7: LDT( 7, val); break;
+             case  8: LDT( 8, val); break;
+             case  9: LDT( 9, val); break;
+             case 10: LDT(10, val); break;
+             case 11: LDT(11, val); break;
+             case 12: LDT(12, val); break;
+             case 13: LDT(13, val); break;
+             case 14: LDT(14, val); break;
+             case 15: LDT(15, val); break;
+             case 16: LDT(16, val); break;
+             case 17: LDT(17, val); break;
+             case 18: LDT(18, val); break;
+             case 19: LDT(19, val); break;
+             case 20: LDT(20, val); break;
+             case 21: LDT(21, val); break;
+             case 22: LDT(22, val); break;
+             case 23: LDT(23, val); break;
+             case 24: LDT(24, val); break;
+             case 25: LDT(25, val); break;
+             case 26: LDT(26, val); break;
+             case 27: LDT(27, val); break;
+             case 28: LDT(28, val); break;
+             case 29: LDT(29, val); break;
+             case 30: LDT(30, val); break;
+             case 31: LDT(31, val); break;
+       }
+}
+
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#define STS(reg,val)  asm volatile ("ftois $f"#reg",%0" : "=r"(val));
+#else
+#define STS(reg,val)  asm volatile ("sts $f"#reg",%0" : "=m"(val));
+#endif
+
+unsigned long
+alpha_read_fp_reg_s (unsigned long reg)
+{
+       unsigned long val;
+
+       switch (reg) {
+             case  0: STS( 0, val); break;
+             case  1: STS( 1, val); break;
+             case  2: STS( 2, val); break;
+             case  3: STS( 3, val); break;
+             case  4: STS( 4, val); break;
+             case  5: STS( 5, val); break;
+             case  6: STS( 6, val); break;
+             case  7: STS( 7, val); break;
+             case  8: STS( 8, val); break;
+             case  9: STS( 9, val); break;
+             case 10: STS(10, val); break;
+             case 11: STS(11, val); break;
+             case 12: STS(12, val); break;
+             case 13: STS(13, val); break;
+             case 14: STS(14, val); break;
+             case 15: STS(15, val); break;
+             case 16: STS(16, val); break;
+             case 17: STS(17, val); break;
+             case 18: STS(18, val); break;
+             case 19: STS(19, val); break;
+             case 20: STS(20, val); break;
+             case 21: STS(21, val); break;
+             case 22: STS(22, val); break;
+             case 23: STS(23, val); break;
+             case 24: STS(24, val); break;
+             case 25: STS(25, val); break;
+             case 26: STS(26, val); break;
+             case 27: STS(27, val); break;
+             case 28: STS(28, val); break;
+             case 29: STS(29, val); break;
+             case 30: STS(30, val); break;
+             case 31: STS(31, val); break;
+       }
+       return val;
+}
+
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#define LDS(reg,val)  asm volatile ("itofs %0,$f"#reg : : "r"(val));
+#else
+#define LDS(reg,val)  asm volatile ("lds $f"#reg",%0" : : "m"(val));
+#endif
+
+void
+alpha_write_fp_reg_s (unsigned long reg, unsigned long val)
+{
+       switch (reg) {
+             case  0: LDS( 0, val); break;
+             case  1: LDS( 1, val); break;
+             case  2: LDS( 2, val); break;
+             case  3: LDS( 3, val); break;
+             case  4: LDS( 4, val); break;
+             case  5: LDS( 5, val); break;
+             case  6: LDS( 6, val); break;
+             case  7: LDS( 7, val); break;
+             case  8: LDS( 8, val); break;
+             case  9: LDS( 9, val); break;
+             case 10: LDS(10, val); break;
+             case 11: LDS(11, val); break;
+             case 12: LDS(12, val); break;
+             case 13: LDS(13, val); break;
+             case 14: LDS(14, val); break;
+             case 15: LDS(15, val); break;
+             case 16: LDS(16, val); break;
+             case 17: LDS(17, val); break;
+             case 18: LDS(18, val); break;
+             case 19: LDS(19, val); break;
+             case 20: LDS(20, val); break;
+             case 21: LDS(21, val); break;
+             case 22: LDS(22, val); break;
+             case 23: LDS(23, val); break;
+             case 24: LDS(24, val); break;
+             case 25: LDS(25, val); break;
+             case 26: LDS(26, val); break;
+             case 27: LDS(27, val); break;
+             case 28: LDS(28, val); break;
+             case 29: LDS(29, val); break;
+             case 30: LDS(30, val); break;
+             case 31: LDS(31, val); break;
+       }
+}
index 6ea85465ffdac763a330c270916cea7e6137a5ac..b5fc3776568a7a6f8e1e8aade709a537d5ffddb0 100644 (file)
@@ -1,9 +1,15 @@
 #
-# Makefile for math-emulator files...
+# Makefile for the FPU instruction emulation.
 #
+# 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...
 
 O_TARGET := math-emu.o
-O_OBJS   := fp-emul.o ieee-math.o
+O_OBJS   := math.o
+CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w
 
 ifeq ($(CONFIG_MATHEMU),m)
 M_OBJS   := $(O_TARGET)
diff --git a/arch/alpha/math-emu/fp-emul.c b/arch/alpha/math-emu/fp-emul.c
deleted file mode 100644 (file)
index c2ebbbb..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/uaccess.h>
-
-#include "ieee-math.h"
-
-#define        OPC_PAL         0x00
-
-#define OPC_INTA       0x10
-#define OPC_INTL       0x11
-#define OPC_INTS       0x12
-#define OPC_INTM       0x13
-#define OPC_FLTC       0x14
-#define OPC_FLTV       0x15
-#define OPC_FLTI       0x16
-#define OPC_FLTL       0x17
-
-#define OPC_MISC       0x18
-
-#define        OPC_JSR         0x1a
-
-#define OP_FUN(OP,FUN) ((OP << 26) | (FUN << 5))
-
-/*
- * "Base" function codes for the FLTI-class instructions.
- * Note that in most cases these actually correspond to the "chopped"
- * form of the instruction.  Not to worry---we extract the qualifier
- * bits separately and deal with them separately.  Notice that base
- * function code 0x2c is used for both CVTTS and CVTST.  The other bits
- * in the function code are used to distinguish the two.
- */
-#define FLTI_FUNC_ADDS                 OP_FUN(OPC_FLTI, 0x000)
-#define FLTI_FUNC_ADDT                 OP_FUN(OPC_FLTI, 0x020)
-#define FLTI_FUNC_CMPTEQ               OP_FUN(OPC_FLTI, 0x025)
-#define FLTI_FUNC_CMPTLT               OP_FUN(OPC_FLTI, 0x026)
-#define FLTI_FUNC_CMPTLE               OP_FUN(OPC_FLTI, 0x027)
-#define FLTI_FUNC_CMPTUN               OP_FUN(OPC_FLTI, 0x024)
-#define FLTI_FUNC_CVTTS_or_CVTST       OP_FUN(OPC_FLTI, 0x02c)
-#define FLTI_FUNC_CVTTQ                        OP_FUN(OPC_FLTI, 0x02f)
-#define FLTI_FUNC_CVTQS                        OP_FUN(OPC_FLTI, 0x03c)
-#define FLTI_FUNC_CVTQT                        OP_FUN(OPC_FLTI, 0x03e)
-#define FLTI_FUNC_DIVS                 OP_FUN(OPC_FLTI, 0x003)
-#define FLTI_FUNC_DIVT                 OP_FUN(OPC_FLTI, 0x023)
-#define FLTI_FUNC_MULS                 OP_FUN(OPC_FLTI, 0x002)
-#define FLTI_FUNC_MULT                 OP_FUN(OPC_FLTI, 0x022)
-#define FLTI_FUNC_SUBS                 OP_FUN(OPC_FLTI, 0x001)
-#define FLTI_FUNC_SUBT                 OP_FUN(OPC_FLTI, 0x021)
-
-#define FLTC_FUNC_SQRTS                        OP_FUN(OPC_FLTC, 0x00B)
-#define FLTC_FUNC_SQRTT                        OP_FUN(OPC_FLTC, 0x02B)
-
-#define FLTL_FUNC_CVTQL                        OP_FUN(OPC_FLTL, 0x030)
-
-#define MISC_TRAPB     0x0000
-#define MISC_EXCB      0x0400
-
-extern unsigned long alpha_read_fp_reg (unsigned long reg);
-extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
-
-
-#ifdef MODULE
-
-MODULE_DESCRIPTION("FP Software completion module");
-
-extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long);
-extern long (*alpha_fp_emul) (unsigned long pc);
-
-static long (*save_emul_imprecise)(struct pt_regs *, unsigned long);
-static long (*save_emul) (unsigned long pc);
-
-long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long);
-long do_alpha_fp_emul(unsigned long);
-
-int init_module(void)
-{
-       save_emul_imprecise = alpha_fp_emul_imprecise;
-       save_emul = alpha_fp_emul;
-       alpha_fp_emul_imprecise = do_alpha_fp_emul_imprecise;
-       alpha_fp_emul = do_alpha_fp_emul;
-       return 0;
-}
-
-void cleanup_module(void)
-{
-       alpha_fp_emul_imprecise = save_emul_imprecise;
-       alpha_fp_emul = save_emul;
-}
-
-#undef  alpha_fp_emul_imprecise
-#define alpha_fp_emul_imprecise                do_alpha_fp_emul_imprecise
-#undef  alpha_fp_emul
-#define alpha_fp_emul                  do_alpha_fp_emul
-
-#endif /* MODULE */
-
-/*
- * Emulate the floating point instruction at address PC.  Returns 0 if
- * emulation fails.  Notice that the kernel does not and cannot use FP
- * regs.  This is good because it means that instead of
- * saving/restoring all fp regs, we simply stick the result of the
- * operation into the appropriate register.
- */
-long
-alpha_fp_emul (unsigned long pc)
-{
-       unsigned long op_fun, fa, fb, fc, func, mode;
-       unsigned long fpcw = current->thread.flags;
-       unsigned long va, vb, vc, res, fpcr;
-       __u32 insn;
-
-       MOD_INC_USE_COUNT;
-
-       get_user(insn, (__u32*)pc);
-       fc     = (insn >>  0) &  0x1f;  /* destination register */
-       fb     = (insn >> 16) &  0x1f;
-       fa     = (insn >> 21) &  0x1f;
-       func   = (insn >>  5) & 0x7ff;
-       mode   = (insn >>  5) & 0xc0;
-       op_fun = insn & OP_FUN(0x3f, 0x3f);
-       
-       va = alpha_read_fp_reg(fa);
-       vb = alpha_read_fp_reg(fb);
-       fpcr = rdfpcr();
-
-       /*
-        * Try the operation in software.  First, obtain the rounding
-        * mode...
-        */
-       if (mode == 0xc0) {
-           /* dynamic---get rounding mode from fpcr: */
-           mode = ((fpcr & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT) << ROUND_SHIFT;
-       }
-       mode |= (fpcw & IEEE_TRAP_ENABLE_MASK);
-
-       if ((IEEE_TRAP_ENABLE_MASK & 0xc0)) {
-               extern int something_is_wrong (void);
-               something_is_wrong();
-       }
-
-       switch (op_fun) {
-             case FLTI_FUNC_CMPTEQ:
-               res = ieee_CMPTEQ(va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_CMPTLT:
-               res = ieee_CMPTLT(va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_CMPTLE:
-               res = ieee_CMPTLE(va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_CMPTUN:
-               res = ieee_CMPTUN(va, vb, &vc);
-               break;
-
-             case FLTL_FUNC_CVTQL:
-               /*
-                * Notice: We can get here only due to an integer
-                * overflow.  Such overflows are reported as invalid
-                * ops.  We return the result the hw would have
-                * computed.
-                */
-               vc = ((vb & 0xc0000000) << 32 | /* sign and msb */
-                     (vb & 0x3fffffff) << 29); /* rest of the integer */
-               res = FPCR_INV;
-               break;
-
-             case FLTI_FUNC_CVTQS:
-               res = ieee_CVTQS(mode, vb, &vc);
-               break;
-
-             case FLTI_FUNC_CVTQT:
-               res = ieee_CVTQT(mode, vb, &vc);
-               break;
-
-             case FLTI_FUNC_CVTTS_or_CVTST:
-               if (func == 0x6ac) {
-                       /*
-                        * 0x2ac is also CVTST, but if the /S
-                        * qualifier isn't set, we wouldn't be here in
-                        * the first place...
-                        */
-                       res = ieee_CVTST(mode, vb, &vc);
-               } else {
-                       res = ieee_CVTTS(mode, vb, &vc);
-               }
-               break; 
-
-             case FLTI_FUNC_DIVS:
-               res = ieee_DIVS(mode, va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_DIVT:
-               res = ieee_DIVT(mode, va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_MULS:
-               res = ieee_MULS(mode, va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_MULT:
-               res = ieee_MULT(mode, va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_SUBS:
-               res = ieee_SUBS(mode, va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_SUBT:
-               res = ieee_SUBT(mode, va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_ADDS:
-               res = ieee_ADDS(mode, va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_ADDT:
-               res = ieee_ADDT(mode, va, vb, &vc);
-               break;
-
-             case FLTI_FUNC_CVTTQ:
-               res = ieee_CVTTQ(mode, vb, &vc);
-               break;
-
-             case FLTC_FUNC_SQRTS:
-               res = ieee_SQRTS(mode, vb, &vc);
-               break;
-
-             case FLTC_FUNC_SQRTT:
-               res = ieee_SQRTT(mode, vb, &vc);
-               break;
-
-             default:
-               printk("alpha_fp_emul: unexpected function code %#lx at %#lx\n",
-                      func & 0x3f, pc);
-               MOD_DEC_USE_COUNT;
-               return 0;
-       }
-
-       /*
-        * Take the appropriate action for each possible
-        * floating-point result:
-        *
-        *      - Set the appropriate bits in the FPCR
-        *      - If the specified exception is enabled in the FPCR,
-        *        return.  The caller (entArith) will dispatch
-        *        the appropriate signal to the translated program.
-        *
-        * In addition, properly track the exception state in software
-        * as described in the Alpha Architectre Handbook section 4.7.7.3.
-        */
-       if (res) {
-               /* Record exceptions in software control word.  */
-               current->thread.flags = fpcw |= res >> 35;
-
-               /* Update hardware control register */
-               fpcr &= (~FPCR_MASK | FPCR_DYN_MASK);
-               fpcr |= ieee_swcr_to_fpcr(fpcw);
-               wrfpcr(fpcr);
-
-               /* Do we generate a signal?  */
-               if (res >> 51 & fpcw & IEEE_TRAP_ENABLE_MASK) {
-                       MOD_DEC_USE_COUNT;
-                       return 0;
-               }
-       }
-
-       /*
-        * Whoo-kay... we got this far, and we're not generating a signal
-        * to the translated program.  All that remains is to write the
-        * result:
-        */
-       alpha_write_fp_reg(fc, vc);
-
-       MOD_DEC_USE_COUNT;
-       return 1;
-}
-
-
-long
-alpha_fp_emul_imprecise (struct pt_regs *regs, unsigned long write_mask)
-{
-       unsigned long trigger_pc = regs->pc - 4;
-       unsigned long insn, opcode, rc;
-
-       MOD_INC_USE_COUNT;
-
-       /*
-        * Turn off the bits corresponding to registers that are the
-        * target of instructions that set bits in the exception
-        * summary register.  We have some slack doing this because a
-        * register that is the target of a trapping instruction can
-        * be written at most once in the trap shadow.
-        *
-        * Branches, jumps, TRAPBs, EXCBs and calls to PALcode all
-        * bound the trap shadow, so we need not look any further than
-        * up to the first occurrence of such an instruction.
-        */
-       while (write_mask) {
-               get_user(insn, (__u32*)(trigger_pc));
-               opcode = insn >> 26;
-               rc = insn & 0x1f;
-
-               switch (opcode) {
-                     case OPC_PAL:
-                     case OPC_JSR:
-                     case 0x30 ... 0x3f:       /* branches */
-                       MOD_DEC_USE_COUNT;
-                       return 0;
-
-                     case OPC_MISC:
-                       switch (insn & 0xffff) {
-                             case MISC_TRAPB:
-                             case MISC_EXCB:
-                               MOD_DEC_USE_COUNT;
-                               return 0;
-
-                             default:
-                               break;
-                       }
-                       break;
-
-                     case OPC_INTA:
-                     case OPC_INTL:
-                     case OPC_INTS:
-                     case OPC_INTM:
-                       write_mask &= ~(1UL << rc);
-                       break;
-
-                     case OPC_FLTC:
-                     case OPC_FLTV:
-                     case OPC_FLTI:
-                     case OPC_FLTL:
-                       write_mask &= ~(1UL << (rc + 32));
-                       break;
-               }
-               if (!write_mask) {
-                       if (alpha_fp_emul(trigger_pc)) {
-                               /* re-execute insns in trap-shadow: */
-                               regs->pc = trigger_pc + 4;
-                               MOD_DEC_USE_COUNT;
-                               return 1;
-                       }
-                       break;
-               }
-               trigger_pc -= 4;
-       }
-       MOD_DEC_USE_COUNT;
-       return 0;
-}
diff --git a/arch/alpha/math-emu/fp-emul.h b/arch/alpha/math-emu/fp-emul.h
deleted file mode 100644 (file)
index 12965fe..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * These defines correspond to the dynamic rounding mode bits in the
- * Floating Point Control Register.  They also happen to correspond to
- * the instruction encodings except that 0x03 signifies dynamic
- * rounding mode in that case.
- */
-#define ROUND_CHOP     0x00    /* chopped (aka round towards zero) */
-#define ROUND_NINF     0x01    /* round towards negative infinity */
-#define ROUND_NEAR     0x02    /* round towards nearest number */
-#define ROUND_PINF     0x03    /* round towards positive infinity */
diff --git a/arch/alpha/math-emu/ieee-math.c b/arch/alpha/math-emu/ieee-math.c
deleted file mode 100644 (file)
index 9a86b10..0000000
+++ /dev/null
@@ -1,1382 +0,0 @@
-/*
- * ieee-math.c - IEEE floating point emulation code
- * Copyright (C) 1989,1990,1991,1995 by
- * Digital Equipment Corporation, Maynard, Massachusetts.
- *
- * Heavily modified for Linux/Alpha.  Changes are Copyright (c) 1995
- * by David Mosberger (davidm@azstarnet.com).
- *
- * This file may be redistributed according to the terms of the
- * GNU General Public License.
- */
-/*
- * The original code did not have any comments. I have created many
- * comments as I fix the bugs in the code.  My comments are based on
- * my observation and interpretation of the code.  If the original
- * author would have spend a few minutes to comment the code, we would
- * never had a problem of misinterpretation.  -HA
- *
- * This code could probably be a lot more optimized (especially the
- * division routine).  However, my foremost concern was to get the
- * IEEE behavior right.  Performance is less critical as these
- * functions are used on exceptional numbers only (well, assuming you
- * don't turn on the "trap on inexact"...).
- */
-#include <linux/sched.h>
-#include "ieee-math.h"
-
-#define STICKY_S       0x20000000      /* both in longword 0 of fraction */
-#define STICKY_T       1
-
-/*
- * Careful: order matters here!
- */
-enum {
-       NaN, QNaN, INFTY, ZERO, DENORM, NORMAL
-};
-
-enum {
-       SINGLE, DOUBLE
-};
-
-typedef unsigned long fpclass_t;
-
-#define IEEE_TMAX      0x7fefffffffffffff
-#define IEEE_SMAX      0x47efffffe0000000
-#define IEEE_SNaN      0xfff00000000f0000
-#define IEEE_QNaN      0xfff8000000000000
-#define IEEE_PINF      0x7ff0000000000000
-#define IEEE_NINF      0xfff0000000000000
-
-
-/*
- * The memory format of S floating point numbers differs from the
- * register format.  In the following, the bitnumbers above the
- * diagram below give the memory format while the numbers below give
- * the register format.
- *
- *       31 30      23 22                              0
- *     +-----------------------------------------------+
- * S   | s |   exp    |       fraction                 |
- *     +-----------------------------------------------+
- *       63 62      52 51                            29
- *     
- * For T floating point numbers, the register and memory formats
- * match:
- *
- *     +-------------------------------------------------------------------+
- * T   | s |        exp        |           frac | tion                     |
- *     +-------------------------------------------------------------------+
- *       63 62               52 51            32 31                       0
- */
-typedef struct {
-       unsigned long   f[2];   /* bit 55 in f[0] is the factor of 2^0*/
-       int             s;      /* 1 bit sign (0 for +, 1 for -) */
-       int             e;      /* 16 bit signed exponent */
-} EXTENDED;
-
-
-/*
- * Return the sign of a Q integer, S or T fp number in the register
- * format.
- */
-static inline int
-sign (unsigned long a)
-{
-       if ((long) a < 0)
-               return -1;
-       else
-               return 1;
-}
-
-
-static inline long
-cmp128 (const long a[2], const long b[2])
-{
-       if (a[1] < b[1]) return -1;
-       if (a[1] > b[1]) return  1;
-       return a[0] - b[0];
-}
-
-
-static inline void
-sll128 (unsigned long a[2])
-{
-       a[1] = (a[1] << 1) | (a[0] >> 63);
-       a[0] <<= 1;
-}
-
-
-static inline void
-srl128 (unsigned long a[2])
-{
-       a[0] = (a[0] >> 1) | (a[1] << 63);
-       a[1] >>= 1;
-}
-
-
-static inline void
-add128 (const unsigned long a[2], const unsigned long b[2], unsigned long c[2])
-{
-       unsigned long carry = a[0] > (0xffffffffffffffff - b[0]);
-
-       c[0] = a[0] + b[0];
-       c[1] = a[1] + b[1] + carry;
-}
-
-
-static inline void
-sub128 (const unsigned long a[2], const unsigned long b[2], unsigned long c[2])
-{
-       unsigned long borrow = a[0] < b[0];
-
-       c[0] = a[0] - b[0];
-       c[1] = a[1] - b[1] - borrow;
-}
-
-
-static inline void
-mul64 (const unsigned long a, const unsigned long b, unsigned long c[2])
-{
-       c[0] = a * b;
-       asm ("umulh %1,%2,%0" : "=r"(c[1]) : "r"(a), "r"(b));
-}
-
-
-static void
-div128 (unsigned long a[2], unsigned long b[2], unsigned long c[2])
-{
-       unsigned long mask[2] = {1, 0};
-
-       /*
-        * Shift b until either the sign bit is set or until it is at
-        * least as big as the dividend:
-        */
-       while (cmp128(b, a) < 0 && sign(b[1]) >= 0) {
-               sll128(b);
-               sll128(mask);
-       }
-       c[0] = c[1] = 0;
-       do {
-               if (cmp128(a, b) >= 0) {
-                       sub128(a, b, a);
-                       add128(mask, c, c);
-               }
-               srl128(mask);
-               srl128(b);
-       } while (mask[0] || mask[1]);
-}
-
-
-static void
-normalize (EXTENDED *a)
-{
-       if (!a->f[0] && !a->f[1])
-               return;         /* zero fraction, unnormalizable... */
-       /*
-        * In "extended" format, the "1" in "1.f" is explicit; it is
-        * in bit 55 of f[0], and the decimal point is understood to
-        * be between bit 55 and bit 54.  To normalize, shift the
-        * fraction until we have a "1" in bit 55.
-        */
-       if ((a->f[0] & 0xff00000000000000) != 0 || a->f[1] != 0) {
-               /*
-                * Mantissa is greater than 1.0:
-                */
-               while ((a->f[0] & 0xff80000000000000) != 0x0080000000000000 ||
-                      a->f[1] != 0)
-               {
-                       unsigned long sticky;
-
-                       ++a->e;
-                       sticky = a->f[0] & 1;
-                       srl128(a->f);
-                       a->f[0] |= sticky;
-               }
-               return;
-       }
-
-       if (!(a->f[0] & 0x0080000000000000)) {
-               /*
-                * Mantissa is less than 1.0:
-                */
-               while (!(a->f[0] & 0x0080000000000000)) {
-                       --a->e;
-                       a->f[0] <<= 1;
-               }
-               return;
-       }
-}
-
-
-static inline fpclass_t
-ieee_fpclass (unsigned long a)
-{
-       unsigned long exp, fract;
-
-       exp   = (a >> 52) & 0x7ff;      /* 11 bits of exponent */
-       fract = a & 0x000fffffffffffff; /* 52 bits of fraction */
-       if (exp == 0) {
-               if (fract == 0)
-                       return ZERO;
-               return DENORM;
-       }
-       if (exp == 0x7ff) {
-               if (fract == 0)
-                       return INFTY;
-               if (((fract >> 51) & 1) != 0)
-                       return QNaN;
-               return NaN;
-       }
-       return NORMAL;
-}
-
-
-/*
- * Translate S/T fp number in register format into extended format.
- */
-static fpclass_t
-extend_ieee (unsigned long a, EXTENDED *b, int prec)
-{
-       fpclass_t result_kind;
-
-       b->s = a >> 63;
-       b->e = ((a >> 52) & 0x7ff) - 0x3ff;     /* remove bias */
-       b->f[1] = 0;
-       /*
-        * We shift f[1] left three bits so that the higher order bits
-        * of the fraction will reside in bits 55 through 0 of f[0].
-        */
-       b->f[0] = (a & 0x000fffffffffffff) << 3;
-       result_kind = ieee_fpclass(a);
-       if (result_kind == NORMAL) {
-               /* set implied 1. bit: */
-               b->f[0] |= 1UL << 55;
-       } else if (result_kind == DENORM) {
-               if (prec == SINGLE)
-                       b->e = -126;
-               else
-                       b->e = -1022;
-       }
-       return result_kind;
-}
-
-
-/*
- * INPUT PARAMETERS:
- *       a           a number in EXTENDED format to be converted to
- *                   s-floating format.
- *      f           rounding mode and exception enable bits.
- * OUTPUT PARAMETERS:
- *       b          will contain the s-floating number that "a" was
- *                  converted to (in register format).
- */
-static unsigned long
-make_s_ieee (long f, EXTENDED *a, unsigned long *b)
-{
-       unsigned long res, sticky;
-
-       if (!a->e && !a->f[0] && !a->f[1]) {
-               *b = (unsigned long) a->s << 63;        /* return +/-0 */
-               return 0;
-       }
-
-       normalize(a);
-       res = 0;
-
-       if (a->e < -0x7e) {
-               res = FPCR_INE;
-               if (f & IEEE_TRAP_ENABLE_UNF) {
-                       res |= FPCR_UNF;
-                       a->e += 0xc0;   /* scale up result by 2^alpha */
-               } else {
-                       /* try making denormalized number: */
-                       while (a->e < -0x7e) {
-                               ++a->e;
-                               sticky = a->f[0] & 1;
-                               srl128(a->f);
-                               if (!a->f[0] && !a->f[0]) {
-                                       /* underflow: replace with exact 0 */
-                                       res |= FPCR_UNF;
-                                       break;
-                               }
-                               a->f[0] |= sticky;
-                       }
-                       a->e = -0x3ff;
-               }
-       }
-       if (a->e >= 0x80) {
-               res = FPCR_OVF | FPCR_INE;
-               if (f & IEEE_TRAP_ENABLE_OVF) {
-                       a->e -= 0xc0;   /* scale down result by 2^alpha */
-               } else {
-                       /*
-                        * Overflow without trap enabled, substitute
-                        * result according to rounding mode:
-                        */
-                       switch (RM(f)) {
-                             case ROUND_NEAR:
-                               *b = IEEE_PINF;
-                               break;
-
-                             case ROUND_CHOP:
-                               *b = IEEE_SMAX;
-                               break;
-
-                             case ROUND_NINF:
-                               if (a->s) {
-                                       *b = IEEE_PINF;
-                               } else {
-                                       *b = IEEE_SMAX;
-                               }
-                               break;
-
-                             case ROUND_PINF: 
-                               if (a->s) {
-                                       *b = IEEE_SMAX;
-                               } else {
-                                       *b = IEEE_PINF;
-                               }
-                               break;
-                       }
-                       *b |= ((unsigned long) a->s << 63);
-                       return res;
-               }
-       }
-
-       *b = (((unsigned long) a->s << 63) |
-             (((unsigned long) a->e + 0x3ff) << 52) |
-             ((a->f[0] >> 3) & 0x000fffffe0000000));
-       return res;
-}
-
-
-static unsigned long
-make_t_ieee (long f, EXTENDED *a, unsigned long *b)
-{
-       unsigned long res, sticky;
-
-       if (!a->e && !a->f[0] && !a->f[1]) {
-               *b = (unsigned long) a->s << 63;        /* return +/-0 */
-               return 0;
-       }
-
-       normalize(a);
-       res = 0;
-       if (a->e < -0x3fe) {
-               res = FPCR_INE;
-               if (f & IEEE_TRAP_ENABLE_UNF) {
-                       res |= FPCR_UNF;
-                       a->e += 0x600;
-               } else {
-                       /* try making denormalized number: */
-                       while (a->e < -0x3fe) {
-                               ++a->e;
-                               sticky = a->f[0] & 1;
-                               srl128(a->f);
-                               if (!a->f[0] && !a->f[0]) {
-                                       /* underflow: replace with exact 0 */
-                                       res |= FPCR_UNF;
-                                       break;
-                               }
-                               a->f[0] |= sticky;
-                       }
-                       a->e = -0x3ff;
-               }
-       }
-       if (a->e >= 0x3ff) {
-               res = FPCR_OVF | FPCR_INE;
-               if (f & IEEE_TRAP_ENABLE_OVF) {
-                       a->e -= 0x600;  /* scale down result by 2^alpha */
-               } else {
-                       /*
-                        * Overflow without trap enabled, substitute
-                        * result according to rounding mode:
-                        */
-                       switch (RM(f)) {
-                             case ROUND_NEAR:
-                               *b = IEEE_PINF;
-                               break;
-
-                             case ROUND_CHOP:
-                               *b = IEEE_TMAX;
-                               break;
-
-                             case ROUND_NINF:
-                               if (a->s) {
-                                       *b = IEEE_PINF;
-                               } else {
-                                       *b = IEEE_TMAX;
-                               }
-                               break;
-
-                             case ROUND_PINF: 
-                               if (a->s) {
-                                       *b = IEEE_TMAX;
-                               } else {
-                                       *b = IEEE_PINF;
-                               }
-                               break;
-                       }
-                       *b |= ((unsigned long) a->s << 63);
-                       return res;
-               }
-       }
-       *b = (((unsigned long) a->s << 63) |
-             (((unsigned long) a->e + 0x3ff) << 52) |
-             ((a->f[0] >> 3) & 0x000fffffffffffff));
-       return res;
-}
-
-
-/*
- * INPUT PARAMETERS:
- *       a          EXTENDED format number to be rounded.
- *       rm        integer with value ROUND_NEAR, ROUND_CHOP, etc.
- *                  indicates how "a" should be rounded to produce "b".
- * OUTPUT PARAMETERS:
- *       b          s-floating number produced by rounding "a".
- * RETURN VALUE:
- *       if no errors occurred, will be zero.  Else will contain flags
- *       like FPCR_INE_OP, etc.
- */
-static unsigned long
-round_s_ieee (int f, EXTENDED *a, unsigned long *b)
-{
-       unsigned long diff1, diff2, res = 0;
-       EXTENDED z1, z2;
-
-       if (!(a->f[0] & 0xffffffff)) {
-               return make_s_ieee(f, a, b);    /* no rounding error */
-       }
-
-       /*
-        * z1 and z2 are the S-floating numbers with the next smaller/greater
-        * magnitude than a, respectively.
-        */
-       z1.s = z2.s = a->s;
-       z1.e = z2.e = a->e;
-       z1.f[0] = z2.f[0] = a->f[0] & 0xffffffff00000000;
-       z1.f[1] = z2.f[1] = 0;
-       z2.f[0] += 0x100000000; /* next bigger S float number */
-
-       switch (RM(f)) {
-             case ROUND_NEAR:
-               diff1 = a->f[0] - z1.f[0];
-               diff2 = z2.f[0] - a->f[0];
-               if (diff1 > diff2)
-                       res = make_s_ieee(f, &z2, b);
-               else if (diff2 > diff1)
-                       res = make_s_ieee(f, &z1, b);
-               else
-                       /* equal distance: round towards even */
-                       if (z1.f[0] & 0x100000000)
-                               res = make_s_ieee(f, &z2, b);
-                       else
-                               res = make_s_ieee(f, &z1, b);
-               break;
-
-             case ROUND_CHOP:
-               res = make_s_ieee(f, &z1, b);
-               break;
-
-             case ROUND_PINF:
-               if (a->s) {
-                       res = make_s_ieee(f, &z1, b);
-               } else {
-                       res = make_s_ieee(f, &z2, b);
-               }
-               break;
-
-             case ROUND_NINF:
-               if (a->s) {
-                       res = make_s_ieee(f, &z2, b);
-               } else {
-                       res = make_s_ieee(f, &z1, b);
-               }
-               break;
-       }
-       return FPCR_INE | res;
-}
-
-
-static unsigned long
-round_t_ieee (int f, EXTENDED *a, unsigned long *b)
-{
-       unsigned long diff1, diff2, res;
-       EXTENDED z1, z2;
-
-       if (!(a->f[0] & 0x7)) {
-               /* no rounding error */
-               return make_t_ieee(f, a, b);
-       }
-
-       z1.s = z2.s = a->s;
-       z1.e = z2.e = a->e;
-       z1.f[0] = z2.f[0] = a->f[0] & ~0x7;
-       z1.f[1] = z2.f[1] = 0;
-       z2.f[0] += (1 << 3);
-
-       res = 0;
-       switch (RM(f)) {
-             case ROUND_NEAR:
-               diff1 = a->f[0] - z1.f[0];
-               diff2 = z2.f[0] - a->f[0];
-               if (diff1 > diff2)
-                       res = make_t_ieee(f, &z2, b);
-               else if (diff2 > diff1)
-                       res = make_t_ieee(f, &z1, b);
-               else
-                       /* equal distance: round towards even */
-                       if (z1.f[0] & (1 << 3))
-                               res = make_t_ieee(f, &z2, b);
-                       else
-                               res = make_t_ieee(f, &z1, b);
-               break;
-
-             case ROUND_CHOP:
-               res = make_t_ieee(f, &z1, b);
-               break;
-
-             case ROUND_PINF:
-               if (a->s) {
-                       res = make_t_ieee(f, &z1, b);
-               } else {
-                       res = make_t_ieee(f, &z2, b);
-               }
-               break;
-
-             case ROUND_NINF:
-               if (a->s) {
-                       res = make_t_ieee(f, &z2, b);
-               } else {
-                       res = make_t_ieee(f, &z1, b);
-               }
-               break;
-       }
-       return FPCR_INE | res;
-}
-
-
-static fpclass_t
-add_kernel_ieee (EXTENDED *op_a, EXTENDED *op_b, EXTENDED *op_c)
-{
-       unsigned long mask, fa, fb, fc;
-       int diff;
-
-       diff = op_a->e - op_b->e;
-       fa = op_a->f[0];
-       fb = op_b->f[0];
-       if (diff < 0) {
-               diff = -diff;
-               op_c->e = op_b->e;
-               mask = (1UL << diff) - 1;
-               fa >>= diff;
-               if (op_a->f[0] & mask) {
-                       fa |= 1;                /* set sticky bit */
-               }
-       } else {
-               op_c->e = op_a->e;
-               mask = (1UL << diff) - 1;
-               fb >>= diff;
-               if (op_b->f[0] & mask) {
-                       fb |= 1;                /* set sticky bit */
-               }
-       }
-       if (op_a->s)
-               fa = -fa;
-       if (op_b->s)
-               fb = -fb;
-       fc = fa + fb;
-       op_c->f[1] = 0;
-       op_c->s = fc >> 63;
-       if (op_c->s) {
-               fc = -fc;
-       }
-       op_c->f[0] = fc;
-       normalize(op_c);
-       return 0;
-}
-
-
-/*
- * converts s-floating "a" to t-floating "b".
- *
- * INPUT PARAMETERS:
- *       a           a s-floating number to be converted
- *       f           the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- *       b           the t-floating number that "a" is converted to.
- * RETURN VALUE:
- *       error flags - i.e., zero if no errors occurred,
- *       FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTST (int f, unsigned long a, unsigned long *b)
-{
-       EXTENDED temp;
-       fpclass_t a_type;
-
-       a_type = extend_ieee(a, &temp, SINGLE);
-       if (a_type >= NaN && a_type <= INFTY) {
-               *b = a;
-               if (a_type == NaN) {
-                       *b |= (1UL << 51);      /* turn SNaN into QNaN */
-                       return FPCR_INV;
-               }
-               return 0;
-       }
-       return round_t_ieee(f, &temp, b);
-}
-
-
-/*
- * converts t-floating "a" to s-floating "b".
- *
- * INPUT PARAMETERS:
- *       a           a t-floating number to be converted
- *       f           the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- *       b           the s-floating number that "a" is converted to.
- * RETURN VALUE:
- *       error flags - i.e., zero if no errors occurred,
- *       FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTTS (int f, unsigned long a, unsigned long *b)
-{
-       EXTENDED temp;
-       fpclass_t a_type;
-
-       a_type = extend_ieee(a, &temp, DOUBLE);
-       if (a_type >= NaN && a_type <= INFTY) {
-               *b = a;
-               if (a_type == NaN) {
-                       *b |= (1UL << 51);      /* turn SNaN into QNaN */
-                       return FPCR_INV;
-               }
-               return 0;
-       }
-       return round_s_ieee(f, &temp, b);
-}
-
-
-/*
- * converts q-format (64-bit integer) "a" to s-floating "b".
- *
- * INPUT PARAMETERS:
- *       a           an 64-bit integer to be converted.
- *       f           the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- *       b           the s-floating number "a" is converted to.
- * RETURN VALUE:
- *       error flags - i.e., zero if no errors occurred,
- *       FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTQS (int f, unsigned long a, unsigned long *b)
-{
-       EXTENDED op_b;
-
-       op_b.s    = 0;
-       op_b.f[0] = a;
-       op_b.f[1] = 0;
-       if (sign(a) < 0) {
-               op_b.s = 1;
-               op_b.f[0] = -a;
-       }
-       op_b.e = 55;
-       normalize(&op_b);
-       return round_s_ieee(f, &op_b, b);
-}
-
-
-/*
- * converts 64-bit integer "a" to t-floating "b".
- *
- * INPUT PARAMETERS:
- *       a           a 64-bit integer to be converted.
- *       f           the rounding mode (ROUND_NEAR, etc.)
- * OUTPUT PARAMETERS:
- *       b           the t-floating number "a" is converted to.
- * RETURN VALUE:
- *       error flags - i.e., zero if no errors occurred,
- *       FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTQT (int f, long a, unsigned long *b)
-{
-       EXTENDED op_b;
-
-       if (a != 0) {
-               op_b.s = (a < 0 ? 1 : 0);
-               op_b.f[0] = (a < 0 ? -a : a);
-               op_b.f[1] = 0;
-               op_b.e = 55;
-               normalize(&op_b);
-               return round_t_ieee(f, &op_b, b);
-       } else {
-               *b = 0;
-               return 0;
-       }
-}
-
-
-/*
- * converts t-floating "a" to 64-bit integer (q-format) "b".
- *
- * INPUT PARAMETERS:
- *       a           a t-floating number to be converted.
- *       f           the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- *       b           the 64-bit integer "a" is converted to.
- * RETURN VALUE:
- *       error flags - i.e., zero if no errors occurred,
- *       FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTTQ (int f, unsigned long a, unsigned long *pb)
-{
-       unsigned int midway;
-       unsigned long ov, uv, res, b;
-       fpclass_t a_type;
-       EXTENDED temp;
-
-       a_type = extend_ieee(a, &temp, DOUBLE);
-
-       b = 0x7fffffffffffffff;
-       res = FPCR_INV;
-       if (a_type == NaN || a_type == INFTY)
-               goto out;
-
-       res = 0;
-       if (a_type == QNaN)
-               goto out;
-
-       if (temp.e > 0) {
-               ov = 0;
-               while (temp.e > 0) {
-                       --temp.e;
-                       ov |= temp.f[1] >> 63;
-                       sll128(temp.f);
-               }
-               if (ov || (temp.f[1] & 0xffc0000000000000))
-                       res |= FPCR_IOV | FPCR_INE;
-       }
-       else if (temp.e < 0) {
-               while (temp.e < 0) {
-                       ++temp.e;
-                       uv = temp.f[0] & 1;             /* save sticky bit */
-                       srl128(temp.f);
-                       temp.f[0] |= uv;
-               }
-       }
-       b = (temp.f[1] << 9) | (temp.f[0] >> 55);
-
-       /*
-        * Notice: the fraction is only 52 bits long.  Thus, rounding
-        * cannot possibly result in an integer overflow.
-        */
-       switch (RM(f)) {
-             case ROUND_NEAR:
-               if (temp.f[0] & 0x0040000000000000) {
-                       midway = (temp.f[0] & 0x003fffffffffffff) == 0;
-                       if ((midway && (temp.f[0] & 0x0080000000000000)) ||
-                           !midway)
-                               ++b;
-               }
-               break;
-
-             case ROUND_PINF:
-               b += ((temp.f[0] & 0x007fffffffffffff) != 0 && !temp.s);
-               break;
-
-             case ROUND_NINF:
-               b += ((temp.f[0] & 0x007fffffffffffff) != 0 && temp.s);
-               break;
-
-             case ROUND_CHOP:
-               /* no action needed */
-               break;
-       }
-       if ((temp.f[0] & 0x007fffffffffffff) != 0)
-               res |= FPCR_INE;
-
-       if (temp.s) {
-               b = -b;
-       }
-
-out:
-       *pb = b;
-       return res;
-}
-
-
-unsigned long
-ieee_CMPTEQ (unsigned long a, unsigned long b, unsigned long *c)
-{
-       EXTENDED op_a, op_b;
-       fpclass_t a_type, b_type;
-
-       *c = 0;
-       a_type = extend_ieee(a, &op_a, DOUBLE);
-       b_type = extend_ieee(b, &op_b, DOUBLE);
-       if (a_type == NaN || b_type == NaN)
-               return FPCR_INV;
-       if (a_type == QNaN || b_type == QNaN)
-               return 0;
-
-       if ((op_a.e == op_b.e && op_a.s == op_b.s &&
-            op_a.f[0] == op_b.f[0] && op_a.f[1] == op_b.f[1]) ||
-           (a_type == ZERO && b_type == ZERO))
-               *c = 0x4000000000000000;
-       return 0;
-}
-
-
-unsigned long
-ieee_CMPTLT (unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b;
-
-       *c = 0;
-       a_type = extend_ieee(a, &op_a, DOUBLE);
-       b_type = extend_ieee(b, &op_b, DOUBLE);
-       if (a_type == NaN || b_type == NaN)
-               return FPCR_INV;
-       if (a_type == QNaN || b_type == QNaN)
-               return 0;
-
-       if ((op_a.s == 1 && op_b.s == 0 &&
-            (a_type != ZERO || b_type != ZERO)) ||
-           (op_a.s == 1 && op_b.s == 1 &&
-            (op_a.e > op_b.e || (op_a.e == op_b.e &&
-                                 cmp128(op_a.f, op_b.f) > 0))) ||
-           (op_a.s == 0 && op_b.s == 0 &&
-            (op_a.e < op_b.e || (op_a.e == op_b.e &&
-                                 cmp128(op_a.f,op_b.f) < 0))))
-               *c = 0x4000000000000000;
-       return 0;
-}
-
-
-unsigned long
-ieee_CMPTLE (unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b;
-
-       *c = 0;
-       a_type = extend_ieee(a, &op_a, DOUBLE);
-       b_type = extend_ieee(b, &op_b, DOUBLE);
-       if (a_type == NaN || b_type == NaN)
-               return FPCR_INV;
-       if (a_type == QNaN || b_type == QNaN)
-               return 0;
-
-       if ((a_type == ZERO && b_type == ZERO) ||
-           (op_a.s == 1 && op_b.s == 0) ||
-           (op_a.s == 1 && op_b.s == 1 &&
-            (op_a.e > op_b.e || (op_a.e == op_b.e &&
-                                 cmp128(op_a.f,op_b.f) >= 0))) ||
-           (op_a.s == 0 && op_b.s == 0 &&
-            (op_a.e < op_b.e || (op_a.e == op_b.e &&
-                                 cmp128(op_a.f,op_b.f) <= 0))))
-               *c = 0x4000000000000000;
-       return 0;
-}
-
-
-unsigned long
-ieee_CMPTUN (unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b;
-
-       *c = 0x4000000000000000;
-       a_type = extend_ieee(a, &op_a, DOUBLE);
-       b_type = extend_ieee(b, &op_b, DOUBLE);
-       if (a_type == NaN || b_type == NaN)
-               return FPCR_INV;
-       if (a_type == QNaN || b_type == QNaN)
-               return 0;
-       *c = 0;
-       return 0;
-}
-
-
-/*
- * Add a + b = c, where a, b, and c are ieee s-floating numbers.  "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_ADDS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b, op_c;
-
-       a_type = extend_ieee(a, &op_a, SINGLE);
-       b_type = extend_ieee(b, &op_b, SINGLE);
-       if ((a_type >= NaN && a_type <= INFTY) ||
-           (b_type >= NaN && b_type <= INFTY))
-       {
-               /* propagate NaNs according to arch. ref. handbook: */
-               if (b_type == QNaN)
-                       *c = b;
-               else if (b_type == NaN)
-                       *c = b | (1UL << 51);
-               else if (a_type == QNaN)
-                       *c = a;
-               else if (a_type == NaN)
-                       *c = a | (1UL << 51);
-
-               if (a_type == NaN || b_type == NaN)
-                       return FPCR_INV;
-               if (a_type == QNaN || b_type == QNaN)
-                       return 0;
-
-               if (a_type == INFTY && b_type == INFTY && sign(a) != sign(b)) {
-                       *c = IEEE_QNaN;
-                       return FPCR_INV;
-               }
-               if (a_type == INFTY)
-                       *c = a;
-               else
-                       *c = b;
-               return 0;
-       }
-
-       add_kernel_ieee(&op_a, &op_b, &op_c);
-       /* special case for -0 + -0 ==> -0 */
-       if (a_type == ZERO && b_type == ZERO)
-               op_c.s = op_a.s && op_b.s;
-       return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Add a + b = c, where a, b, and c are ieee t-floating numbers.  "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_ADDT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b, op_c;
-
-       a_type = extend_ieee(a, &op_a, DOUBLE);
-       b_type = extend_ieee(b, &op_b, DOUBLE);
-       if ((a_type >= NaN && a_type <= INFTY) ||
-           (b_type >= NaN && b_type <= INFTY))
-       {
-               /* propagate NaNs according to arch. ref. handbook: */
-               if (b_type == QNaN)
-                       *c = b;
-               else if (b_type == NaN)
-                       *c = b | (1UL << 51);
-               else if (a_type == QNaN)
-                       *c = a;
-               else if (a_type == NaN)
-                       *c = a | (1UL << 51);
-
-               if (a_type == NaN || b_type == NaN)
-                       return FPCR_INV;
-               if (a_type == QNaN || b_type == QNaN)
-                       return 0;
-
-               if (a_type == INFTY && b_type == INFTY && sign(a) != sign(b)) {
-                       *c = IEEE_QNaN;
-                       return FPCR_INV;
-               }
-               if (a_type == INFTY)
-                       *c = a;
-               else
-                       *c = b;
-               return 0;
-       }
-       add_kernel_ieee(&op_a, &op_b, &op_c);
-       /* special case for -0 + -0 ==> -0 */
-       if (a_type == ZERO && b_type == ZERO)
-               op_c.s = op_a.s && op_b.s;
-
-       return round_t_ieee(f, &op_c, c);
-}
-
-
-/*
- * Subtract a - b = c, where a, b, and c are ieee s-floating numbers.
- * "f" contains the rounding mode etc.
- */
-unsigned long
-ieee_SUBS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b, op_c;
-
-       a_type = extend_ieee(a, &op_a, SINGLE);
-       b_type = extend_ieee(b, &op_b, SINGLE);
-       if ((a_type >= NaN && a_type <= INFTY) ||
-           (b_type >= NaN && b_type <= INFTY))
-       {
-               /* propagate NaNs according to arch. ref. handbook: */
-               if (b_type == QNaN)
-                       *c = b;
-               else if (b_type == NaN)
-                       *c = b | (1UL << 51);
-               else if (a_type == QNaN)
-                       *c = a;
-               else if (a_type == NaN)
-                       *c = a | (1UL << 51);
-
-               if (a_type == NaN || b_type == NaN)
-                       return FPCR_INV;
-               if (a_type == QNaN || b_type == QNaN)
-                       return 0;
-
-               if (a_type == INFTY && b_type == INFTY && sign(a) == sign(b)) {
-                       *c = IEEE_QNaN;
-                       return FPCR_INV;
-               }
-               if (a_type == INFTY)
-                       *c = a;
-               else
-                       *c = b ^ (1UL << 63);
-               return 0;
-       }
-       op_b.s = !op_b.s;
-       add_kernel_ieee(&op_a, &op_b, &op_c);
-       /* special case for -0 - +0 ==> -0 */
-       if (a_type == ZERO && b_type == ZERO)
-               op_c.s = op_a.s && op_b.s;
-
-       return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Subtract a - b = c, where a, b, and c are ieee t-floating numbers.
- * "f" contains the rounding mode etc.
- */
-unsigned long
-ieee_SUBT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b, op_c;
-
-       a_type = extend_ieee(a, &op_a, DOUBLE);
-       b_type = extend_ieee(b, &op_b, DOUBLE);
-       if ((a_type >= NaN && a_type <= INFTY) ||
-           (b_type >= NaN && b_type <= INFTY))
-       {
-               /* propagate NaNs according to arch. ref. handbook: */
-               if (b_type == QNaN)
-                       *c = b;
-               else if (b_type == NaN)
-                       *c = b | (1UL << 51);
-               else if (a_type == QNaN)
-                       *c = a;
-               else if (a_type == NaN)
-                       *c = a | (1UL << 51);
-
-               if (a_type == NaN || b_type == NaN)
-                       return FPCR_INV;
-               if (a_type == QNaN || b_type == QNaN)
-                       return 0;
-
-               if (a_type == INFTY && b_type == INFTY && sign(a) == sign(b)) {
-                       *c = IEEE_QNaN;
-                       return FPCR_INV;
-               }
-               if (a_type == INFTY)
-                       *c = a;
-               else
-                       *c = b ^ (1UL << 63);
-               return 0;
-       }
-       op_b.s = !op_b.s;
-       add_kernel_ieee(&op_a, &op_b, &op_c);
-       /* special case for -0 - +0 ==> -0 */
-       if (a_type == ZERO && b_type == ZERO)
-               op_c.s = op_a.s && op_b.s;
-
-       return round_t_ieee(f, &op_c, c);
-}
-
-
-/*
- * Multiply a x b = c, where a, b, and c are ieee s-floating numbers.
- * "f" contains the rounding mode.
- */
-unsigned long
-ieee_MULS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b, op_c;
-
-       a_type = extend_ieee(a, &op_a, SINGLE);
-       b_type = extend_ieee(b, &op_b, SINGLE);
-       if ((a_type >= NaN && a_type <= INFTY) ||
-           (b_type >= NaN && b_type <= INFTY))
-       {
-               /* propagate NaNs according to arch. ref. handbook: */
-               if (b_type == QNaN)
-                       *c = b;
-               else if (b_type == NaN)
-                       *c = b | (1UL << 51);
-               else if (a_type == QNaN)
-                       *c = a;
-               else if (a_type == NaN)
-                       *c = a | (1UL << 51);
-
-               if (a_type == NaN || b_type == NaN)
-                       return FPCR_INV;
-               if (a_type == QNaN || b_type == QNaN)
-                       return 0;
-
-               if ((a_type == INFTY && b_type == ZERO) ||
-                   (b_type == INFTY && a_type == ZERO))
-               {
-                       *c = IEEE_QNaN;         /* return canonical QNaN */
-                       return FPCR_INV;
-               }
-               if (a_type == INFTY)
-                       *c = a ^ ((b >> 63) << 63);
-               else if (b_type == INFTY)
-                       *c = b ^ ((a >> 63) << 63);
-               else
-                       /* either of a and b are +/-0 */
-                       *c = ((unsigned long) op_a.s ^ op_b.s) << 63;
-               return 0;
-       }
-       op_c.s = op_a.s ^ op_b.s;
-       op_c.e = op_a.e + op_b.e - 55;
-       mul64(op_a.f[0], op_b.f[0], op_c.f);
-
-       return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Multiply a x b = c, where a, b, and c are ieee t-floating numbers.
- * "f" contains the rounding mode.
- */
-unsigned long
-ieee_MULT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b, op_c;
-
-       *c = IEEE_QNaN;
-       a_type = extend_ieee(a, &op_a, DOUBLE);
-       b_type = extend_ieee(b, &op_b, DOUBLE);
-       if ((a_type >= NaN && a_type <= ZERO) ||
-           (b_type >= NaN && b_type <= ZERO))
-       {
-               /* propagate NaNs according to arch. ref. handbook: */
-               if (b_type == QNaN)
-                       *c = b;
-               else if (b_type == NaN)
-                       *c = b | (1UL << 51);
-               else if (a_type == QNaN)
-                       *c = a;
-               else if (a_type == NaN)
-                       *c = a | (1UL << 51);
-
-               if (a_type == NaN || b_type == NaN)
-                       return FPCR_INV;
-               if (a_type == QNaN || b_type == QNaN)
-                       return 0;
-
-               if ((a_type == INFTY && b_type == ZERO) ||
-                   (b_type == INFTY && a_type == ZERO))
-               {
-                       *c = IEEE_QNaN;         /* return canonical QNaN */
-                       return FPCR_INV;
-               }
-               if (a_type == INFTY)
-                       *c = a ^ ((b >> 63) << 63);
-               else if (b_type == INFTY)
-                       *c = b ^ ((a >> 63) << 63);
-               else
-                       /* either of a and b are +/-0 */
-                       *c = ((unsigned long) op_a.s ^ op_b.s) << 63;
-               return 0;
-       }
-       op_c.s = op_a.s ^ op_b.s;
-       op_c.e = op_a.e + op_b.e - 55;
-       mul64(op_a.f[0], op_b.f[0], op_c.f);
-
-       return round_t_ieee(f, &op_c, c);
-}
-
-
-/*
- * Divide a / b = c, where a, b, and c are ieee s-floating numbers.
- * "f" contains the rounding mode etc.
- */
-unsigned long
-ieee_DIVS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b, op_c;
-
-       a_type = extend_ieee(a, &op_a, SINGLE);
-       b_type = extend_ieee(b, &op_b, SINGLE);
-       if ((a_type >= NaN && a_type <= ZERO) ||
-           (b_type >= NaN && b_type <= ZERO))
-       {
-               unsigned long res;
-
-               /* propagate NaNs according to arch. ref. handbook: */
-               if (b_type == QNaN)
-                       *c = b;
-               else if (b_type == NaN)
-                       *c = b | (1UL << 51);
-               else if (a_type == QNaN)
-                       *c = a;
-               else if (a_type == NaN)
-                       *c = a | (1UL << 51);
-
-               if (a_type == NaN || b_type == NaN)
-                       return FPCR_INV;
-               if (a_type == QNaN || b_type == QNaN)
-                       return 0;
-
-               res = 0;
-               *c = IEEE_PINF;
-               if (a_type == INFTY) {
-                       if (b_type == INFTY) {
-                               *c = IEEE_QNaN;
-                               return FPCR_INV;
-                       }
-               } else if (b_type == ZERO) {
-                       if (a_type == ZERO) {
-                               *c = IEEE_QNaN;
-                               return FPCR_INV;
-                       }
-                       res = FPCR_DZE;
-               } else
-                       /* a_type == ZERO || b_type == INFTY */
-                       *c = 0;
-               *c |= (unsigned long) (op_a.s ^ op_b.s) << 63;
-               return res;
-       }
-       op_c.s = op_a.s ^ op_b.s;
-       op_c.e = op_a.e - op_b.e;
-
-       op_a.f[1] = op_a.f[0];
-       op_a.f[0] = 0;
-       div128(op_a.f, op_b.f, op_c.f);
-       if (a_type != ZERO)
-               /* force a sticky bit because DIVs never hit exact .5: */
-               op_c.f[0] |= STICKY_S;
-       normalize(&op_c);
-       op_c.e -= 9;            /* remove excess exp from original shift */
-       return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Divide a/b = c, where a, b, and c are ieee t-floating numbers.  "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_DIVT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-       fpclass_t a_type, b_type;
-       EXTENDED op_a, op_b, op_c;
-
-       *c = IEEE_QNaN;
-       a_type = extend_ieee(a, &op_a, DOUBLE);
-       b_type = extend_ieee(b, &op_b, DOUBLE);
-       if ((a_type >= NaN && a_type <= ZERO) ||
-           (b_type >= NaN && b_type <= ZERO))
-       {
-               unsigned long res;
-
-               /* propagate NaNs according to arch. ref. handbook: */
-               if (b_type == QNaN)
-                       *c = b;
-               else if (b_type == NaN)
-                       *c = b | (1UL << 51);
-               else if (a_type == QNaN)
-                       *c = a;
-               else if (a_type == NaN)
-                       *c = a | (1UL << 51);
-
-               if (a_type == NaN || b_type == NaN)
-                       return FPCR_INV;
-               if (a_type == QNaN || b_type == QNaN)
-                       return 0;
-
-               res = 0;
-               *c = IEEE_PINF;
-               if (a_type == INFTY) {
-                       if (b_type == INFTY) {
-                               *c = IEEE_QNaN;
-                               return FPCR_INV;
-                       }
-               } else if (b_type == ZERO) {
-                       if (a_type == ZERO) {
-                               *c = IEEE_QNaN;
-                               return FPCR_INV;
-                       }
-                       res = FPCR_DZE;
-               } else
-                       /* a_type == ZERO || b_type == INFTY */
-                       *c = 0;
-               *c |= (unsigned long) (op_a.s ^ op_b.s) << 63;
-               return res;
-       }
-       op_c.s = op_a.s ^ op_b.s;
-       op_c.e = op_a.e - op_b.e;
-
-       op_a.f[1] = op_a.f[0];
-       op_a.f[0] = 0;
-       div128(op_a.f, op_b.f, op_c.f);
-       if (a_type != ZERO)
-               /* force a sticky bit because DIVs never hit exact .5 */
-               op_c.f[0] |= STICKY_T;
-       normalize(&op_c);
-       op_c.e -= 9;            /* remove excess exp from original shift */
-       return round_t_ieee(f, &op_c, c);
-}
-
-/*
- * Sqrt a = b, where a and b are ieee s-floating numbers.  "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_SQRTS (int f, unsigned long a, unsigned long *b)
-{
-       fpclass_t a_type;
-       EXTENDED op_a, op_b;
-
-       *b = IEEE_QNaN;
-       a_type = extend_ieee(a, &op_a, SINGLE);
-       if (op_a.s == 0) {
-               /* FIXME -- handle positive denormals.  */
-               send_sig(SIGFPE, current, 1);
-       }
-       return FPCR_INV;
-}
-
-/*
- * Sqrt a = b, where a and b are ieee t-floating numbers.  "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_SQRTT (int f, unsigned long a, unsigned long *b)
-{
-       fpclass_t a_type;
-       EXTENDED op_a, op_b;
-
-       *b = IEEE_QNaN;
-       a_type = extend_ieee(a, &op_a, DOUBLE);
-       if (op_a.s == 0) {
-               /* FIXME -- handle positive denormals.  */
-               send_sig(SIGFPE, current, 1);
-       }
-       return FPCR_INV;
-}
diff --git a/arch/alpha/math-emu/ieee-math.h b/arch/alpha/math-emu/ieee-math.h
deleted file mode 100644 (file)
index 076a6d1..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 1992,1995 by
- * Digital Equipment Corporation, Maynard, Massachusetts.
- * This file may be redistributed according to the terms of the
- * GNU General Public License.
- */
-#ifndef __ieee_math_h__
-#define __ieee_math_h__
-
-#include <asm/fpu.h>
-
-#define ROUND_SHIFT    6               /* make space for trap-enable bits */
-#define RM(f)          (((f) >> ROUND_SHIFT) & 0x3)
-
-#define ROUND_CHOP     (FPCR_DYN_CHOPPED >> FPCR_DYN_SHIFT)
-#define ROUND_NINF     (FPCR_DYN_MINUS   >> FPCR_DYN_SHIFT)
-#define ROUND_NEAR     (FPCR_DYN_NORMAL  >> FPCR_DYN_SHIFT)
-#define ROUND_PINF     (FPCR_DYN_PLUS    >> FPCR_DYN_SHIFT)
-
-extern unsigned long ieee_CVTST (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_CVTTS (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_CVTQS (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_CVTQT (int rm, long a, unsigned long *b);
-extern unsigned long ieee_CVTTQ (int rm, unsigned long a, unsigned long *b);
-
-extern unsigned long ieee_CMPTEQ (unsigned long a, unsigned long b,
-                                 unsigned long *c);
-extern unsigned long ieee_CMPTLT (unsigned long a, unsigned long b,
-                                 unsigned long *c);
-extern unsigned long ieee_CMPTLE (unsigned long a, unsigned long b,
-                                 unsigned long *c);
-extern unsigned long ieee_CMPTUN (unsigned long a, unsigned long b,
-                                 unsigned long *c);
-
-extern unsigned long ieee_ADDS (int rm, unsigned long a, unsigned long b,
-                               unsigned long *c);
-extern unsigned long ieee_ADDT (int rm, unsigned long a, unsigned long b,
-                               unsigned long *c);
-extern unsigned long ieee_SUBS (int rm, unsigned long a, unsigned long b,
-                               unsigned long *c);
-extern unsigned long ieee_SUBT (int rm, unsigned long a, unsigned long b,
-                               unsigned long *c);
-extern unsigned long ieee_MULS (int rm, unsigned long a, unsigned long b,
-                               unsigned long *c);
-extern unsigned long ieee_MULT (int rm, unsigned long a, unsigned long b,
-                               unsigned long *c);
-extern unsigned long ieee_DIVS (int rm, unsigned long a, unsigned long b,
-                               unsigned long *c);
-extern unsigned long ieee_DIVT (int rm, unsigned long a, unsigned long b,
-                               unsigned long *c);
-extern unsigned long ieee_SQRTS (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_SQRTT (int rm, unsigned long a, unsigned long *b);
-
-#endif /* __ieee_math_h__ */
diff --git a/arch/alpha/math-emu/math.c b/arch/alpha/math-emu/math.c
new file mode 100644 (file)
index 0000000..c0ece7b
--- /dev/null
@@ -0,0 +1,447 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/uaccess.h>
+
+#include "sfp-util.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+#include <math-emu/double.h>
+
+#define        OPC_PAL         0x00
+#define OPC_INTA       0x10
+#define OPC_INTL       0x11
+#define OPC_INTS       0x12
+#define OPC_INTM       0x13
+#define OPC_FLTC       0x14
+#define OPC_FLTV       0x15
+#define OPC_FLTI       0x16
+#define OPC_FLTL       0x17
+#define OPC_MISC       0x18
+#define        OPC_JSR         0x1a
+
+#define FOP_SRC_S      0
+#define FOP_SRC_T      2
+#define FOP_SRC_Q      3
+
+#define FOP_FNC_ADDx   0
+#define FOP_FNC_CVTQL  0
+#define FOP_FNC_SUBx   1
+#define FOP_FNC_MULx   2
+#define FOP_FNC_DIVx   3
+#define FOP_FNC_CMPxUN 4
+#define FOP_FNC_CMPxEQ 5
+#define FOP_FNC_CMPxLT 6
+#define FOP_FNC_CMPxLE 7
+#define FOP_FNC_SQRTx  11
+#define FOP_FNC_CVTxS  12
+#define FOP_FNC_CVTxT  14
+#define FOP_FNC_CVTxQ  15
+
+#define MISC_TRAPB     0x0000
+#define MISC_EXCB      0x0400
+
+extern unsigned long alpha_read_fp_reg (unsigned long reg);
+extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
+extern unsigned long alpha_read_fp_reg_s (unsigned long reg);
+extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val);
+
+
+#ifdef MODULE
+
+MODULE_DESCRIPTION("FP Software completion module");
+
+extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long);
+extern long (*alpha_fp_emul) (unsigned long pc);
+
+static long (*save_emul_imprecise)(struct pt_regs *, unsigned long);
+static long (*save_emul) (unsigned long pc);
+
+long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long);
+long do_alpha_fp_emul(unsigned long);
+
+int init_module(void)
+{
+       save_emul_imprecise = alpha_fp_emul_imprecise;
+       save_emul = alpha_fp_emul;
+       alpha_fp_emul_imprecise = do_alpha_fp_emul_imprecise;
+       alpha_fp_emul = do_alpha_fp_emul;
+       return 0;
+}
+
+void cleanup_module(void)
+{
+       alpha_fp_emul_imprecise = save_emul_imprecise;
+       alpha_fp_emul = save_emul;
+}
+
+#undef  alpha_fp_emul_imprecise
+#define alpha_fp_emul_imprecise                do_alpha_fp_emul_imprecise
+#undef  alpha_fp_emul
+#define alpha_fp_emul                  do_alpha_fp_emul
+
+#endif /* MODULE */
+
+/* For 128-bit division.  */
+
+void
+udiv128(unsigned long divisor_f0, unsigned long divisor_f1,
+       unsigned long dividend_f0, unsigned long dividend_f1,
+       unsigned long *quot, unsigned long *remd)
+{
+       _FP_FRAC_DECL_2(quo);
+       _FP_FRAC_DECL_2(rem);
+       _FP_FRAC_DECL_2(tmp);
+       unsigned long i, num_bits, bit;
+
+       _FP_FRAC_SET_2(rem, _FP_ZEROFRAC_2);
+       _FP_FRAC_SET_2(quo, _FP_ZEROFRAC_2);
+
+       if (_FP_FRAC_ZEROP_2(divisor))
+               goto out;
+
+       if (_FP_FRAC_GT_2(divisor, dividend)) {
+               _FP_FRAC_COPY_2(rem, dividend);
+               goto out;
+       }
+
+       if (_FP_FRAC_EQ_2(divisor, dividend)) {
+               __FP_FRAC_SET_2(quo, 0, 1);
+               goto out;
+       }
+
+       num_bits = 128;
+       while (1) {
+               bit = _FP_FRAC_NEGP_2(dividend);
+               _FP_FRAC_COPY_2(tmp, rem);
+               _FP_FRAC_SLL_2(tmp, 1);
+               _FP_FRAC_LOW_2(tmp) |= bit;
+               if (! _FP_FRAC_GE_2(tmp, divisor))
+                       break;
+               _FP_FRAC_COPY_2(rem, tmp);
+               _FP_FRAC_SLL_2(dividend, 1);
+               num_bits--;
+       }
+
+       for (i = 0; i < num_bits; i++) {
+               bit = _FP_FRAC_NEGP_2(dividend);
+               _FP_FRAC_SLL_2(rem, 1);
+               _FP_FRAC_LOW_2(rem) |= bit;
+               _FP_FRAC_SUB_2(tmp, rem, divisor);
+               bit = _FP_FRAC_NEGP_2(tmp);
+               _FP_FRAC_SLL_2(dividend, 1);
+               _FP_FRAC_SLL_2(quo, 1);
+               if (!bit) {
+                       _FP_FRAC_LOW_2(quo) |= 1;
+                       _FP_FRAC_COPY_2(rem, tmp);
+               }
+       }
+
+out:
+       *quot = quo_f1;
+       *remd = rem_f1;
+       return;
+}
+
+/*
+ * Emulate the floating point instruction at address PC.  Returns 0 if
+ * emulation fails.  Notice that the kernel does not and cannot use FP
+ * regs.  This is good because it means that instead of
+ * saving/restoring all fp regs, we simply stick the result of the
+ * operation into the appropriate register.
+ */
+long
+alpha_fp_emul (unsigned long pc)
+{
+       FP_DECL_EX;
+       FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
+       FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
+
+       unsigned long fa, fb, fc, func, mode, src;
+       unsigned long fpcw = current->thread.flags;
+       unsigned long res, va, vb, vc, fpcr;
+       __u32 insn;
+
+       MOD_INC_USE_COUNT;
+
+       get_user(insn, (__u32*)pc);
+       fc     = (insn >>  0) & 0x1f;   /* destination register */
+       fb     = (insn >> 16) & 0x1f;
+       fa     = (insn >> 21) & 0x1f;
+       func   = (insn >>  5) & 0xf;
+       src    = (insn >>  9) & 0x3;
+       mode   = (insn >> 11) & 0x3;
+       
+       fpcr = rdfpcr();
+
+       if (mode == 3) {
+           /* Dynamic -- get rounding mode from fpcr.  */
+           mode = (fpcr >> FPCR_DYN_SHIFT) & 3;
+       }
+
+       switch (src) {
+       case FOP_SRC_S:
+               va = alpha_read_fp_reg_s(fa);
+               vb = alpha_read_fp_reg_s(fb);
+               
+               FP_UNPACK_SP(SA, &va);
+               FP_UNPACK_SP(SB, &vb);
+
+               switch (func) {
+               case FOP_FNC_SUBx:
+                       FP_SUB_S(SR, SA, SB);
+                       goto pack_s;
+
+               case FOP_FNC_ADDx:
+                       FP_ADD_S(SR, SA, SB);
+                       goto pack_s;
+
+               case FOP_FNC_MULx:
+                       FP_MUL_S(SR, SA, SB);
+                       goto pack_s;
+
+               case FOP_FNC_DIVx:
+                       FP_DIV_S(SR, SA, SB);
+                       goto pack_s;
+
+               case FOP_FNC_SQRTx:
+                       FP_SQRT_S(SR, SB);
+                       goto pack_s;
+               }
+               goto bad_insn;
+
+       case FOP_SRC_T:
+               va = alpha_read_fp_reg(fa);
+               vb = alpha_read_fp_reg(fb);
+
+               if ((func & ~3) == FOP_FNC_CMPxUN) {
+                       FP_UNPACK_RAW_DP(DA, &va);
+                       FP_UNPACK_RAW_DP(DB, &vb);
+                       if (!DA_e && !_FP_FRAC_ZEROP_1(DA)) {
+                               FP_SET_EXCEPTION(FP_EX_DENORM);
+                               if (FP_DENORM_ZERO)
+                                       _FP_FRAC_SET_1(DA, _FP_ZEROFRAC_1);
+                       }
+                       if (!DB_e && !_FP_FRAC_ZEROP_1(DB)) {
+                               FP_SET_EXCEPTION(FP_EX_DENORM);
+                               if (FP_DENORM_ZERO)
+                                       _FP_FRAC_SET_1(DB, _FP_ZEROFRAC_1);
+                       }
+                       FP_CMP_D(res, DA, DB, 3);
+                       vc = 0x4000000000000000;
+                       /* CMPTEQ, CMPTUN don't trap on QNaN, while CMPTLT and CMPTLE do */
+                       if (res == 3 && ((func & 3) >= 2 || FP_ISSIGNAN_D(DA) || FP_ISSIGNAN_D(DB)))
+                               FP_SET_EXCEPTION(FP_EX_INVALID);
+                       switch (func) {
+                       case FOP_FNC_CMPxUN: if (res != 3) vc = 0; break;
+                       case FOP_FNC_CMPxEQ: if (res) vc = 0; break;
+                       case FOP_FNC_CMPxLT: if (res != -1) vc = 0; break;
+                       case FOP_FNC_CMPxLE: if ((long)res > 0) vc = 0; break;
+                       }
+                       goto done_d;
+               }
+
+               FP_UNPACK_DP(DA, &va);
+               FP_UNPACK_DP(DB, &vb);
+
+               switch (func) {
+               case FOP_FNC_SUBx:
+                       FP_SUB_D(DR, DA, DB);
+                       goto pack_d;
+
+               case FOP_FNC_ADDx:
+                       FP_ADD_D(DR, DA, DB);
+                       goto pack_d;
+
+               case FOP_FNC_MULx:
+                       FP_MUL_D(DR, DA, DB);
+                       goto pack_d;
+
+               case FOP_FNC_DIVx:
+                       FP_DIV_D(DR, DA, DB);
+                       goto pack_d;
+
+               case FOP_FNC_SQRTx:
+                       FP_SQRT_D(DR, DB);
+                       goto pack_d;
+
+               case FOP_FNC_CVTxS:
+                       /* It is irritating that DEC encoded CVTST with
+                          SRC == T_floating.  It is also interesting that
+                          the bit used to tell the two apart is /U... */
+                       if (insn & 0x2000) {
+                               FP_CONV(S,D,1,1,SR,DB);
+                               goto pack_s;
+                       } else {
+                               /* CVTST need do nothing else but copy the
+                                  bits and repack.  */
+                               DR_c = DB_c;
+                               DR_s = DB_s;
+                               DR_e = DB_e;
+                               DR_f = DB_f;
+                               goto pack_d;
+                       }
+
+               case FOP_FNC_CVTxQ:
+                       if (DB_c == FP_CLS_NAN && (_FP_FRAC_HIGH_RAW_D(DB) & _FP_QNANBIT_D))
+                               vc = 0; /* AAHB Table B-2 sais QNaN should not trigger INV */
+                       else
+                               FP_TO_INT_ROUND_D(vc, DB, 64, 2);
+                       goto done_d;
+               }
+               goto bad_insn;
+
+       case FOP_SRC_Q:
+               vb = alpha_read_fp_reg(fb);
+
+               switch (func) {
+               case FOP_FNC_CVTQL:
+                       /* Notice: We can get here only due to an integer
+                          overflow.  Such overflows are reported as invalid
+                          ops.  We return the result the hw would have
+                          computed.  */
+                       vc = ((vb & 0xc0000000) << 32 | /* sign and msb */
+                             (vb & 0x3fffffff) << 29); /* rest of the int */
+                       FP_SET_EXCEPTION (FP_EX_INVALID);
+                       goto done_d;
+
+               case FOP_FNC_CVTxS:
+                       FP_FROM_INT_S(SR, ((long)vb), 64, long);
+                       goto pack_s;
+
+               case FOP_FNC_CVTxT:
+                       FP_FROM_INT_D(DR, ((long)vb), 64, long);
+                       goto pack_d;
+               }
+               goto bad_insn;
+       }
+       goto bad_insn;
+
+pack_s:
+       FP_PACK_SP(&vc, SR);
+       alpha_write_fp_reg_s(fc, vc);
+       goto done;
+
+pack_d:
+       FP_PACK_DP(&vc, DR);
+done_d:
+       alpha_write_fp_reg(fc, vc);
+       goto done;
+
+       /*
+        * Take the appropriate action for each possible
+        * floating-point result:
+        *
+        *      - Set the appropriate bits in the FPCR
+        *      - If the specified exception is enabled in the FPCR,
+        *        return.  The caller (entArith) will dispatch
+        *        the appropriate signal to the translated program.
+        *
+        * In addition, properly track the exception state in software
+        * as described in the Alpha Architectre Handbook section 4.7.7.3.
+        */
+done:
+       if (_fex) {
+               /* Record exceptions in software control word.  */
+               current->thread.flags
+                 = fpcw |= (_fex << IEEE_STATUS_TO_EXCSUM_SHIFT);
+
+               /* Update hardware control register */
+               fpcr &= (~FPCR_MASK | FPCR_DYN_MASK);
+               fpcr |= ieee_swcr_to_fpcr(fpcw);
+               wrfpcr(fpcr);
+
+               /* Do we generate a signal?  */
+               if (_fex & fpcw & IEEE_TRAP_ENABLE_MASK) {
+                       MOD_DEC_USE_COUNT;
+                       return 0;
+               }
+       }
+
+       /* We used to write the destination register here, but DEC FORTRAN
+          requires that the result *always* be written... so we do the write
+          immediately after the operations above.  */
+
+       MOD_DEC_USE_COUNT;
+       return 1;
+
+bad_insn:
+       printk(KERN_ERR "alpha_fp_emul: Invalid FP insn %#x at %#lx\n",
+              insn, pc);
+       MOD_DEC_USE_COUNT;
+       return 0;
+}
+
+long
+alpha_fp_emul_imprecise (struct pt_regs *regs, unsigned long write_mask)
+{
+       unsigned long trigger_pc = regs->pc - 4;
+       unsigned long insn, opcode, rc;
+
+       MOD_INC_USE_COUNT;
+
+       /*
+        * Turn off the bits corresponding to registers that are the
+        * target of instructions that set bits in the exception
+        * summary register.  We have some slack doing this because a
+        * register that is the target of a trapping instruction can
+        * be written at most once in the trap shadow.
+        *
+        * Branches, jumps, TRAPBs, EXCBs and calls to PALcode all
+        * bound the trap shadow, so we need not look any further than
+        * up to the first occurrence of such an instruction.
+        */
+       while (write_mask) {
+               get_user(insn, (__u32*)(trigger_pc));
+               opcode = insn >> 26;
+               rc = insn & 0x1f;
+
+               switch (opcode) {
+                     case OPC_PAL:
+                     case OPC_JSR:
+                     case 0x30 ... 0x3f:       /* branches */
+                       MOD_DEC_USE_COUNT;
+                       return 0;
+
+                     case OPC_MISC:
+                       switch (insn & 0xffff) {
+                             case MISC_TRAPB:
+                             case MISC_EXCB:
+                               MOD_DEC_USE_COUNT;
+                               return 0;
+
+                             default:
+                               break;
+                       }
+                       break;
+
+                     case OPC_INTA:
+                     case OPC_INTL:
+                     case OPC_INTS:
+                     case OPC_INTM:
+                       write_mask &= ~(1UL << rc);
+                       break;
+
+                     case OPC_FLTC:
+                     case OPC_FLTV:
+                     case OPC_FLTI:
+                     case OPC_FLTL:
+                       write_mask &= ~(1UL << (rc + 32));
+                       break;
+               }
+               if (!write_mask) {
+                       if (alpha_fp_emul(trigger_pc)) {
+                               /* re-execute insns in trap-shadow: */
+                               regs->pc = trigger_pc + 4;
+                               MOD_DEC_USE_COUNT;
+                               return 1;
+                       }
+                       break;
+               }
+               trigger_pc -= 4;
+       }
+       MOD_DEC_USE_COUNT;
+       return 0;
+}
diff --git a/arch/alpha/math-emu/sfp-util.h b/arch/alpha/math-emu/sfp-util.h
new file mode 100644 (file)
index 0000000..7a6a8cf
--- /dev/null
@@ -0,0 +1,40 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/fpu.h>
+
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  ((sl) = (al) + (bl), (sh) = (ah) + (bh) + ((sl) < (al)))
+
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  ((sl) = (al) - (bl), (sh) = (ah) - (bh) - ((al) < (bl)))
+
+#define umul_ppmm(wh, wl, u, v)                        \
+  __asm__ ("mulq %2,%3,%1; umulh %2,%3,%0"     \
+          : "=r" ((UDItype)(wh)),              \
+            "=&r" ((UDItype)(wl))              \
+          : "r" ((UDItype)(u)),                \
+            "r" ((UDItype)(v)))
+
+extern void udiv128(unsigned long, unsigned long,
+                   unsigned long, unsigned long,
+                   unsigned long *,
+                   unsigned long *);
+
+#define udiv_qrnnd(q, r, n1, n0, d)            \
+  do {                                         \
+    unsigned long xr, xi;                      \
+    udiv128((n0), (n1), 0, (d), &xr, &xi);     \
+    (q) = xr;                                  \
+    (r) = xi;                                  \
+  } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1  
+
+#define abort()                        goto bad_insn
+
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN -1
+#endif
+#define __BYTE_ORDER __LITTLE_ENDIAN
index 4e6c8a848cdcd549524fa6aa4fbe934cd3b00096..4bbe50e93d525875809e16fdd6b68f0e4909c3ac 100644 (file)
@@ -273,12 +273,42 @@ srm_paging_stop (void)
 }
 #endif
 
+static void printk_memory_info(void)
+{
+       unsigned long codesize, reservedpages, datasize, initsize, tmp;
+       extern int page_is_ram(unsigned long) __init;
+       extern char _text, _etext, _data, _edata;
+       extern char __init_begin, __init_end;
+
+       /* printk all informations */
+       reservedpages = 0;
+       for (tmp = 0; tmp < max_low_pfn; tmp++)
+               /*
+                * Only count reserved RAM pages
+                */
+               if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
+                       reservedpages++;
+
+       codesize =  (unsigned long) &_etext - (unsigned long) &_text;
+       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
+       initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+       printk("Memory: %luk/%luk available (%luk kernel code, %luk reserved, %luk data, %luk init)\n",
+              (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+              max_mapnr << (PAGE_SHIFT-10),
+              codesize >> 10,
+              reservedpages << (PAGE_SHIFT-10),
+              datasize >> 10,
+              initsize >> 10);
+}
+
 void
 mem_init(void)
 {
        max_mapnr = num_physpages = max_low_pfn;
        totalram_pages += free_all_bootmem();
-       printk("Memory: %luk available\n", totalram_pages << (PAGE_SHIFT-10));
+
+       printk_memory_info();
 }
 
 void
index 539e53c0ebf4c7c05784daff56dbd5b4d19ea32c..2c81731b963b2f614629a901a49da51a206438ee 100644 (file)
@@ -156,7 +156,7 @@ endif
 ifeq ($(CONFIG_ARCH_ACORN),y)
 SUBDIRS                += drivers/acorn
 DRIVERS                += drivers/acorn/block/acorn-block.a
-DRIVERS                += drivers/acorn/char/acorn-char.a
+DRIVERS                += drivers/acorn/char/acorn-char.o
 DRIVERS                += drivers/acorn/net/acorn-net.a
 DRIVERS                += drivers/acorn/scsi/acorn-scsi.a
 endif
index d63f657a28c9105d3a4101a3ae360b446e3c20de..a2e5e1db0e5e7c0ad38623d998a45ba914ee993a 100644 (file)
@@ -203,6 +203,15 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
        }
 }
 
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
+{
+       ranges->io_start -= bus->resource[0]->start;
+       ranges->io_end -= bus->resource[0]->start;
+       ranges->mem_start -= bus->resource[1]->start;
+       ranges->mem_end -= bus->resource[1]->start;
+}
+
 static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
 {
        return 0;
index 5c4a606b0fb4ff6d732afd47bfc027f6644a6990..c7d1da3e19f1eaebd7da8bb0c82f8b44ef89e3bc 100644 (file)
@@ -43,7 +43,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
 
 #ifdef CONFIG_ARCH_ARC
index de070236ddd7d6c99916a5502681ae30ac9da43f..6d4107ede00486954ce56026e6563e2747ddf86d 100644 (file)
@@ -899,7 +899,7 @@ __stubs_end:
                b       __real_stubs_start + (vector_IRQ - __stubs_start)
                b       __real_stubs_start + (vector_FIQ - __stubs_start)
 
-ENTRY(trap_init)
+ENTRY(__trap_init)
                stmfd   sp!, {r4 - r6, lr}
 
                adr     r1, .LCvectors                  @ set up the vectors
index 7a16832c7f813cac8f53625a7f6865972298b97f..6597de1846a3194b109f54d0480612d914d1630d 100644 (file)
@@ -42,7 +42,7 @@
 
 #include <asm/fiq.h>
 #include <asm/io.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
index 07a52ba8e4c5ef833302a5477232cf685daaaecf..349b060d28e7ff2ef364fa7a83435bbb33a22e3b 100644 (file)
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 
+unsigned long
+resource_fixup(struct pci_dev * dev, struct resource * res,
+              unsigned long start, unsigned long size)
+{
+       return start;
+}
+
 #ifdef CONFIG_CPU_32
 asmlinkage int sys_iopl(unsigned long turn_on)
 {
index ccc8c2461bd474999760a1dace51ec7d78a74c3a..9afacbde35aa805b2a6d27df8c25bde88ed13c21 100644 (file)
@@ -5,10 +5,6 @@
  *  Origional Copyright (C) 1995  Linus Torvalds
  */
 
-/*
- * This file handles the architecture-dependent parts of process handling..
- */
-
 #include <stdarg.h>
 
 #include <linux/errno.h>
@@ -39,7 +35,7 @@ extern char *processor_modes[];
 
 asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
 
-static int hlt_counter=0;
+static int hlt_counter;
 
 void disable_hlt(void)
 {
@@ -51,6 +47,21 @@ void enable_hlt(void)
        hlt_counter--;
 }
 
+static int __init nohlt_setup(char *__unused)
+{
+       hlt_counter = 1;
+       return 0;
+}
+
+static int __init hlt_setup(char *__unused)
+{
+       hlt_counter = 0;
+       return 0;
+}
+
+__setup("nohlt", nohlt_setup);
+__setup("hlt", hlt_setup);
+
 /*
  * The idle loop on an ARM...
  */
@@ -93,6 +104,7 @@ void machine_restart(char * __unused)
 
        mdelay(1000);
        printk("Reboot failed -- System halted\n");
+       cli();
        while (1);
 }
 
@@ -110,18 +122,18 @@ void show_regs(struct pt_regs * regs)
 
        flags = condition_codes(regs);
 
-       printk( "pc : [<%08lx>]    lr : [<%08lx>]\n"
-               "sp : %08lx  ip : %08lx  fp : %08lx\n",
+       printk("pc : [<%08lx>]    lr : [<%08lx>]\n"
+              "sp : %08lx  ip : %08lx  fp : %08lx\n",
                instruction_pointer(regs),
                regs->ARM_lr, regs->ARM_sp,
                regs->ARM_ip, regs->ARM_fp);
-       printk( "r10: %08lx  r9 : %08lx  r8 : %08lx\n",
+       printk("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
                regs->ARM_r10, regs->ARM_r9,
                regs->ARM_r8);
-       printk( "r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
+       printk("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
                regs->ARM_r7, regs->ARM_r6,
                regs->ARM_r5, regs->ARM_r4);
-       printk( "r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
+       printk("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
                regs->ARM_r3, regs->ARM_r2,
                regs->ARM_r1, regs->ARM_r0);
        printk("Flags: %c%c%c%c",
index 7a33e7e23f0304db9bb368abd75bd8e51b9606b3..d336af23c484fa95108074eadccff518d3530bcc 100644 (file)
@@ -3,12 +3,6 @@
  *
  *  Copyright (C) 1995-1999 Russell King
  */
-
-/*
- * This file obtains various parameters about the system that the kernel
- * is running on.
- */
-
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #define CONFIG_CMDLINE ""
 #endif
 
-#ifndef PARAMS_BASE
-#define PARAMS_BASE NULL
-#endif
-
-extern void reboot_setup(char *str, int *ints);
+extern void reboot_setup(char *str);
 extern void disable_hlt(void);
 extern int root_mountflags;
 extern int _stext, _text, _etext, _edata, _end;
@@ -61,6 +51,20 @@ unsigned int number_mfm_drives;
 
 struct meminfo meminfo;
 
+struct machine_desc {
+       const char      *name;          /* architecture name    */
+       unsigned int    param_offset;   /* parameter page       */
+       unsigned int    reserve_lp0 :1; /* never has lp0        */
+       unsigned int    reserve_lp1 :1; /* never has lp1        */
+       unsigned int    reserve_lp2 :1; /* never has lp2        */
+       unsigned int    broken_hlt  :1; /* hlt is broken        */
+       unsigned int    soft_reboot :1; /* soft reboot          */
+       unsigned int    video_start;    /* start of video RAM   */
+       unsigned int    video_end;      /* end of video RAM     */
+       void            (*fixup)(struct machine_desc *,
+                                struct param_struct *, char **);
+};
+
 #ifdef MULTI_CPU
 struct processor processor;
 #endif
@@ -81,6 +85,7 @@ char elf_platform[ELF_PLATFORM_SIZE];
 char saved_command_line[COMMAND_LINE_SIZE];
 
 static struct proc_info_item proc_info;
+static const char *machine_name;
 static char command_line[COMMAND_LINE_SIZE] = { 0, };
 
 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
@@ -91,16 +96,14 @@ static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '
  * Standard memory resources
  */
 static struct resource mem_res[] = {
-       { "System RAM",  0,     0,     IORESOURCE_MEM | IORESOURCE_BUSY },
        { "Video RAM",   0,     0,     IORESOURCE_MEM                   },
        { "Kernel code", 0,     0,     IORESOURCE_MEM                   },
        { "Kernel data", 0,     0,     IORESOURCE_MEM                   }
 };
 
-#define system_ram  mem_res[0]
-#define video_ram   mem_res[1]
-#define kernel_code mem_res[2]
-#define kernel_data mem_res[3]
+#define video_ram   mem_res[0]
+#define kernel_code mem_res[1]
+#define kernel_data mem_res[2]
 
 static struct resource io_res[] = {
        { "reserved",    0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
@@ -140,6 +143,10 @@ static void __init setup_processor(void)
 
 #ifdef MULTI_CPU
        processor = *list->proc;
+
+       printk("Processor: %s %s revision %d\n",
+              proc_info.manufacturer, proc_info.cpu_name,
+              (int)processor_id & 15);
 #endif
 
        sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
@@ -218,10 +225,7 @@ static void __init
 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
 {
 #ifdef CONFIG_BLK_DEV_RAM
-       extern int rd_doload;
-       extern int rd_prompt;
-       extern int rd_image_start;
-       extern int rd_size;
+       extern int rd_doload, rd_prompt, rd_image_start, rd_size;
 
        rd_image_start = image_start;
        rd_prompt = prompt;
@@ -309,69 +313,76 @@ static void __init setup_bootmem(void)
 #endif
 }
 
-static void __init request_standard_resources(void)
+static void __init request_standard_resources(struct machine_desc *mdesc)
 {
-       kernel_code.start  = __virt_to_bus((unsigned long) &_text);
-       kernel_code.end    = __virt_to_bus((unsigned long) &_etext - 1);
-       kernel_data.start  = __virt_to_bus((unsigned long) &_etext);
-       kernel_data.end    = __virt_to_bus((unsigned long) &_edata - 1);
-       system_ram.start   = __virt_to_bus(PAGE_OFFSET);
-       system_ram.end     = __virt_to_bus(meminfo.end + PAGE_OFFSET - 1);
-
-       request_resource(&iomem_resource, &system_ram);
-       request_resource(&system_ram, &kernel_code);
-       request_resource(&system_ram, &kernel_data);
-
-       if (video_ram.start != video_ram.end)
+       struct resource *res;
+       int i;
+
+       kernel_code.start  = __virt_to_bus(init_mm.start_code);
+       kernel_code.end    = __virt_to_bus(init_mm.end_code - 1);
+       kernel_data.start  = __virt_to_bus(init_mm.end_code);
+       kernel_data.end    = __virt_to_bus(init_mm.brk - 1);
+
+       for (i = 0; i < meminfo.nr_banks; i++) {
+               unsigned long virt_start, virt_end;
+
+               if (meminfo.bank[i].size == 0)
+                       continue;
+
+               virt_start = __phys_to_virt(meminfo.bank[i].start);
+               virt_end   = virt_start + meminfo.bank[i].size - 1;
+
+               res = alloc_bootmem(sizeof(*res));
+               res->name  = "System RAM";
+               res->start = __virt_to_bus(virt_start);
+               res->end   = __virt_to_bus(virt_end);
+               res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+               request_resource(&iomem_resource, res);
+
+               if (kernel_code.start >= res->start &&
+                   kernel_code.end <= res->end)
+                       request_resource(res, &kernel_code);
+               if (kernel_data.start >= res->start &&
+                   kernel_data.end <= res->end)
+                       request_resource(res, &kernel_data);
+       }
+
+       if (mdesc->video_start) {
+               video_ram.start = mdesc->video_start;
+               video_ram.end   = mdesc->video_end;
                request_resource(&iomem_resource, &video_ram);
+       }
 
        /*
         * Some machines don't have the possibility of ever
-        * possessing LPT1 (lp0) and LPT3 (lp2)
+        * possessing lp0, lp1 or lp2
         */
-       if (machine_is_ebsa110() || machine_is_riscpc() ||
-           machine_is_netwinder())
+       if (mdesc->reserve_lp0)
                request_resource(&ioport_resource, &lp0);
-       if (machine_is_riscpc())
+       if (mdesc->reserve_lp1)
                request_resource(&ioport_resource, &lp1);
-       if (machine_is_ebsa110() || machine_is_netwinder())
+       if (mdesc->reserve_lp2)
                request_resource(&ioport_resource, &lp2);
 }
 
-void __init setup_arch(char **cmdline_p)
+/*
+ * Architecture specific fixups.  This is where any
+ * parameters in the params struct are fixed up, or
+ * any additional architecture specific information
+ * is pulled from the params struct.
+ */
+static void __init
+fixup_acorn(struct machine_desc *desc, struct param_struct *params,
+           char **cmdline)
 {
-       struct param_struct *params = (struct param_struct *)PARAMS_BASE;
-       char *from = default_command_line;
-
-#if defined(CONFIG_ARCH_ARC)
-       __machine_arch_type = MACH_TYPE_ARCHIMEDES;
-#elif defined(CONFIG_ARCH_A5K)
-       __machine_arch_type = MACH_TYPE_A5K;
-#endif
-
-       setup_processor();
-
-       /*
-        * Defaults
-        */
-       ROOT_DEV = MKDEV(0, 255);
-       setup_ramdisk(1, 1, 0, 0);
-
-       /*
-        * Add your machine dependencies here
-        */
-       switch (machine_arch_type) {
-       case MACH_TYPE_EBSA110:
-               /* EBSA110 locks if we execute 'wait for interrupt' */
-               disable_hlt();
-               if (params && params->u1.s.page_size != PAGE_SIZE)
-                       params = NULL;
-               break;
-
 #ifdef CONFIG_ARCH_ACORN
-#ifdef CONFIG_ARCH_RPC
-       case MACH_TYPE_RISCPC:
-               /* RiscPC can't handle half-word loads and stores */
+       int i;
+
+       if (machine_is_riscpc()) {
+               /*
+                * RiscPC can't handle half-word loads and stores
+                */
                elf_hwcap &= ~HWCAP_HALF;
 
                switch (params->u1.s.pages_in_vram) {
@@ -382,106 +393,219 @@ void __init setup_arch(char **cmdline_p)
                default:
                        break;
                }
-               {
-                       int i;
-
-                       for (i = 0; i < 4; i++) {
-                               meminfo.bank[i].start = i << 26;
-                               meminfo.bank[i].size  =
-                                       params->u1.s.pages_in_bank[i] *
-                                       params->u1.s.page_size;
-                       }
-                       meminfo.nr_banks = 4;
+
+               if (vram_size) {
+                       desc->video_start = 0x02000000;
+                       desc->video_end   = 0x02000000 + vram_size;
                }
-#endif
-       case MACH_TYPE_ARCHIMEDES:
-       case MACH_TYPE_A5K:
-               memc_ctrl_reg     = params->u1.s.memc_control_reg;
-               number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
-               break;
-#endif
 
-       case MACH_TYPE_EBSA285:
-               if (params) {
-                       ORIG_X           = params->u1.s.video_x;
-                       ORIG_Y           = params->u1.s.video_y;
-                       ORIG_VIDEO_COLS  = params->u1.s.video_num_cols;
-                       ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
-                       video_ram.start  = 0x0a0000;
-                       video_ram.end    = 0x0bffff;
+               for (i = 0; i < 4; i++) {
+                       meminfo.bank[i].start = i << 26;
+                       meminfo.bank[i].size  =
+                               params->u1.s.pages_in_bank[i] *
+                               params->u1.s.page_size;
                }
-               break;
+               meminfo.nr_banks = 4;
+       }
+       memc_ctrl_reg     = params->u1.s.memc_control_reg;
+       number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
+#endif
+}
+
+static void __init
+fixup_ebsa285(struct machine_desc *desc, struct param_struct *params,
+             char **cmdline)
+{
+       ORIG_X           = params->u1.s.video_x;
+       ORIG_Y           = params->u1.s.video_y;
+       ORIG_VIDEO_COLS  = params->u1.s.video_num_cols;
+       ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
+}
 
-       case MACH_TYPE_CO285:
-               {
+/*
+ * Older NeTTroms either do not provide a parameters
+ * page, or they don't supply correct information in
+ * the parameter page.
+ */
+static void __init
+fixup_netwinder(struct machine_desc *desc, struct param_struct *params,
+               char **cmdline)
+{
+       if (params->u1.s.nr_pages != 0x2000 &&
+           params->u1.s.nr_pages != 0x4000) {
+               printk(KERN_WARNING "Warning: bad NeTTrom parameters "
+                      "detected, using defaults\n");
+
+               params->u1.s.nr_pages = 0x2000; /* 32MB */
+               params->u1.s.ramdisk_size = 0;
+               params->u1.s.flags = FLAG_READONLY;
+               params->u1.s.initrd_start = 0;
+               params->u1.s.initrd_size = 0;
+               params->u1.s.rd_start = 0;
+       }
+}
+
+/*
+ * CATS uses soft-reboot by default, since
+ * hard reboots fail on early boards.
+ */
+static void __init
+fixup_cats(struct machine_desc *desc, struct param_struct *params,
+          char **cmdline)
+{
+       ORIG_VIDEO_LINES  = 25;
+       ORIG_VIDEO_POINTS = 16;
+       ORIG_Y = 24;
+}
+
+static void __init
+fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
+               char **cmdline)
+{
 #if 0
-                       extern unsigned long boot_memory_end;
-                       extern char boot_command_line[];
+       if (machine_is_co285()) {
+               extern unsigned long boot_memory_end;
+               extern char boot_command_line[];
 
-                       from = boot_command_line;
-                       memory_end = boot_memory_end;
-#endif
-                       params = NULL;
-               }
-               break;
+               meminfo.nr_banks      = 1;
+               meminfo.bank[0].start = PHYS_OFFSET;
+               meminfo.bank[0].size  = boot_memory_end;
 
-       case MACH_TYPE_CATS:
-               /* CATS uses soft-reboot by default, since hard reboots
-                * fail on early boards.
-                */
-               reboot_setup("s", NULL);
-               params = NULL;
-               ORIG_VIDEO_LINES  = 25;
-               ORIG_VIDEO_POINTS = 16;
-               ORIG_Y = 24;
-               video_ram.start = 0x0a0000;
-               video_ram.end   = 0x0bffff;
-               break;
+               *cmdline = boot_command_line;
+       }
+#endif
+}
 
-       case MACH_TYPE_NETWINDER:
-               /*
-                * to be fixed in a future NeTTrom
-                */
-               if (params->u1.s.page_size == PAGE_SIZE) {
-                       if (params->u1.s.nr_pages != 0x2000 &&
-                           params->u1.s.nr_pages != 0x4000) {
-                               printk("Warning: bad NeTTrom parameters detected, using defaults\n");
-                               /*
-                                * This stuff doesn't appear to be initialised
-                                * properly by NeTTrom 2.0.6 and 2.0.7
-                                */
-                               params->u1.s.nr_pages = 0x2000; /* 32MB */
-                               params->u1.s.ramdisk_size = 0;
-                               params->u1.s.flags = FLAG_READONLY;
-                               params->u1.s.initrd_start = 0;
-                               params->u1.s.initrd_size = 0;
-                               params->u1.s.rd_start = 0;
-                       }
-               } else {
-                       printk("Warning: no NeTTrom parameter page detected, using "
-                              "compiled-in settings\n");
-                       params = NULL;
-               }
-               video_ram.start = 0x0a0000;
-               video_ram.end   = 0x0bffff;
-               break;
+#define NO_PARAMS      0
+#define NO_VIDEO       0, 0
 
-       default:
-               break;
+/*
+ * This is the list of all architectures supported by
+ * this kernel.  This should be integrated with the list
+ * in head-armv.S.
+ */
+static struct machine_desc machine_desc[] __initdata = {
+       { "EBSA110",            /* RMK                  */
+               0x00000400,
+               NO_VIDEO,
+               1, 0, 1, 1, 1,
+               NULL
+       }, { "Acorn-RiscPC",    /* RMK                  */
+               0x10000100,
+               NO_VIDEO,
+               1, 1, 0, 0, 0,
+               fixup_acorn
+       }, { "unknown",
+               NO_PARAMS,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               NULL
+       }, { "Nexus-FTV/PCI",   /* Philip Blundell      */
+               NO_PARAMS,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               NULL
+       }, { "EBSA285",         /* RMK                  */
+               0x00000100,
+               0x000a0000, 0x000bffff,
+               0, 0, 0, 0, 0,
+               fixup_ebsa285
+       }, { "Rebel-NetWinder", /* RMK                  */
+               0x00000100,
+               0x000a0000, 0x000bffff,
+               1, 0, 1, 0, 0,
+               fixup_netwinder
+       }, { "Chalice-CATS",    /* Philip Blundell      */
+               NO_PARAMS,
+               0x000a0000, 0x000bffff,
+               0, 0, 0, 0, 1,
+               fixup_cats
+       }, { "unknown-TBOX",    /* Philip Blundell      */
+               NO_PARAMS,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               NULL
+       }, { "co-EBSA285",      /* Mark van Doesburg    */
+               NO_PARAMS,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               fixup_coebsa285
+       }, { "CL-PS7110",       /* Werner Almesberger   */
+               NO_PARAMS,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               NULL
+       }, { "Acorn-Archimedes",/* RMK/DAG              */
+               0x0207c000,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               fixup_acorn
+       }, { "Acorn-A5000",     /* RMK/PB               */
+               0x0207c000,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               fixup_acorn
+       }, { "Etoile",          /* Alex de Vries        */
+               NO_PARAMS,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               NULL
+       }, { "LaCie_NAS",       /* Benjamin Herrenschmidt */
+               NO_PARAMS,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               NULL
+       }, { "CL-PS7500",       /* Philip Blundell      */
+               NO_PARAMS,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               NULL
+       }, { "Shark",           /* Alexander Schulz     */
+               NO_PARAMS,
+               NO_VIDEO,
+               0, 0, 0, 0, 0,
+               NULL
        }
+};
+
+void __init setup_arch(char **cmdline_p)
+{
+       struct param_struct *params = NULL;
+       struct machine_desc *mdesc;
+       char *from = default_command_line;
+
+#if defined(CONFIG_ARCH_ARC)
+       __machine_arch_type = MACH_TYPE_ARCHIMEDES;
+#elif defined(CONFIG_ARCH_A5K)
+       __machine_arch_type = MACH_TYPE_A5K;
+#endif
+
+       setup_processor();
+
+       ROOT_DEV = MKDEV(0, 255);
+
+       mdesc = machine_desc + machine_arch_type;
+       machine_name = mdesc->name;
+
+       if (mdesc->broken_hlt)
+               disable_hlt();
+
+       if (mdesc->soft_reboot)
+               reboot_setup("s");
+
+       if (mdesc->param_offset)
+               params = phys_to_virt(mdesc->param_offset);
+
+       if (mdesc->fixup)
+               mdesc->fixup(mdesc, params, &from);
 
        if (params && params->u1.s.page_size != PAGE_SIZE) {
-               printk("Warning: wrong page size configuration, "
+               printk(KERN_WARNING "Warning: bad configuration page, "
                       "trying to continue\n");
                params = NULL;
        }
 
        if (params) {
-               if (meminfo.nr_banks == 0) {
-                       meminfo.nr_banks      = 1;
-                       meminfo.bank[0].start = 0;
-                       meminfo.bank[0].size  = params->u1.s.nr_pages << PAGE_SHIFT;
-               }
                ROOT_DEV           = to_kdev_t(params->u1.s.rootdev);
                system_rev         = params->u1.s.system_rev;
                system_serial_low  = params->u1.s.system_serial_low;
@@ -504,7 +628,10 @@ void __init setup_arch(char **cmdline_p)
        if (meminfo.nr_banks == 0) {
                meminfo.nr_banks      = 1;
                meminfo.bank[0].start = 0;
-               meminfo.bank[0].size  = MEM_SIZE;
+               if (params)
+                       meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT;
+               else
+                       meminfo.bank[0].size = MEM_SIZE;
        }
 
        init_mm.start_code = (unsigned long) &_text;
@@ -512,12 +639,11 @@ void __init setup_arch(char **cmdline_p)
        init_mm.end_data   = (unsigned long) &_edata;
        init_mm.brk        = (unsigned long) &_end;
 
-       /* Save unparsed command line copy for /proc/cmdline */
        memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
        saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
        parse_cmdline(cmdline_p, from);
        setup_bootmem();
-       request_standard_resources();
+       request_standard_resources(mdesc);
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
@@ -528,26 +654,6 @@ void __init setup_arch(char **cmdline_p)
 #endif
 }
 
-static const char *machine_desc[] = {
-       /* Machine name         Allocater                       */
-       "EBSA110",              /* RMK                          */
-       "Acorn-RiscPC",         /* RMK                          */
-       "unknown",
-       "Nexus-FTV/PCI",        /* Philip Blundell              */
-       "EBSA285",              /* RMK                          */
-       "Rebel-NetWinder",      /* RMK                          */
-       "Chalice-CATS",         /* Philip Blundell              */
-       "unknown-TBOX",         /* Philip Blundell              */
-       "co-EBSA285",           /* Mark van Doesburg            */
-       "CL-PS7110",            /* Werner Almesberger           */
-       "Acorn-Archimedes",     /* RMK/DAG                      */
-       "Acorn-A5000",          /* RMK/PB                       */
-       "Etoile",               /* Alex de Vries                */
-       "LaCie_NAS",            /* Benjamin Herrenschmidt       */
-       "CL-PS7500",            /* Philip Blundell              */
-       "Shark"                 /* Alexander Schulz             */
-};
-
 int get_cpuinfo(char * buffer)
 {
        char *p = buffer;
@@ -560,8 +666,7 @@ int get_cpuinfo(char * buffer)
                     (loops_per_sec+2500) / 500000,
                     ((loops_per_sec+2500) / 5000) % 100);
 
-       p += sprintf(p, "Hardware\t: %s\n",
-                    machine_desc[machine_arch_type]);
+       p += sprintf(p, "Hardware\t: %s\n", machine_name);
 
        p += sprintf(p, "Revision\t: %04x\n",
                     system_rev);
index 038946e9c1ce291ad37370560dfe29ec55a0e117..7df72481149e8bb99bb872c5581003e0872903ee 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -423,3 +424,13 @@ asmlinkage void __div0(void)
        printk("Division by zero in kernel.\n");
        __backtrace();
 }
+
+void __init trap_init(void)
+{
+       extern void __trap_init(void);
+
+       __trap_init();
+#ifdef CONFIG_CPU_32
+       modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+#endif
+}
index 85c9698e3c21a5f05e8e8516f9c07d718e8a6b94..de9dc5c8a4f14287678a0aade7214341d0df2aa2 100644 (file)
@@ -244,6 +244,10 @@ void __init mem_init(void)
        unsigned int codepages, datapages, initpages;
        int i;
 
+       codepages = &_etext - &_text;
+       datapages = &_end - &_etext;
+       initpages = &__init_end - &__init_begin;
+
        max_mapnr   = max_low_pfn;
        high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
 
@@ -261,29 +265,28 @@ void __init mem_init(void)
         * Since our memory may not be contiguous, calculate the
         * real number of pages we have in this system
         */
+       printk("Memory:");
+
        num_physpages = 0;
-       for (i = 0; i < meminfo.nr_banks; i++)
+       for (i = 0; i < meminfo.nr_banks; i++) {
                num_physpages += meminfo.bank[i].size >> PAGE_SHIFT;
+               printk(" %ldMB", meminfo.bank[i].size >> 20);
+       }
 
-       codepages = (int)&_etext - &_text;
-       datapages = (int)&_end - &_etext;
-       initpages = (int)&__init_end - &__init_start;
-
-       printk("Memory: %luk/%luM available (%dK code, %dK data, %dK init)\n",
+       printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); 
+       printk("Memory: %luKB available (%dK code, %dK data, %dK init)\n",
                (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-               num_physpages >> (20 - PAGE_SHIFT),
-               codepages << (PAGE_SHIFT-10),
-               datapages << (PAGE_SHIFT-10),
-               initpages << (PAGE_SHIFT-10));
+               codepages >> 10, datapages >> 10, initpages >> 10);
 
-#ifdef CONFIG_CPU_26
-       if (max_mapnr <= 128) {
+       if (PAGE_SIZE >= 16384 && max_mapnr <= 128) {
                extern int sysctl_overcommit_memory;
-               /* On a machine this small we won't get anywhere without
-                  overcommit, so turn it on by default.  */
+               /*
+                * On a machine this small we won't get
+                * anywhere without overcommit, so turn
+                * it on by default.
+                */
                sysctl_overcommit_memory = 1;
        }
-#endif
 }
 
 static inline void free_area(unsigned long addr, unsigned long end, char *s)
@@ -333,6 +336,19 @@ void free_initmem(void)
        printk("\n");
 }
 
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+       for (; start < end; start += PAGE_SIZE) {
+               ClearPageReserved(mem_map + MAP_NR(start));
+               set_page_count(mem_map+MAP_NR(start), 1);
+               free_page(start);
+               totalram_pages++;
+       }
+       printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
 void si_meminfo(struct sysinfo *val)
 {
        val->totalram  = totalram_pages;
index f3296984efbf33ae6cdb967bcc2e8a5bdad24e9e..9b7630eedf06daf292c682cf48762bb49292199b 100644 (file)
@@ -24,6 +24,29 @@ extern unsigned long get_page_2k(int priority);
 extern void free_page_2k(unsigned long page);
 extern pte_t *get_bad_pte_table(void);
 
+/*
+ * These are useful for identifing cache coherency
+ * problems by allowing the cache or the cache and
+ * writebuffer to be turned off.  (Note: the write
+ * buffer should not be on and the cache off).
+ */
+static int __init nocache_setup(char *__unused)
+{
+       cr_alignment &= ~4;
+       cr_no_alignment &= ~4;
+       set_cr(cr_alignment);
+}
+
+static int __init nowrite_setup(char *__unused)
+{
+       cr_alignment &= ~(8|4);
+       cr_no_alignment &= ~(8|4);
+       set_cr(cr_alignment);
+}
+
+__setup("nocache", nocache_setup);
+__setup("nowb", nowrite_setup);
+
 /*
  * need to get a 16k page for level 1
  */
@@ -353,7 +376,7 @@ void __init create_memmap_holes(void)
 {
        unsigned int start_pfn, end_pfn = -1;
        struct page *pg = NULL;
-       unsigned int sz, i;
+       unsigned int i;
 
        for (i = 0; i < meminfo.nr_banks; i++) {
                if (meminfo.bank[i].size == 0)
index dcb5c10dcd19d21800a8f17c68b5f552583bc410..36a9d8b28fcaa8962d4d81d79611c5178f44028a 100644 (file)
@@ -270,9 +270,9 @@ _arm2_3_check_bugs:
                bics    pc, lr, #0x04000000             @ Clear FIQ disable bit
 
 armvlsi_name:  .asciz  "ARM/VLSI"
-_arm2_name:    .asciz  "arm2"
-_arm250_name:  .asciz  "arm250"
-_arm3_name:    .asciz  "arm3"
+_arm2_name:    .asciz  "ARM 2"
+_arm250_name:  .asciz  "ARM 250"
+_arm3_name:    .asciz  "ARM 3"
 
                .section ".text.init", #alloc, #execinstr
 /*
index b085c3c4e7031e78c9826ce68812e0e60bdb7aca..d453269d2ab50edf008d254e9d69e16539db6b69 100644 (file)
@@ -413,12 +413,12 @@ ENTRY(cpu_arm7_reset)
 
 cpu_armvlsi_name:
                .asciz  "ARM/VLSI"
-cpu_arm6_name: .asciz  "arm6"
+cpu_arm6_name: .asciz  "ARM 6"
 cpu_arm610_name:
-               .asciz  "arm610"
-cpu_arm7_name: .asciz  "arm7"
+               .asciz  "ARM 610"
+cpu_arm7_name: .asciz  "ARM 7"
 cpu_arm710_name:
-               .asciz  "arm710"
+               .asciz  "ARM 710"
                .align
 
                .section ".text.init", #alloc, #execinstr
index 266d960b5567302fa2ef00cdbb70305a07c1a46c..2d57b103053685604890f4decb79caa3e37ef74d 100644 (file)
@@ -456,9 +456,9 @@ ENTRY(cpu_sa1100_reset)
 
 cpu_manu_name: .asciz  "Intel"
 ENTRY(cpu_sa110_name)
-               .asciz  "sa110"
+               .asciz  "StrongARM-110"
 ENTRY(cpu_sa1100_name)
-               .asciz  "sa1100"
+               .asciz  "StrongARM-1100"
                .align
 
                .section ".text.init", #alloc, #execinstr
index b21a915aa33e9f6017c753de183c2a18eb629335..3c72c9cb53bb629dbf9772f990f99baf42ee9e54 100644 (file)
 extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu(elf_fpregset_t *);
 
+#ifdef __SMP__
+extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
+extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
+#endif
+
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
 extern struct drive_info_struct drive_info;
 EXPORT_SYMBOL(drive_info);
@@ -92,6 +97,8 @@ EXPORT_SYMBOL(__cpu_logical_map);
 EXPORT_SYMBOL(smp_num_cpus);
 EXPORT_SYMBOL(cpu_present_map);
 EXPORT_SYMBOL(cpu_online_map);
+EXPORT_SYMBOL_NOVERS(__write_lock_failed);
+EXPORT_SYMBOL_NOVERS(__read_lock_failed);
 
 /* Global SMP irq stuff */
 EXPORT_SYMBOL(synchronize_irq);
index 9c7f04e234e6a10d52d5446ee144c24fba1f42e7..b382ce0af3e7a855562057b421c8ba28858dcccb 100644 (file)
@@ -381,10 +381,10 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
 static inline void do_flush_tlb_all_local(void)
 {
        local_flush_tlb();
-       if(current->mm==0) {
+       if (!current->mm && current->active_mm) {
                unsigned long cpu = smp_processor_id();
-               clear_bit(cpu, &current->active_mm->cpu_vm_mask);
 
+               clear_bit(cpu, &current->active_mm->cpu_vm_mask);
                cpu_tlbbad[cpu] = 1;
        }
 }
@@ -396,8 +396,9 @@ static void flush_tlb_all_ipi(void* info)
 
 void flush_tlb_all(void)
 {
-       if(cpu_online_map ^ (1<<smp_processor_id()))
-               smp_call_function (flush_tlb_all_ipi,0,1,1);
+       if (cpu_online_map ^ (1 << smp_processor_id()))
+               while (smp_call_function (flush_tlb_all_ipi,0,0,1) == -EBUSY)
+                       mb();
 
        do_flush_tlb_all_local();
 }
index 98601bef18eb66c9881ea44748b89a125e07c8a4..9013f074e5c0934d6489a795c718256d0e896f8c 100644 (file)
@@ -376,7 +376,7 @@ static void __init pagetable_init(void)
         * Permanent kmaps:
         */
        vaddr = PKMAP_BASE;
-       fixrange_init(vaddr, vaddr + 4*1024*1024, pgd_base);
+       fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
 
        pgd = swapper_pg_dir + __pgd_offset(vaddr);
        pmd = pmd_offset(pgd, vaddr);
index eabc6bc9c90f86fec97065cb9b29e4cf8f23c363..471e9a85fec8f67964ebedd28435b03e3855f234 100644 (file)
@@ -649,6 +649,7 @@ static int __init swap_init(unsigned long start_mem, unsigned long swap_data)
 
        /* now swapping to this device ok */
        p->pages = j + k;
+       swap_list_lock();
        nr_swap_pages += j;
        p->flags = SWP_WRITEOK;
 
@@ -666,6 +667,7 @@ static int __init swap_init(unsigned long start_mem, unsigned long swap_data)
        } else {
                swap_info[prev].next = p - swap_info;
        }
+       swap_list_unlock();
 
        printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
                        p->pages << 2, p->pages );
@@ -924,6 +926,9 @@ static int unswap_by_read(unsigned short *map, unsigned long max,
                        DPRINTK("unswap: map[i=%lu]=%u nr_swap=%u\n",
                                i, map[i], nr_swap_pages);
 
+                       swap_device_lock(stram_swap_info);
+                       map[i]++;
+                       swap_device_unlock(stram_swap_info);
                        /* Get a page for the entry, using the existing
                           swap cache page if there is one.  Otherwise,
                           get a clean page and read the swap into it. */
@@ -945,18 +950,24 @@ static int unswap_by_read(unsigned short *map, unsigned long max,
                                stat_swap_force++;
        #endif
                        }
-                       else if (map[i])
+                       else {
+                               swap_free(entry);
                                return -ENOMEM;
+                       }
                }
 
                DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n",
                                 i, map[i], nr_swap_pages );
+               swap_list_lock();
+               swap_device_lock(stram_swap_info);
                map[i] = SWAP_MAP_BAD;
                if (stram_swap_info->lowest_bit == i)
                        stram_swap_info->lowest_bit++;
                if (stram_swap_info->highest_bit == i)
                        stram_swap_info->highest_bit--;
                --nr_swap_pages;
+               swap_device_unlock(stram_swap_info);
+               swap_list_unlock();
        }
 
        return 0;
@@ -1022,6 +1033,8 @@ static void free_stram_region( unsigned long offset, unsigned long n_pages )
                return;
        }
 
+       swap_list_lock();
+       swap_device_lock(stram_swap_info);
        /* un-reserve the freed pages */
        for( ; n_pages > 0; ++offset, --n_pages ) {
                if (map[offset] != SWAP_MAP_BAD)
@@ -1038,6 +1051,8 @@ static void free_stram_region( unsigned long offset, unsigned long n_pages )
        if (stram_swap_info->prio > swap_info[swap_list.next].prio)
                swap_list.next = swap_list.head;
        nr_swap_pages += n_pages;
+       swap_device_unlock(stram_swap_info);
+       swap_list_unlock();
 }
 
 \f
index a41c086ead95946d31609f8316ed0f5eed79910d..8a6db08e252b2c9559bc8ef1fbdae96b4aa46007 100644 (file)
@@ -43,8 +43,9 @@ ifdef CONFIG_4xx
 else
   ifdef CONFIG_8xx
     HEAD := arch/ppc/kernel/head_8xx.o
+  else
+    HEAD := arch/ppc/kernel/head.o
   endif
-  HEAD := arch/ppc/kernel/head.o
 endif
 
 ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/mm arch/ppc/lib
index 81e21f3e3814ac2d1cbf95e31da47060e0f56e96..a7ed94074b35fa53000e8c53f3d2d27f6f3d16e7 100644 (file)
@@ -9,25 +9,26 @@ CC    = $(CROSS_COMPILE)gcc
 LD     = $(CROSS_COMPILE)ld
 CFLAGS = -O -fno-builtin -I$(TOPDIR)/include
 OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment \
-       --add-section=image=vmlinux.gz
-LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
+OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
+COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
+CHRP_LD_ARGS = -Ttext 0x00400000
 GZ = gzip -9
 
-OBJS = crt0.o start.o main.o misc.o string.o zlib.o
+COFFOBJS = coffcrt0.o start.o coffmain.o misc.o string.o zlib.o image.o
+CHRPOBJS = crt0.o start.o chrpmain.o misc.o string.o zlib.o image.o
 LIBS = $(TOPDIR)/lib/lib.a
 
-ifeq ($(CONFIG_ALL_PPC),y)
-# yes, we want to build pmac stuff
-CONFIG_PMAC = y
-endif
-
 ifeq ($(CONFIG_PPC64),y)
 MSIZE=.64
 else
 MSIZE=
 endif
 
+ifeq ($(CONFIG_ALL_PPC),y)
+# yes, we want to build pmac stuff
+CONFIG_PMAC = y
+endif
+
 ifeq ($(CONFIG_SMP),y)
 TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE)
 else
@@ -38,34 +39,58 @@ ifeq ($(CONFIG_PMAC),y)
 hack-coff: hack-coff.c
        $(HOSTCC) $(HOSTCFLAGS) -o hack-coff hack-coff.c
 
+znetboot: vmlinux.coff zImage
+       cp vmlinux.coff $(TFTPIMAGE)
+
+znetboot.initrd: vmlinux.coff.initrd
+       cp vmlinux.coff.initrd $(TFTPIMAGE)
+
 floppy: zImage
 #      mount -t hfs /dev/fd0 /mnt
 #      cp vmlinux.coff /mnt
 #      umount /mnt
 
-znetboot: vmlinux.coff
-       cp vmlinux.coff $(TFTPIMAGE)
+coffboot: $(COFFOBJS) no_initrd.o ld.script
+       $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) no_initrd.o $(LIBS)
 
-znetboot.initrd: vmlinux.coff.initrd
-       cp vmlinux.coff.initrd $(TFTPIMAGE)
+coffboot.initrd: $(COFFOBJS) initrd.o ld.script
+       $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS)
 
-coffboot: $(OBJS) ld.script
-       $(LD) -o coffboot $(LD_ARGS) $(OBJS) $(LIBS)
+piggyback: piggyback.c
+       $(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c
 
-zImage: vmlinux.coff
+mknote: mknote.c
+       $(HOSTCC) $(HOSTCFLAGS) -o mknote mknote.c
 
-zImage.initrd: vmlinux.coff.initrd
+image.o: piggyback vmlinux.gz
+       ./piggyback image < vmlinux.gz | $(AS) -o image.o
 
-vmlinux.coff: coffboot hack-coff vmlinux.gz
+initrd.o: ramdisk.image.gz piggyback
+       ./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o
+
+vmlinux.coff: coffboot hack-coff
        $(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@
        ./hack-coff $@
        ln -sf vmlinux.coff zImage
 
-vmlinux.coff.initrd: coffboot hack-coff vmlinux.gz ramdisk.image.gz
-       $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=ramdisk.image.gz \
-               coffboot $@
+vmlinux.coff.initrd: coffboot.initrd hack-coff
+       $(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@
        ./hack-coff $@
 
+vmlinux.elf: $(CHRPOBJS) no_initrd.o mknote
+       $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) no_initrd.o $(LIBS)
+       ./mknote > note
+       $(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
+
+vmlinux.elf.initrd: $(CHRPOBJS) initrd.o mknote
+       $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) initrd.o $(LIBS)
+       ./mknote > note
+       $(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
+
+zImage: vmlinux.coff vmlinux.elf
+
+zImage.initrd: vmlinux.coff.initrd vmlinux.elf.initrd
+
 else
 znetboot: vmlinux.gz
 
diff --git a/arch/ppc/coffboot/chrpmain.c b/arch/ppc/coffboot/chrpmain.c
new file mode 100644 (file)
index 0000000..fc56489
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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 Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "nonstdio.h"
+#include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#define __KERNEL__
+#include <asm/page.h>
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+void make_bi_recs(unsigned long);
+void gunzip(void *, int, unsigned char *, int *);
+void stop_imac_ethernet(void);
+void stop_imac_usb(void);
+
+#define get_16be(x)    (*(unsigned short *)(x))
+#define get_32be(x)    (*(unsigned *)(x))
+
+#define RAM_START      0x00000000
+#define RAM_END                (8<<20)
+
+#define PROG_START     0x00010000
+
+char *avail_ram;
+char *end_avail;
+
+extern char _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+
+
+boot(int a1, int a2, void *prom)
+{
+    int ns, oh, i;
+    unsigned sa, len;
+    void *dst;
+    unsigned char *im;
+    unsigned initrd_start, initrd_size;
+    extern char _start;
+    
+    printf("chrpboot starting: loaded at 0x%x\n", &_start);
+    if (initrd_len) {
+       initrd_size = initrd_len;
+       initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+       a1 = initrd_start;
+       a2 = initrd_size;
+       claim(initrd_start, RAM_END - initrd_start, 0);
+       printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start,
+              initrd_data,initrd_size);
+       memcpy((char *)initrd_start, initrd_data, initrd_size);
+    }
+    im = image_data;
+    len = image_len;
+    /* claim 3MB starting at PROG_START */
+    claim(PROG_START, 3 << 20, 0);
+    dst = (void *) PROG_START;
+    if (im[0] == 0x1f && im[1] == 0x8b) {
+       /* claim 512kB for scratch space */
+       avail_ram = (char *) claim(0, 512 << 10, 0x10);
+       end_avail = avail_ram + (512 << 10);
+       printf("avail_ram = %x\n", avail_ram);
+       printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+       gunzip(dst, 3 << 20, im, &len);
+       printf("done %u bytes\n", len);
+    } else {
+       memmove(dst, im, len);
+    }
+
+    flush_cache(dst, len);
+    stop_imac_ethernet();
+    stop_imac_usb();
+    make_bi_recs((unsigned long) dst + len);
+
+    sa = (unsigned long)PROG_START;
+    printf("start address = 0x%x\n", sa);
+
+    (*(void (*)())sa)(0, 0, prom, a1, a2);
+
+    printf("returned?\n");
+
+    pause();
+}
+
+void make_bi_recs(unsigned long addr)
+{
+       struct bi_record *rec;
+
+       rec = (struct bi_record *)PAGE_ALIGN(addr);
+           
+       rec->tag = BI_FIRST;
+       rec->size = sizeof(struct bi_record);
+       rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+       rec->tag = BI_BOOTLOADER_ID;
+       sprintf( (char *)rec->data, "coffboot");
+       rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
+       rec = (struct bi_record *)((unsigned long)rec + rec->size);
+           
+       rec->tag = BI_MACHTYPE;
+       rec->data[0] = _MACH_Pmac;
+       rec->data[1] = 1;
+       rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+       rec = (struct bi_record *)((unsigned long)rec + rec->size);
+           
+       rec->tag = BI_LAST;
+       rec->size = sizeof(struct bi_record);
+       rec = (struct bi_record *)((unsigned long)rec + rec->size);
+}
+
+#define eieio()        asm volatile("eieio");
+
+void stop_imac_ethernet(void)
+{
+    void *macio, *enet;
+    unsigned int macio_addr[5], enet_reg[6];
+    int len;
+    volatile unsigned int *dbdma;
+
+    macio = finddevice("/pci/mac-io");
+    enet = finddevice("/pci/mac-io/ethernet");
+    if (macio == NULL || enet == NULL)
+       return;
+    len = getprop(macio, "assigned-addresses", macio_addr, sizeof(macio_addr));
+    if (len != sizeof(macio_addr))
+       return;
+    len = getprop(enet, "reg", enet_reg, sizeof(enet_reg));
+    if (len != sizeof(enet_reg))
+       return;
+    printf("macio base %x, dma at %x & %x\n",
+          macio_addr[2], enet_reg[2], enet_reg[4]);
+
+    /* hope this is mapped... */
+    dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[2]);
+    *dbdma = 0x80;     /* clear the RUN bit */
+    eieio();
+    dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[4]);
+    *dbdma = 0x80;     /* clear the RUN bit */
+    eieio();
+}
+
+void stop_imac_usb(void)
+{
+    void *usb;
+    unsigned int usb_addr[5];
+    int len;
+    volatile unsigned int *usb_ctrl;
+
+    usb = finddevice("/pci/usb");
+    if (usb == NULL)
+       return;
+    len = getprop(usb, "assigned-addresses", usb_addr, sizeof(usb_addr));
+    if (len != sizeof(usb_addr))
+       return;
+    printf("usb base %x\n", usb_addr[2]);
+
+    usb_ctrl = (volatile unsigned int *) (usb_addr[2] + 8);
+    *usb_ctrl = 0x01000000;    /* cpu_to_le32(1) */
+    eieio();
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+    void *p = avail_ram;
+
+    size *= items;
+    size = (size + 7) & -8;
+    avail_ram += size;
+    if (avail_ram > end_avail) {
+       printf("oops... out of memory\n");
+       pause();
+    }
+    return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+}
+
+#define HEAD_CRC       2
+#define EXTRA_FIELD    4
+#define ORIG_NAME      8
+#define COMMENT                0x10
+#define RESERVED       0xe0
+
+#define DEFLATED       8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+    z_stream s;
+    int r, i, flags;
+
+    /* skip header */
+    i = 10;
+    flags = src[3];
+    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+       printf("bad gzipped data\n");
+       exit();
+    }
+    if ((flags & EXTRA_FIELD) != 0)
+       i = 12 + src[10] + (src[11] << 8);
+    if ((flags & ORIG_NAME) != 0)
+       while (src[i++] != 0)
+           ;
+    if ((flags & COMMENT) != 0)
+       while (src[i++] != 0)
+           ;
+    if ((flags & HEAD_CRC) != 0)
+       i += 2;
+    if (i >= *lenp) {
+       printf("gunzip: ran out of data in header\n");
+       exit();
+    }
+
+    s.zalloc = zalloc;
+    s.zfree = zfree;
+    r = inflateInit2(&s, -MAX_WBITS);
+    if (r != Z_OK) {
+       printf("inflateInit2 returned %d\n", r);
+       exit();
+    }
+    s.next_in = src + i;
+    s.avail_in = *lenp - i;
+    s.next_out = dst;
+    s.avail_out = dstlen;
+    r = inflate(&s, Z_FINISH);
+    if (r != Z_OK && r != Z_STREAM_END) {
+       printf("inflate returned %d msg: %s\n", r, s.msg);
+       exit();
+    }
+    *lenp = s.next_out - (unsigned char *) dst;
+    inflateEnd(&s);
+}
diff --git a/arch/ppc/coffboot/coffcrt0.S b/arch/ppc/coffboot/coffcrt0.S
new file mode 100644 (file)
index 0000000..43ae4e0
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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 Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+       .text
+       .globl  _start
+_start:
+       .long   __start,0,0
+
+       .globl  __start
+__start:
+       lis     9,_start@h
+       lis     8,_etext@ha
+       addi    8,8,_etext@l
+1:     dcbf    0,9
+       icbi    0,9
+       addi    9,9,0x20
+       cmplwi  0,9,8
+       blt     1b
+       b       start
diff --git a/arch/ppc/coffboot/coffmain.c b/arch/ppc/coffboot/coffmain.c
new file mode 100644 (file)
index 0000000..2bb4ea3
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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 Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "nonstdio.h"
+#include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#define __KERNEL__
+#include <asm/page.h>
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+extern char *claim(unsigned, unsigned, unsigned);
+void make_bi_recs(unsigned long);
+void gunzip(void *, int, unsigned char *, int *);
+
+#define get_16be(x)    (*(unsigned short *)(x))
+#define get_32be(x)    (*(unsigned *)(x))
+
+#define RAM_START      0xc0000000
+#define PROG_START     RAM_START
+#define RAM_END                (RAM_START + 0x800000)  /* only 8M mapped with BATs */
+
+char *avail_ram;
+char *end_avail;
+
+extern char _start[], _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+
+
+boot(int a1, int a2, void *prom)
+{
+    int ns, oh, i;
+    unsigned sa, len;
+    void *dst;
+    unsigned char *im;
+    unsigned initrd_start, initrd_size;
+    
+    printf("coffboot starting: loaded at 0x%x\n", _start);
+    setup_bats(RAM_START);
+    if (initrd_len) {
+       initrd_size = initrd_len;
+       initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+       a1 = initrd_start;
+       a2 = initrd_size;
+       claim(initrd_start - RAM_START, RAM_END - initrd_start, 0);
+       printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n",
+              initrd_start, initrd_data, initrd_size);
+       memcpy((char *)initrd_start, initrd_data, initrd_size);
+    }
+    im = image_data;
+    len = image_len;
+    /* claim 3MB starting at 0 */
+    claim(0, 3 << 20, 0);
+    dst = (void *) RAM_START;
+    if (im[0] == 0x1f && im[1] == 0x8b) {
+       /* claim 512kB for scratch space */
+       avail_ram = claim(0, 512 << 10, 0x10) + RAM_START;
+       end_avail = avail_ram + (512 << 10);
+       printf("avail_ram = %x\n", avail_ram);
+       printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+       gunzip(dst, 3 << 20, im, &len);
+       printf("done %u bytes\n", len);
+    } else {
+       memmove(dst, im, len);
+    }
+
+    flush_cache(dst, len);
+    make_bi_recs((unsigned long)dst + len);
+    
+    sa = (unsigned long)PROG_START;
+    printf("start address = 0x%x\n", sa);
+
+#if 0
+    pause();
+#endif
+    (*(void (*)())sa)(a1, a2, prom);
+
+    printf("returned?\n");
+
+    pause();
+}
+
+void make_bi_recs(unsigned long addr)
+{
+       struct bi_record *rec;
+
+       rec = (struct bi_record *)PAGE_ALIGN(addr);
+           
+       rec->tag = BI_FIRST;
+       rec->size = sizeof(struct bi_record);
+       rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+       rec->tag = BI_BOOTLOADER_ID;
+       sprintf( (char *)rec->data, "coffboot");
+       rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
+       rec = (struct bi_record *)((unsigned long)rec + rec->size);
+           
+       rec->tag = BI_MACHTYPE;
+       rec->data[0] = _MACH_Pmac;
+       rec->data[1] = 1;
+       rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+       rec = (struct bi_record *)((unsigned long)rec + rec->size);
+           
+       rec->tag = BI_LAST;
+       rec->size = sizeof(struct bi_record);
+       rec = (struct bi_record *)((unsigned long)rec + rec->size);
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+    void *p = avail_ram;
+
+    size *= items;
+    size = (size + 7) & -8;
+    avail_ram += size;
+    if (avail_ram > end_avail) {
+       printf("oops... out of memory\n");
+       pause();
+    }
+    return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+}
+
+#define HEAD_CRC       2
+#define EXTRA_FIELD    4
+#define ORIG_NAME      8
+#define COMMENT                0x10
+#define RESERVED       0xe0
+
+#define DEFLATED       8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+    z_stream s;
+    int r, i, flags;
+
+    /* skip header */
+    i = 10;
+    flags = src[3];
+    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+       printf("bad gzipped data\n");
+       exit();
+    }
+    if ((flags & EXTRA_FIELD) != 0)
+       i = 12 + src[10] + (src[11] << 8);
+    if ((flags & ORIG_NAME) != 0)
+       while (src[i++] != 0)
+           ;
+    if ((flags & COMMENT) != 0)
+       while (src[i++] != 0)
+           ;
+    if ((flags & HEAD_CRC) != 0)
+       i += 2;
+    if (i >= *lenp) {
+       printf("gunzip: ran out of data in header\n");
+       exit();
+    }
+
+    s.zalloc = zalloc;
+    s.zfree = zfree;
+    r = inflateInit2(&s, -MAX_WBITS);
+    if (r != Z_OK) {
+       printf("inflateInit2 returned %d\n", r);
+       exit();
+    }
+    s.next_in = src + i;
+    s.avail_in = *lenp - i;
+    s.next_out = dst;
+    s.avail_out = dstlen;
+    r = inflate(&s, Z_FINISH);
+    if (r != Z_OK && r != Z_STREAM_END) {
+       printf("inflate returned %d msg: %s\n", r, s.msg);
+       exit();
+    }
+    *lenp = s.next_out - (unsigned char *) dst;
+    inflateEnd(&s);
+}
index 43ae4e0ec4a7e2509440f5832b987dadf04617ef..c43340594032f2cc5beb90636f9a7211163eb5c9 100644 (file)
@@ -9,10 +9,6 @@
        .text
        .globl  _start
 _start:
-       .long   __start,0,0
-
-       .globl  __start
-__start:
        lis     9,_start@h
        lis     8,_etext@ha
        addi    8,8,_etext@l
index df542a5223ec11e771f14cd8e0fd1a0370257187..7defc69e870d7c4ffee1c5484b22dbbf2d6de3f4 100644 (file)
  */
        .globl  setup_bats
 setup_bats:
-       mr      4,3
-       mfpvr   3
-       rlwinm  3,3,16,16,31            /* r3 = 1 for 601, 4 for 604 */
-       cmpi    0,3,1
+       mfpvr   5
+       rlwinm  5,5,16,16,31            /* r3 = 1 for 601, 4 for 604 */
+       cmpi    0,5,1
+       li      0,0
        bne     4f
-       ori     4,4,4                   /* set up BAT registers for 601 */
-       li      5,0x7f
-       mtibatu 3,4
-       mtibatl 3,5
-       isync
-       blr
-4:     ori     4,4,0xfe                /* set up BAT registers for 604 */
-       li      5,2
-       mtdbatl 3,5
-       mtdbatu 3,4
-       mtibatl 3,5
-       mtibatu 3,4
+       mtibatl 3,0                     /* invalidate BAT first */
+       ori     3,3,4                   /* set up BAT registers for 601 */
+       li      4,0x7f
+       mtibatu 3,3
+       mtibatl 3,4
+       b       5f
+4:     mtdbatu 3,0                     /* invalidate BATs first */
+       mtibatu 3,0
+       ori     3,3,0xff                /* set up BAT registers for 604 */
+       li      4,2
+       mtdbatl 3,4
+       mtdbatu 3,3
+       mtibatl 3,4
+       mtibatu 3,3
+5:     sync
        isync
        blr
 
diff --git a/arch/ppc/coffboot/mknote.c b/arch/ppc/coffboot/mknote.c
new file mode 100644 (file)
index 0000000..120cc1d
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) Cort Dougan 1999.
+ *
+ * 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 Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Generate a note section as per the CHRP specification.
+ *
+ */
+
+#include <stdio.h>
+
+#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
+
+int main(void)
+{
+/* header */
+       /* namesz */
+       PL(strlen("PowerPC")+1);
+       /* descrsz */
+       PL(6*4);
+       /* type */
+       PL(0x1275);
+       /* name */
+       printf("PowerPC"); printf("%c", 0);
+       
+/* descriptor */
+       /* real-mode */
+       PL(0xffffffff);
+       /* real-base */
+       PL(0x00c00000);
+       /* real-size */
+       PL(0xffffffff);
+       /* virt-base */
+       PL(0xffffffff);
+       /* virt-size */
+       PL(0xffffffff);
+       /* load-base */
+       PL(0x4000);
+       return 0;
+}
diff --git a/arch/ppc/coffboot/no_initrd.c b/arch/ppc/coffboot/no_initrd.c
new file mode 100644 (file)
index 0000000..ed5dcdb
--- /dev/null
@@ -0,0 +1,2 @@
+char initrd_data[1];
+int initrd_len = 0;
diff --git a/arch/ppc/coffboot/piggyback.c b/arch/ppc/coffboot/piggyback.c
new file mode 100644 (file)
index 0000000..1720258
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+extern long ce_exec_config[];
+
+main(int argc, char *argv[])
+{
+       int i, cnt, pos, len;
+       unsigned int cksum, val;
+       unsigned char *lp;
+       unsigned char buf[8192];
+       if (argc != 2)
+       {
+               fprintf(stderr, "usage: %s name <in-file >out-file\n",
+                       argv[0]);
+               exit(1);
+       }
+       fprintf(stdout, "#\n");
+       fprintf(stdout, "# Miscellaneous data structures:\n");
+       fprintf(stdout, "# WARNING - this file is automatically generated!\n");
+       fprintf(stdout, "#\n");
+       fprintf(stdout, "\n");
+       fprintf(stdout, "\t.data\n");
+       fprintf(stdout, "\t.globl %s_data\n", argv[1]);
+       fprintf(stdout, "%s_data:\n", argv[1]);
+       pos = 0;
+       cksum = 0;
+       while ((len = read(0, buf, sizeof(buf))) > 0)
+       {
+               cnt = 0;
+               lp = (unsigned char *)buf;
+               len = (len + 3) & ~3;  /* Round up to longwords */
+               for (i = 0;  i < len;  i += 4)
+               {
+                       if (cnt == 0)
+                       {
+                               fprintf(stdout, "\t.long\t");
+                       }
+                       fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
+                       val = *(unsigned long *)lp;
+                       cksum ^= val;
+                       lp += 4;
+                       if (++cnt == 4)
+                       {
+                               cnt = 0;
+                               fprintf(stdout, " # %x \n", pos+i-12);
+                               fflush(stdout);
+                       } else
+                       {
+                               fprintf(stdout, ",");
+                       }
+               }
+               if (cnt)
+               {
+                       fprintf(stdout, "0\n");
+               }
+               pos += len;
+       }
+       fprintf(stdout, "\t.globl %s_len\n", argv[1]);
+       fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos);
+       fflush(stdout);
+       fclose(stdout);
+       fprintf(stderr, "cksum = %x\n", cksum);
+       exit(0);
+}
+
index 1f11edbec83681e94aef541e3ca2b2e63707a673..6fc1fc1fbcdce56625be2056ac4df801fa8e08a0 100644 (file)
@@ -33,7 +33,7 @@ start(int a1, int a2, void *promptr)
     if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
        exit();
 
-    coffboot(a1, a2, promptr);
+    boot(a1, a2, promptr);
     for (;;)
        exit();
 }
@@ -62,6 +62,25 @@ write(void *handle, void *ptr, int nb)
     return args.actual;
 }
 
+int writestring(void *f, char *ptr, int nb)
+{
+       int w = 0, i;
+       char *ret = "\r";
+
+       for (i = 0; i < nb; ++i) {
+               if (ptr[i] == '\n') {
+                       if (i > w) {
+                               write(f, ptr + w, i - w);
+                               w = i;
+                       }
+                       write(f, ret, 1);
+               }
+       }
+       if (w < nb)
+               write(f, ptr + w, nb - w);
+       return nb;
+}
+
 int
 read(void *handle, void *ptr, int nb)
 {
@@ -130,6 +149,29 @@ finddevice(const char *name)
     return args.phandle;
 }
 
+void *
+claim(unsigned int virt, unsigned int size, unsigned int align)
+{
+    struct prom_args {
+       char *service;
+       int nargs;
+       int nret;
+       unsigned int virt;
+       unsigned int size;
+       unsigned int align;
+       void *ret;
+    } args;
+
+    args.service = "claim";
+    args.nargs = 3;
+    args.nret = 1;
+    args.virt = virt;
+    args.size = size;
+    args.align = align;
+    (*prom)(&args);
+    return args.ret;
+}
+
 int
 getprop(void *phandle, const char *name, void *buf, int buflen)
 {
@@ -161,9 +203,7 @@ putc(int c, void *f)
 {
     char ch = c;
 
-    if (c == '\n')
-       putc('\r', f);
-    return write(f, &ch, 1) == 1? c: -1;
+    return writestring(f, &ch, 1) == 1? c: -1;
 }
 
 int
@@ -177,7 +217,7 @@ fputs(char *str, void *f)
 {
     int n = strlen(str);
 
-    return write(f, str, n) == n? 0: -1;
+    return writestring(f, str, n) == n? 0: -1;
 }
 
 int
@@ -190,7 +230,7 @@ readchar()
        case 1:
            return ch;
        case -1:
-           printk("read(stdin) returned -1\r\n");
+           printk("read(stdin) returned -1\n");
            return -1;
        }
     }
@@ -264,7 +304,7 @@ printk(char *fmt, ...)
        va_start(args, fmt);
        n = vsprintf(sprint_buf, fmt, args);
        va_end(args);
-       write(stdout, sprint_buf, n);
+       writestring(stdout, sprint_buf, n);
 }
 
 int
@@ -276,6 +316,6 @@ printf(char *fmt, ...)
        va_start(args, fmt);
        n = vsprintf(sprint_buf, fmt, args);
        va_end(args);
-       write(stdout, sprint_buf, n);
+       writestring(stdout, sprint_buf, n);
        return n;
 }
index 4ca5417740fe3bb792d4a1a8052ad85bfadca4df..e989838e328eaa401280566038eff5975b3114cf 100644 (file)
@@ -66,7 +66,7 @@ if [ "$CONFIG_ALL_PPC" != "y" ];then
   define_bool CONFIG_MACH_SPECIFIC y
 fi
 
-if [ "$CONFIG_4xx" = "y" ] || [ "$CONFIG_8xx" = "y" ]; then
+if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then
   bool 'Math emulation' CONFIG_MATH_EMULATION
 fi
 endmenu
index 4a8d6b5727138038b848d28de36f2c6d6e6bfc90..19404751d5f3a99e1376e364c6e9a1648da4a666 100644 (file)
@@ -274,7 +274,6 @@ CONFIG_BMAC=y
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_YELLOWFIN is not set
 # CONFIG_RTL8139 is not set
 # CONFIG_DM9102 is not set
 # CONFIG_AT1700 is not set
@@ -283,7 +282,6 @@ CONFIG_BMAC=y
 CONFIG_NET_EISA=y
 CONFIG_PCNET32=y
 # CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_ACENIC is not set
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
@@ -301,6 +299,13 @@ CONFIG_DE4X5=y
 # CONFIG_EPIC100 is not set
 # CONFIG_ZNET is not set
 # CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 
index 4a8d6b5727138038b848d28de36f2c6d6e6bfc90..19404751d5f3a99e1376e364c6e9a1648da4a666 100644 (file)
@@ -274,7 +274,6 @@ CONFIG_BMAC=y
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_YELLOWFIN is not set
 # CONFIG_RTL8139 is not set
 # CONFIG_DM9102 is not set
 # CONFIG_AT1700 is not set
@@ -283,7 +282,6 @@ CONFIG_BMAC=y
 CONFIG_NET_EISA=y
 CONFIG_PCNET32=y
 # CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_ACENIC is not set
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
@@ -301,6 +299,13 @@ CONFIG_DE4X5=y
 # CONFIG_EPIC100 is not set
 # CONFIG_ZNET is not set
 # CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 
index 4da6328ce724e49b0ac81872d6626a1d1d16bfae..7f6340261f3984f575f55f18b680cfb7b7de101b 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
  *   PowerPC 403GCX/405GP modifications.
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <asm/ptrace.h>
index c7247a5e03151f266ba15479e2172e8405af37b7..5ed04344ec4244db62abcdd83999d501eab52482 100644 (file)
@@ -392,7 +392,7 @@ _GLOBAL(fake_interrupt)
  * here so it's easy to add arch-specific sections later.
  * -- Cort
  */
-#if defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
 /*
  * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
  * called with the MMU off.
@@ -432,4 +432,4 @@ enter_rtas:
        mtspr   SRR0,r8
        mtspr   SRR1,r9
        rfi                     /* return to caller */
-#endif /* defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) */
+#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */
index eda9a77fe5094899d48521ee4efda8ef7b47cd0c..57ea34687cdb5cdf15c26cfa9197287e7331a0bc 100644 (file)
@@ -331,7 +331,7 @@ void __init gemini_init_IRQ(void)
 
        /* gemini has no 8259 */
        open_pic.irq_offset = 0;
-       for( i=0; i < OPENPIC_VEC_SPURIOUS; i++ ) 
+       for( i=0; i < NR_IRQS; i++ ) 
                irq_desc[i].ctl = &open_pic;
        openpic_init(1);
 #ifdef __SMP__
index 258f0056604ffb1890c36377368a15b6eaf2440a..451a1cad4482d551214b611c6f8d0e5333fc852c 100644 (file)
@@ -1352,30 +1352,6 @@ _GLOBAL(set_context)
        SYNC
        blr
 
-/*
- * We put a few things here that have to be page-aligned.
- * This stuff goes at the beginning of the data segment,
- * which is page-aligned.
- */
-       .data
-       .globl  sdata
-sdata:
-       .globl  empty_zero_page
-empty_zero_page:
-       .space  4096
-
-       .globl  swapper_pg_dir
-swapper_pg_dir:
-       .space  4096    
-
-/*
- * This space gets a copy of optional info passed to us by the bootstrap
- * Used to pass parameters into the kernel like root=/dev/sda1, etc.
- */    
-       .globl  cmd_line
-cmd_line:
-       .space  512
-       
 /* 
  * An undocumented "feature" of 604e requires that the v bit
  * be cleared before changing BAT values.
@@ -1412,10 +1388,26 @@ clear_bats:
 #endif /* !defined(CONFIG_GEMINI) */
        blr
 
-flush_tlbs:
-       lis     r20, 0x1000
-1:     addic.  r20, r20, -0x1000
-       tlbie   r20
-       blt     1b
-       sync
-       blr
+/*
+ * We put a few things here that have to be page-aligned.
+ * This stuff goes at the beginning of the data segment,
+ * which is page-aligned.
+ */
+       .data
+       .globl  sdata
+sdata:
+       .globl  empty_zero_page
+empty_zero_page:
+       .space  4096
+
+       .globl  swapper_pg_dir
+swapper_pg_dir:
+       .space  4096    
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */    
+       .globl  cmd_line
+cmd_line:
+       .space  512
index da5dccfa10d9cdc4ef538cef150432cf0cf50c7b..444654ec6b2f813ac9ab0ae93aedcb1e2d1400af 100644 (file)
@@ -404,8 +404,10 @@ _GLOBAL(atomic_set_mask)
  * The *_ns versions don't do byte-swapping.
  */
 _GLOBAL(_insb)
+       cmpw    0,r5,0
        mtctr   r5
        subi    r4,r4,1
+       blelr-
 00:    lbz     r5,0(r3)
        eieio
        stbu    r5,1(r4)
@@ -413,8 +415,10 @@ _GLOBAL(_insb)
        blr
 
 _GLOBAL(_outsb)
+       cmpw    0,r5,0
        mtctr   r5
        subi    r4,r4,1
+       blelr-
 00:    lbzu    r5,1(r4)
        stb     r5,0(r3)
        eieio
@@ -422,8 +426,10 @@ _GLOBAL(_outsb)
        blr     
 
 _GLOBAL(_insw)
+       cmpw    0,r5,0
        mtctr   r5
        subi    r4,r4,2
+       blelr-
 00:    lhbrx   r5,0,r3
        eieio
        sthu    r5,2(r4)
@@ -431,8 +437,10 @@ _GLOBAL(_insw)
        blr
 
 _GLOBAL(_outsw)
+       cmpw    0,r5,0
        mtctr   r5
        subi    r4,r4,2
+       blelr-
 00:    lhzu    r5,2(r4)
        eieio
        sthbrx  r5,0,r3 
@@ -440,8 +448,10 @@ _GLOBAL(_outsw)
        blr     
 
 _GLOBAL(_insl)
+       cmpw    0,r5,0
        mtctr   r5
        subi    r4,r4,4
+       blelr-
 00:    lwbrx   r5,0,r3
        eieio
        stwu    r5,4(r4)
@@ -449,8 +459,10 @@ _GLOBAL(_insl)
        blr
 
 _GLOBAL(_outsl)
+       cmpw    0,r5,0
        mtctr   r5
        subi    r4,r4,4
+       blelr-
 00:    lwzu    r5,4(r4)
        stwbrx  r5,0,r3
        eieio
@@ -459,8 +471,10 @@ _GLOBAL(_outsl)
 
 _GLOBAL(ide_insw)
 _GLOBAL(_insw_ns)
+       cmpw    0,r5,0
        mtctr   r5
        subi    r4,r4,2
+       blelr-
 00:    lhz     r5,0(r3)
        eieio
        sthu    r5,2(r4)
@@ -469,8 +483,10 @@ _GLOBAL(_insw_ns)
 
 _GLOBAL(ide_outsw)
 _GLOBAL(_outsw_ns)
+       cmpw    0,r5,0
        mtctr   r5
        subi    r4,r4,2
+       blelr-
 00:    lhzu    r5,2(r4)
        sth     r5,0(r3)
        eieio
@@ -478,8 +494,10 @@ _GLOBAL(_outsw_ns)
        blr     
 
 _GLOBAL(_insl_ns)
+       cmpw    0,r5,0
        mtctr   r5
        subi    r4,r4,4
+       blelr-
 00:    lwz     r5,0(r3)
        eieio
        stwu    r5,4(r4)
@@ -487,8 +505,10 @@ _GLOBAL(_insl_ns)
        blr
 
 _GLOBAL(_outsl_ns)
+       cmpw    0,r5,0
        mtctr   r5
        subi    r4,r4,4
+       blelr-
 00:    lwzu    r5,4(r4)
        stw     r5,0(r3)
        eieio
@@ -929,7 +949,7 @@ _GLOBAL(sys_call_table)
        .long sys_sigpending
        .long sys_sethostname
        .long sys_setrlimit     /* 75 */
-       .long sys_getrlimit
+       .long sys_old_getrlimit
        .long sys_getrusage
        .long sys_gettimeofday
        .long sys_settimeofday
@@ -1047,4 +1067,5 @@ _GLOBAL(sys_call_table)
        .long sys_ni_syscall            /* streams1 */
        .long sys_ni_syscall            /* streams2 */
        .long sys_vfork
-       .space (NR_syscalls-183)*4
+       .long sys_getrlimit     /* 190 */
+       .space (NR_syscalls-190)*4
index 9f3f58a384f9a5ff43113bd3513cbb55b5286281..4b0375433f0bfd9fd37cd064befc5f9174a97c38 100644 (file)
@@ -63,9 +63,15 @@ struct hw_interrupt_type open_pic = {
 #define check_arg_pri(pri) \
     if (pri < 0 || pri >= OPENPIC_NUM_PRI) \
        printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri);
-#define check_arg_irq(irq) \
+/*
+ * Turned this check off since the IPI's are treated as irqs
+ * but they're above NumSources -- Cort
+ */
+#define check_arg_irq(irq)
+#if 0
     if (irq < 0 || irq >= (NumSources+open_pic.irq_offset)) \
        printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);
+#endif
 #define check_arg_cpu(cpu) \
     if (cpu < 0 || cpu >= NumProcessors) \
        printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu);
@@ -201,15 +207,12 @@ void __init openpic_init(int main_pic)
                /* Initialize IPI interrupts */
                if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb);
                for (i = 0; i < OPENPIC_NUM_IPI; i++) {
-                       /* Disabled, Priority 0 */
-                       openpic_initipi(i, 0, OPENPIC_VEC_IPI+i);
+                       /* Disabled, Priority 8 */
+                       openpic_initipi(i, 8, OPENPIC_VEC_IPI+i);
                }
            
                /* Initialize external interrupts */
                if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc);
-               /* SIOint (8259 cascade) is special */
-               openpic_initirq(0, 8, open_pic.irq_offset, 1, 1);
-               openpic_mapirq(0, 1<<0);
                for (i = 1; i < NumSources; i++) {
                        /* Enabled, Priority 8 */
                        openpic_initirq(i, 8, open_pic.irq_offset+i, 0,
@@ -223,6 +226,9 @@ void __init openpic_init(int main_pic)
                openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
                if ( _machine != _MACH_gemini )
                {
+                       /* SIOint (8259 cascade) is special */
+                       openpic_initirq(0, 8, open_pic.irq_offset, 1, 1);
+                       openpic_mapirq(0, 1<<0);
                        if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT,
                                        "82c59 cascade", NULL))
                                printk("Unable to get OpenPIC IRQ 0 for cascade\n");
index ea2b1c2c16109f17cd7b8609e4b1bc6bd684fb1c..054eee9189c8bb8888cadfa9b08e046a77fc82eb 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/config.h>
 #include <linux/openpic.h>
 
 #include <asm/processor.h>
index 1b1850a77faca74ffae473ad4e14c0e94d499add..99bfa4f8b8f8ad481362b9c43df97f74f5ec2f41 100644 (file)
@@ -4,13 +4,10 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/stddef.h>
-#include <linux/reboot.h>
 #include <linux/nvram.h>
 #include <linux/init.h>
 #include <asm/init.h>
-#include <asm/ptrace.h>
 #include <asm/io.h>
-#include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/prom.h>
 #include <linux/adb.h>
index bcd8a2c2b2dea143eee69f6d3146ad0d9340e4b2..a9166da348baf66ac15b146e03751b32de388fda 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <asm/init.h>
 #include <asm/io.h>
-#include <asm/pgtable.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <asm/machdep.h>
index b858ea0d1e33c64937e2a751d1fb2d847ca9b0c2..11d2cd114237143f12b2726ccb85a63e786b3b43 100644 (file)
@@ -225,13 +225,14 @@ EXPORT_SYMBOL(find_type_devices);
 EXPORT_SYMBOL(find_compatible_devices);
 EXPORT_SYMBOL(find_path_device);
 EXPORT_SYMBOL(find_phandle);
+EXPORT_SYMBOL(device_is_compatible);
+EXPORT_SYMBOL(machine_is_compatible);
 EXPORT_SYMBOL(get_property);
 EXPORT_SYMBOL(pci_io_base);
 EXPORT_SYMBOL(pci_device_loc);
 EXPORT_SYMBOL(feature_set);
 EXPORT_SYMBOL(feature_clear);
 EXPORT_SYMBOL(feature_test);
-EXPORT_SYMBOL(device_is_compatible);
 #endif /* defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) */
 #if defined(CONFIG_SCSI) && (defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC))
 EXPORT_SYMBOL(note_scsi_host);
index d0c03685d348655c5747886d9e34d458d3706d9f..caffdcf99a46c4dbc7ed37cb1e3bf00822512391 100644 (file)
@@ -330,6 +330,30 @@ int get_cpuinfo(char *buffer)
        return len;
 }
 
+#ifndef CONFIG_MACH_SPECIFIC
+void __init
+intuit_machine_type(void)
+{
+       char *model;
+       struct device_node *root;
+                       
+       /* ask the OF info if we're a chrp or pmac */
+       root = find_path_device("/");
+       if (root != 0) {
+               /* assume pmac unless proven to be chrp -- Cort */
+               _machine = _MACH_Pmac;
+               model = get_property(root, "device_type", NULL);
+               if (model && !strncmp("chrp", model, 4))
+                       _machine = _MACH_chrp;
+               else {
+                       model = get_property(root, "model", NULL);
+                       if (model && !strncmp(model, "IBM", 3))
+                               _machine = _MACH_chrp;
+               }
+       }
+}
+#endif /* CONFIG_MACH_SPECIFIC */
+
 /*
  * Find out what kind of machine we're on and save any data we need
  * from the early boot process (devtree is copied on pmac by prom_init() )
@@ -362,34 +386,7 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
                {
                        _machine = _MACH_prep;
                } else
-               {
-                       char *model;
-                       struct device_node *root;
-                       
                        have_of = 1;
-                       
-                       /* prom_init has already been called from __start */
-                       if (boot_infos)
-                               relocate_nodes();
-                       
-                       /* ask the OF info if we're a chrp or pmac */
-                       /* we need to set _machine before calling finish_device_tree */
-                       root = find_path_device("/");
-                       if (root != 0) {
-                               /* assume pmac unless proven to be chrp -- Cort */
-                               _machine = _MACH_Pmac;
-                               model = get_property(root, "device_type", NULL);
-                               if (model && !strncmp("chrp", model, 4))
-                                       _machine = _MACH_chrp;
-                               else {
-                                       model = get_property(root, "model", NULL);
-                                       if (model && !strncmp(model, "IBM", 3))
-                                               _machine = _MACH_chrp;
-                               }
-                       }
-                       
-                       finish_device_tree();
-               }
        }
 #endif /* CONFIG_MACH_SPECIFIC */
 
@@ -398,7 +395,13 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
                /* prom_init has already been called from __start */
                if (boot_infos)
                        relocate_nodes();
+#ifndef CONFIG_MACH_SPECIFIC
+               /* we need to set _machine before calling finish_device_tree */
+               if (_machine == 0)
+                       intuit_machine_type();
+#endif /* CONFIG_MACH_SPECIFIC */
                finish_device_tree();
+
                /*
                 * If we were booted via quik, r3 points to the physical
                 * address of the command-line parameters.
index 3293b284c7b51d20d4452c32b5cc164fa27849f2..fad7c7c1d07cb23f86bf56167f21edc3896d51be 100644 (file)
@@ -161,14 +161,15 @@ void smp_message_recv(void)
 void smp_send_reschedule(int cpu)
 {
        /*
+        * This is only used if `cpu' is running an idle task,
+        * so it will reschedule itself anyway...
+        *
         * This isn't the case anymore since the other CPU could be
         * sleeping and won't reschedule until the next interrupt (such
         * as the timer).
         *  -- Cort
         */
-       /* This is only used if `cpu' is running an idle task,
-          so it will reschedule itself anyway... */
-       /*smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);*/
+       smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);
 }
 
 void smp_send_stop(void)
@@ -310,7 +311,6 @@ void __init smp_boot_cpus(void)
                        openpic_enable_IPI(i);
                 cpu_nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK)>>2;
                 cpu_nr = (cpu_nr == 0) ? 4 : cpu_nr;
-cpu_nr = 2;            
                break;
        }
 
index 5eb60537c2661704fd41d76c013a567931571a05..40741dac409b4fc760b121565f9037476f5ab03a 100644 (file)
  * len is in words and is always >= 5.
  */
 _GLOBAL(ip_fast_csum)
-       cmpi    0,r4,0
-       beq     10f
        lwz     r0,0(r3)
        lwzu    r5,4(r3)
-       addi    r4,r4,-2
+       addic.  r4,r4,-2
        addc    r0,r0,r5
        mtctr   r4
+       blelr-
 1:     lwzu    r4,4(r3)
        adde    r0,r0,r4
        bdnz    1b
@@ -40,8 +39,6 @@ _GLOBAL(ip_fast_csum)
        not     r3,r3
        srwi    r3,r3,16
        blr
-10:    li      r3,0
-       blr     
 
 /*
  * Compute checksum of TCP or UDP pseudo-header:
index d4ca2fb8257ad6551e740bf71ffb7c75cf7eff12..397083aca118734dd4aa0f105c1a9b5b891c8d4a 100644 (file)
@@ -324,24 +324,23 @@ void show_mem(void)
 
 void si_meminfo(struct sysinfo *val)
 {
-       int i;
+       int i, c;
 
        i = max_mapnr;
-       val->totalram = 0;
-       val->sharedram = 0;
+       val->totalram = totalram_pages;
        val->freeram = nr_free_pages();
        val->bufferram = atomic_read(&buffermem_pages);
+       val->sharedram = 0;
        while (i-- > 0)  {
                if (PageReserved(mem_map+i))
                        continue;
-               val->totalram++;
-               if (!atomic_read(&mem_map[i].count))
-                       continue;
-               val->sharedram += atomic_read(&mem_map[i].count) - 1;
+               c = atomic_read(&mem_map[i].count);
+               if (c > 1)
+                       val->sharedram += c - 1;
        }
-       val->totalram <<= PAGE_SHIFT;
-       val->sharedram <<= PAGE_SHIFT;
-       return;
+       val->totalhigh = 0;
+       val->freehigh = 0;
+       val->mem_unit = PAGE_SIZE;
 }
 
 void *
@@ -716,7 +715,7 @@ static void __init mapin_ram(void)
                                f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE;
 #ifndef CONFIG_8xx
                        else
-                               /* On the powerpc (not 8xx), no user access
+                               /* On the powerpc, denying user access
                                   forces R/W kernel access */
                                f |= _PAGE_USER;
 #endif /* CONFIG_8xx */
@@ -875,7 +874,7 @@ void __init MMU_init(void)
                setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
                break;
        case _MACH_Pmac:
-#if 0
+#if 1
                {
                        unsigned long base = 0xf3000000;
                        struct device_node *macio = find_devices("mac-io");
@@ -968,6 +967,7 @@ void __init do_init_bootmem(void)
 
        /* remove the bootmem bitmap from the available memory */
        mem_pieces_remove(&phys_avail, start, boot_mapsize, 1);
+
        /* add everything in phys_avail into the bootmem map */
        for (i = 0; i < phys_avail.n_regions; ++i)
                free_bootmem(phys_avail.regions[i].address,
@@ -1053,9 +1053,9 @@ void __init mem_init(void)
        int codepages = 0;
        int datapages = 0;
        int initpages = 0;
-#if defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)    
+#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
        extern unsigned int rtas_data, rtas_size;
-#endif /* defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) */
+#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */
        max_mapnr = max_low_pfn;
        high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
        num_physpages = max_mapnr;      /* RAM is assumed contiguous */
@@ -1071,13 +1071,13 @@ void __init mem_init(void)
        }
 #endif /* CONFIG_BLK_DEV_INITRD */
 
-#if defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)    
+#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
        /* mark the RTAS pages as reserved */
        if ( rtas_data )
                for (addr = rtas_data; addr < PAGE_ALIGN(rtas_data+rtas_size) ;
                     addr += PAGE_SIZE)
                        SetPageReserved(mem_map + MAP_NR(addr));
-#endif /* defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) */
+#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */
        
        for (addr = PAGE_OFFSET; addr < (unsigned long)end_of_DRAM;
             addr += PAGE_SIZE) {
@@ -1088,12 +1088,12 @@ void __init mem_init(void)
                else if (addr >= (unsigned long)&__init_begin
                         && addr < (unsigned long)&__init_end)
                        initpages++;
-               else if (addr < (ulong) klimit)
+               else
                        datapages++;
        }
 
         printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08x,%08lx]\n",
-              (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+              (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
               codepages << (PAGE_SHIFT-10),
               datapages << (PAGE_SHIFT-10), 
               initpages << (PAGE_SHIFT-10),
index 737b82a0a9e4407be6df2f592923e56e99e675f6..6dbe045da7dd9a1e2e691c70fc29daccb5118ea9 100644 (file)
@@ -17,7 +17,6 @@
 #ifndef __MEM_PIECES_H__
 #define        __MEM_PIECES_H__
 
-#include <linux/config.h>
 #include <linux/init.h>
 
 
index 9a46f1aeeea4857af4284f0614ca271b596ef54a..ec281a154eba34e2838c93b38651baba60491792 100644 (file)
@@ -70,4 +70,13 @@ static inline void store_inst(void *p)
     asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
 }
 
+static inline void cflush(void *p)
+{
+    asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
+}
+
+static inline void cinval(void *p)
+{
+    asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
+}
 
index 1b0fffd7128cc831a7fec6787e659cef6966f35a..9fc97b5a9ff115a140ff4e640959314de8057587 100644 (file)
@@ -6,11 +6,11 @@
 #include <asm/machdep.h>
 #include <asm/io.h>
 #include <asm/page.h>
-#include <asm/pgtable.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <asm/prom.h>
 #include <asm/bootx.h>
+#include <asm/processor.h>
 
 static volatile unsigned char *sccc, *sccd;
 unsigned long TXRDY, RXRDY;
@@ -41,7 +41,7 @@ xmon_map_scc(void)
 
 #ifdef CONFIG_BOOTX_TEXT
                if (boot_infos != 0 && find_via_pmu()) {
-                       printk(KERN_INFO "xmon uses screen and keyboard\n");
+                       printk("xmon uses screen and keyboard\n");
                        use_screen = 1;
                        map_bootx_text();
                        return;
index b07d7fc9918ae585c35e7897bd92a0538828d320..f5a42cc29d9132163576b5fb7bf1495d01b25aa9 100644 (file)
@@ -79,6 +79,7 @@ static void remove_bpts(void);
 static void insert_bpts(void);
 static struct bpt *at_breakpoint(unsigned pc);
 static void bpt_cmds(void);
+static void cacheflush(void);
 
 extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned);
 extern void printf(const char *fmt, ...);
@@ -342,11 +343,9 @@ cmds(struct pt_regs *excp)
                case 't':
                        backtrace(excp);
                        break;
-#if 0
                case 'f':
-                       openforth();
+                       cacheflush();
                        break;
-#endif
                case 'h':
                        dump_hash_table();
                        break;
@@ -541,6 +540,30 @@ prregs(struct pt_regs *fp)
               fp->ctr, fp->xer, fp->trap);
 }
 
+void
+cacheflush(void)
+{
+       int cmd;
+       unsigned nflush;
+
+       cmd = inchar();
+       if (cmd != 'i')
+               termch = cmd;
+       scanhex(&adrs);
+       if (termch != '\n')
+               termch = 0;
+       nflush = 1;
+       scanhex(&nflush);
+       nflush = (nflush + 31) / 32;
+       if (cmd != 'i') {
+               for (; nflush > 0; --nflush, adrs += 0x20)
+                       cflush((void *) adrs);
+       } else {
+               for (; nflush > 0; --nflush, adrs += 0x20)
+                       cinval((void *) adrs);
+       }
+}
+
 unsigned int
 read_spr(int n)
 {
index 301cebd1b32103860c5560e823c4fd5b0a5cfde6..050431cfcd87e23fe7088424b2e55a123b71f1c0 100644 (file)
 #include <asm/uaccess.h>
 
 #include "sfp-util.h"
-#include "soft-fp.h"
-#include "single.h"
-#include "double.h"
-#include "quad.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+#include <math-emu/double.h>
+#include <math-emu/quad.h>
 
 #define FLOATFUNC(x) extern int x(void *,void *,void *)
 
diff --git a/arch/sparc/math-emu/sfp-machine.h b/arch/sparc/math-emu/sfp-machine.h
deleted file mode 100644 (file)
index c3f1233..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/* Machine-dependent software floating-point definitions.
-   Sparc userland (_Q_*) version.
-   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Richard Henderson (rth@cygnus.com),
-                 Jakub Jelinek (jj@ultra.linux.cz),
-                 David S. Miller (davem@redhat.com) and
-                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If
-   not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#ifndef _SFP_MACHINE_H
-#define _SFP_MACHINE_H
-   
-#define _FP_W_TYPE_SIZE                32
-#define _FP_W_TYPE             unsigned long
-#define _FP_WS_TYPE            signed long
-#define _FP_I_TYPE             long
-
-#define _FP_MUL_MEAT_S(R,X,Y)                                  \
-  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_D(R,X,Y)                                  \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
-  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_udiv(S,R,X,Y)
-#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
-#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
-#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1), -1
-#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
-#define _FP_NANSIGN_S          0
-#define _FP_NANSIGN_D          0
-#define _FP_NANSIGN_Q          0
-
-#define _FP_KEEPNANFRACP 1
-
-/* If one NaN is signaling and the other is not,
- * we choose that one, otherwise we choose X.
- */
-/* For _Qp_* and _Q_*, this should prefer X, for
- * CPU instruction emulation this should prefer Y.
- * (see SPAMv9 B.2.2 section).
- */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
-  do {                                                         \
-    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)         \
-       && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))     \
-      {                                                                \
-       R##_s = X##_s;                                          \
-       _FP_FRAC_COPY_##wc(R,X);                                \
-      }                                                                \
-    else                                                       \
-      {                                                                \
-       R##_s = Y##_s;                                          \
-       _FP_FRAC_COPY_##wc(R,Y);                                \
-      }                                                                \
-    R##_c = FP_CLS_NAN;                                                \
-  } while (0)
-
-/* Some assembly to speed things up. */
-#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
-  __asm__ ("addcc %r7,%8,%2
-           addxcc %r5,%6,%1
-           addx %r3,%4,%0"                                             \
-          : "=r" ((USItype)(r2)),                                      \
-            "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
-          : "%rJ" ((USItype)(x2)),                                     \
-            "rI" ((USItype)(y2)),                                      \
-            "%rJ" ((USItype)(x1)),                                     \
-            "rI" ((USItype)(y1)),                                      \
-            "%rJ" ((USItype)(x0)),                                     \
-            "rI" ((USItype)(y0))                                       \
-          : "cc")
-
-#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
-  __asm__ ("subcc %r7,%8,%2
-           subxcc %r5,%6,%1
-           subx %r3,%4,%0"                                             \
-          : "=r" ((USItype)(r2)),                                      \
-            "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
-          : "%rJ" ((USItype)(x2)),                                     \
-            "rI" ((USItype)(y2)),                                      \
-            "%rJ" ((USItype)(x1)),                                     \
-            "rI" ((USItype)(y1)),                                      \
-            "%rJ" ((USItype)(x0)),                                     \
-            "rI" ((USItype)(y0))                                       \
-          : "cc")
-
-#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
-  do {                                                                 \
-    /* We need to fool gcc,  as we need to pass more than 10           \
-       input/outputs.  */                                              \
-    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");           \
-    __asm__ __volatile__ ("
-           addcc %r8,%9,%1
-           addxcc %r6,%7,%0
-           addxcc %r4,%5,%%g2
-           addx %r2,%3,%%g1"                                           \
-          : "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
-          : "%rJ" ((USItype)(x3)),                                     \
-            "rI" ((USItype)(y3)),                                      \
-            "%rJ" ((USItype)(x2)),                                     \
-            "rI" ((USItype)(y2)),                                      \
-            "%rJ" ((USItype)(x1)),                                     \
-            "rI" ((USItype)(y1)),                                      \
-            "%rJ" ((USItype)(x0)),                                     \
-            "rI" ((USItype)(y0))                                       \
-          : "cc", "g1", "g2");                                         \
-    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));                        \
-    r3 = _t1; r2 = _t2;                                                        \
-  } while (0)
-
-#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
-  do {                                                                 \
-    /* We need to fool gcc,  as we need to pass more than 10           \
-       input/outputs.  */                                              \
-    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");           \
-    __asm__ __volatile__ ("
-           subcc %r8,%9,%1
-           subxcc %r6,%7,%0
-           subxcc %r4,%5,%%g2
-           subx %r2,%3,%%g1"                                           \
-          : "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
-          : "%rJ" ((USItype)(x3)),                                     \
-            "rI" ((USItype)(y3)),                                      \
-            "%rJ" ((USItype)(x2)),                                     \
-            "rI" ((USItype)(y2)),                                      \
-            "%rJ" ((USItype)(x1)),                                     \
-            "rI" ((USItype)(y1)),                                      \
-            "%rJ" ((USItype)(x0)),                                     \
-            "rI" ((USItype)(y0))                                       \
-          : "cc", "g1", "g2");                                         \
-    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));                        \
-    r3 = _t1; r2 = _t2;                                                        \
-  } while (0)
-
-#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0)
-
-#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
-
-#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)                                        \
-  __asm__ ("addcc %3,%4,%3
-           addxcc %2,%%g0,%2
-           addxcc %1,%%g0,%1
-           addx %0,%%g0,%0"                                            \
-          : "=&r" ((USItype)(x3)),                                     \
-            "=&r" ((USItype)(x2)),                                     \
-            "=&r" ((USItype)(x1)),                                     \
-            "=&r" ((USItype)(x0))                                      \
-          : "rI" ((USItype)(i)),                                       \
-            "0" ((USItype)(x3)),                                       \
-            "1" ((USItype)(x2)),                                       \
-            "2" ((USItype)(x1)),                                       \
-            "3" ((USItype)(x0))                                        \
-          : "cc")
-
-#ifndef __SMP__
-extern struct task_struct *last_task_used_math;
-#endif
-
-/* Obtain the current rounding mode. */
-#ifndef FP_ROUNDMODE
-#ifdef __SMP__
-#define FP_ROUNDMODE   ((current->thread.fsr >> 30) & 0x3)
-#else
-#define FP_ROUNDMODE   ((last_task_used_math->thread.fsr >> 30) & 0x3)
-#endif
-#endif
-
-/* Exception flags. */
-#define FP_EX_INVALID          (1 << 4)
-#define FP_EX_OVERFLOW         (1 << 3)
-#define FP_EX_UNDERFLOW                (1 << 2)
-#define FP_EX_DIVZERO          (1 << 1)
-#define FP_EX_INEXACT          (1 << 0)
-
-#define FP_HANDLE_EXCEPTIONS return _fex
-
-#ifdef __SMP__
-#define FP_INHIBIT_RESULTS ((current->thread.fsr >> 23) & _fex)
-#else
-#define FP_INHIBIT_RESULTS ((last_task_used_math->thread.fsr >> 23) & _fex)
-#endif
-
-#endif
index 38a846c9f267c5eb76802db8038c9551f5ef82d4..b23bbf1bb2a8e2ae5d24dd19bed791cad78966dc 100644 (file)
 #include <asm/uaccess.h>
 
 #include "sfp-util.h"
-#include "soft-fp.h"
-#include "single.h"
-#include "double.h"
-#include "quad.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+#include <math-emu/double.h>
+#include <math-emu/quad.h>
 
 /* QUAD - ftt == 3 */
 #define FMOVQ  0x003
diff --git a/arch/sparc64/math-emu/sfp-machine.h b/arch/sparc64/math-emu/sfp-machine.h
deleted file mode 100644 (file)
index edb3098..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Machine-dependent software floating-point definitions.
-   Sparc64 kernel version.
-   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Richard Henderson (rth@cygnus.com),
-                 Jakub Jelinek (jj@ultra.linux.cz) and
-                 David S. Miller (davem@redhat.com).
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If
-   not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#ifndef _SFP_MACHINE_H
-#define _SFP_MACHINE_H
-   
-#define _FP_W_TYPE_SIZE                64
-#define _FP_W_TYPE             unsigned long
-#define _FP_WS_TYPE            signed long
-#define _FP_I_TYPE             long
-
-#define _FP_MUL_MEAT_S(R,X,Y)                                  \
-  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
-#define _FP_MUL_MEAT_D(R,X,Y)                                  \
-  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
-  _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
-#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_1_udiv(D,R,X,Y)
-#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
-#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1)
-#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1
-#define _FP_NANSIGN_S          0
-#define _FP_NANSIGN_D          0
-#define _FP_NANSIGN_Q          0
-
-#define _FP_KEEPNANFRACP 1
-
-/* If one NaN is signaling and the other is not,
- * we choose that one, otherwise we choose X.
- */
-/* For _Qp_* and _Q_*, this should prefer X, for
- * CPU instruction emulation this should prefer Y.
- * (see SPAMv9 B.2.2 section).
- */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
-  do {                                                         \
-    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)         \
-       && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))     \
-      {                                                                \
-       R##_s = X##_s;                                          \
-       _FP_FRAC_COPY_##wc(R,X);                                \
-      }                                                                \
-    else                                                       \
-      {                                                                \
-       R##_s = Y##_s;                                          \
-       _FP_FRAC_COPY_##wc(R,Y);                                \
-      }                                                                \
-    R##_c = FP_CLS_NAN;                                                \
-  } while (0)
-
-/* Obtain the current rounding mode. */
-#ifndef FP_ROUNDMODE
-#define FP_ROUNDMODE   ((current->thread.xfsr[0] >> 30) & 0x3)
-#endif
-
-/* Exception flags. */
-#define FP_EX_INVALID          (1 << 4)
-#define FP_EX_OVERFLOW         (1 << 3)
-#define FP_EX_UNDERFLOW                (1 << 2)
-#define FP_EX_DIVZERO          (1 << 1)
-#define FP_EX_INEXACT          (1 << 0)
-
-#define FP_HANDLE_EXCEPTIONS return _fex
-
-#define FP_INHIBIT_RESULTS ((current->thread.xfsr[0] >> 23) & _fex)
-
-#endif
index f9bef2dd8c8cd252ddafb9e8292d68b5f9ece91b..89f5e171db70ee73c958f21763a7723a9518b425 100644 (file)
 #define MY_CARD_LIST { MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL }
 #define MY_NUMPORTS 3
 #define MY_BAUD_BASE (7372800 / 16)
-#define MY_INIT atomwide_serial_init
 #define MY_BASE_ADDRESS(ec) \
        ecard_address ((ec), ECARD_IOC, ECARD_SLOW) + (0x2000 >> 2)
 #define MY_PORT_ADDRESS(port,cardaddr) \
        ((cardaddr) + 0x200 - (port) * 0x100)
+
+#define INIT serial_card_atomwide_init
+#define EXIT serial_card_atomwide_exit
+
 #include "serial-card.c"
index 6a8ee528f9b35b8431b288f410ea451e923aa544..d9d73fa9eaecb5ff437f2f16029450058b6ea7ad 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/drivers/char/serial-card.c
  *
- * Copyright (c) 1996 Russell King.
+ * Copyright (c) 1996-1999 Russell King.
  *
  * A generic handler of serial expansion cards that use 16550s or
  * the like.
  *  22-04-1998 RMK     Removed old register_pre_init_serial
  */
 #include <linux/module.h>
+#include <linux/types.h>
 #include <linux/serial.h>
 #include <linux/errno.h>
+#include <linux/init.h>
+
 #include <asm/ecard.h>
+#include <asm/string.h>
 
 #ifndef NUM_SERIALS
 #define NUM_SERIALS    MY_NUMPORTS * MAX_ECARDS
@@ -42,8 +46,6 @@ static struct expansion_card *expcard[MAX_ECARDS];
                __serial_addr[__serial_pcount] = (addr);        \
                __serial_pcount += 1;                           \
        } while (0)
-#undef MY_INIT
-#define MY_INIT init_module
 #else
 #define ADD_ECARD(ec,card)
 #define ADD_PORT(port,addr)
@@ -55,8 +57,7 @@ static inline int serial_register_onedev (unsigned long port, int irq)
 {
     struct serial_struct req;
 
-    memset(&req, 0, sizeof(serial_struct));
-
+    memset(&req, 0, sizeof(req));
     req.baud_base = MY_BAUD_BASE;
     req.irq = irq;
     req.port = port;
@@ -65,7 +66,7 @@ static inline int serial_register_onedev (unsigned long port, int irq)
     return register_serial(&req);
 }
 
-int MY_INIT (void)
+static int __init INIT (void)
 {
     int card = 0;
 
@@ -103,9 +104,9 @@ int MY_INIT (void)
     return card ? 0 : -ENODEV;
 }
 
-#ifdef MODULE
-void cleanup_module (void)
+static void __exit EXIT (void)
 {
+#ifdef MODULE
     int i;
 
     for (i = 0; i < __serial_pcount; i++) {
@@ -116,5 +117,10 @@ void cleanup_module (void)
     for (i = 0; i < MAX_ECARDS; i++)
        if (expcard[i])
            ecard_release (expcard[i]);
-}
 #endif
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(INIT);
+module_exit(EXIT);
index 6a9df75991b64a5c381b302142a519c0568f0de2..734352b31d80f08663ffa44af2d73c29f179796f 100644 (file)
@@ -9,9 +9,12 @@
 #define MY_CARD_LIST { MANU_SERPORT, PROD_SERPORT_DSPORT }
 #define MY_NUMPORTS 2
 #define MY_BAUD_BASE (3686400 / 16)
-#define MY_INIT dualsp_serial_init
 #define MY_BASE_ADDRESS(ec) \
        ecard_address (ec, ECARD_IOC, ECARD_SLOW) + (0x2000 >> 2)
 #define MY_PORT_ADDRESS(port,cardaddress) \
        ((cardaddress) + (port) * 8)
+
+#define INIT serial_card_dualsp_init
+#define EXIT serial_card_dualsp_exit
+
 #include "serial-card.c"
index e2ed170f833723e68eab99d6b47d1f342915c942..4a058db7f42bffc9c45fa2f04bfd7093a9f84969 100644 (file)
@@ -665,7 +665,6 @@ static int cdrom_timer_expiry(ide_drive_t *drive)
        struct packet_command *pc = (struct packet_command *) rq->buffer;
        unsigned long wait = 0;
 
-       printk("in expiry\n");
        /* blank and format can take an extremly long time to
         * complete, if the IMMED bit was not set.
         */
index 4dedb867188f892f2684611539b64be088b6b00e..2a791dede3269b9546ca34a27399ae12c9ece156 100644 (file)
@@ -1176,98 +1176,85 @@ void mdsyncd (void *data)
 
 #ifdef CONFIG_MD_BOOT
 struct {
-       int set;
-       int ints[100];
-       char str[100];
+       unsigned long set;
+       int pers[MAX_MD_DEV];
+       kdev_t devices[MAX_MD_DEV][MAX_REAL];
 } md_setup_args __initdata = {
-       0,{0},{0}
+       0,{0},{{0}}
 };
 
-/* called from init/main.c */
-void __init md_setup(char *str,int *ints)
-{
-       int i;
-       for(i=0;i<=ints[0];i++) {
-               md_setup_args.ints[i] = ints[i];
-               strcpy(md_setup_args.str, str);
-/*      printk ("md: ints[%d]=%d.\n", i, ints[i]);*/
-       }
-       md_setup_args.set=1;
-       return;
-}
-
-void __init do_md_setup(char *str,int *ints)
+/*
+ * Parse the command-line parameters given our kernel, but do not
+ * actually try to invoke the MD device now; that is handled by
+ * md_setup_drive after the low-level disk drivers have initialised.
+ *
+ * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
+ *             assigns the task of parsing integer arguments to the
+ *             invoked program now).  Added ability to initialise all
+ *             the MD devices (by specifying multiple "md=" lines)
+ *             instead of just one.  -- KTK
+ */
+int __init md_setup(char *str)
 {
-       int minor, pers, factor, fault;
-       kdev_t dev;
-       int i=1;
-
-       if(ints[0] < 4) {
-               printk ("md: Too few Arguments (%d).\n", ints[0]);
-               return;
-       }
-   
-       minor=ints[i++];
-   
-       if (minor >= MAX_MD_DEV) {
+       int minor, level, factor, fault, i;
+       kdev_t device;
+       char *devnames, *pername;
+
+       if(get_option(&str, &minor) != 2 ||     /* MD Number */
+          get_option(&str, &level) != 2 ||     /* RAID Personality */
+          get_option(&str, &factor) != 2 ||    /* Chunk Size */
+          get_option(&str, &fault) != 2) {
+               printk("md: Too few arguments supplied to md=.\n");
+               return 0;
+       } else if (minor >= MAX_MD_DEV) {
                printk ("md: Minor device number too high.\n");
-               return;
+               return 0;
+       } else if (md_setup_args.set & (1 << minor)) {
+               printk ("md: Warning - md=%d,... has been specified twice;\n"
+                       "    will discard the first definition.\n", minor);
        }
-
-       pers = 0;
-       
-       switch(ints[i++]) {  /* Raidlevel  */
-       case -1:
+       switch(level) {
 #ifdef CONFIG_MD_LINEAR
-               pers = LINEAR;
-               printk ("md: Setting up md%d as linear device.\n",minor);
-#else 
-               printk ("md: Linear mode not configured." 
-                       "Recompile the kernel with linear mode enabled!\n");
-#endif
+       case -1:
+               level = LINEAR;
+               pername = "linear";
                break;
-       case 0:
-               pers = STRIPED;
-#ifdef CONFIG_MD_STRIPED
-               printk ("md: Setting up md%d as a striped device.\n",minor);
-#else 
-               printk ("md: Striped mode not configured." 
-                       "Recompile the kernel with striped mode enabled!\n");
 #endif
+#ifdef CONFIG_MD_STRIPED
+       case 0:
+               level = STRIPED;
+               pername = "striped";
                break;
-/*      not supported yet
-       case 1:
-               pers = RAID1;
-               printk ("md: Setting up md%d as a raid1 device.\n",minor);
-               break;
-       case 5:
-               pers = RAID5;
-               printk ("md: Setting up md%d as a raid5 device.\n",minor);
-               break;
-*/
-       default:           
-               printk ("md: Unknown or not supported raid level %d.\n", ints[--i]);
-               return;
+#endif
+       default:
+               printk ("md: The kernel has not been configured for raid%d"
+                       " support!\n", level);
+               return 0;
        }
-
-       if(pers) {
-
-         factor=ints[i++]; /* Chunksize  */
-         fault =ints[i++]; /* Faultlevel */
-   
-         pers=pers | factor | (fault << FAULT_SHIFT);   
-   
-         while( str && (dev = name_to_kdev_t(str))) {
-           do_md_add (minor, dev);
-           if((str = strchr (str, ',')) != NULL)
-             str++;
-         }
-
-         do_md_run (minor, pers);
-         printk ("md: Loading md%d.\n",minor);
+       devnames = str;
+       for (i = 0; str; i++) {
+               if ((device = name_to_kdev_t(str))) {
+                       md_setup_args.devices[minor][i] = device;
+               } else {
+                       printk ("md: Unknown device name, %s.\n", str);
+                       return 0;
+               }
+               if ((str = strchr(str, ',')) != NULL)
+                       str++;
        }
-   
+       if (!i) {
+               printk ("md: No devices specified for md%d?\n", minor);
+               return 0;
+       }
+
+       printk ("md: Will configure md%d (%s) from %s, below.\n",
+               minor, pername, devnames);
+       md_setup_args.devices[minor][i] = (kdev_t) 0;
+       md_setup_args.pers[minor] = level | factor | (fault << FAULT_SHIFT);
+       md_setup_args.set |= (1 << minor);
+       return 0;
 }
+
 #endif
 
 void linear_init (void);
@@ -1318,7 +1305,18 @@ int __init md_init (void)
 #ifdef CONFIG_MD_BOOT
 void __init md_setup_drive(void)
 {
-       if(md_setup_args.set)
-               do_md_setup(md_setup_args.str, md_setup_args.ints);
+       int minor, i;
+       kdev_t dev;
+
+       for (minor = 0; minor < MAX_MD_DEV; minor++) {
+               if ((md_setup_args.set & (1 << minor)) == 0)
+                       continue;
+               printk("md: Loading md%d.\n", minor);
+               for (i = 0; (dev = md_setup_args.devices[minor][i]); i++)
+                       do_md_add (minor, dev);
+               do_md_run (minor, md_setup_args.pers[minor]);
+       }
 }
+
+__setup("md=", md_setup);
 #endif
index fa47adbb70feeb2165c405e70ab4591b4d3a7005..e029fcce6cdc253208b890bc1b07d9ec45e56dc2 100644 (file)
@@ -61,6 +61,7 @@ static unsigned int get_timing_sl82c105(ide_pio_data_t *p)
 static int ide_set_drive_pio_mode(ide_drive_t *drive, byte pio)
 {
        ide_hwif_t *hwif = HWIF(drive);
+       ide_startstop_t startstop;
 
        if (pio > 2) {
                /* FIXME: I don't believe that this SELECT_DRIVE is required,
@@ -74,7 +75,7 @@ static int ide_set_drive_pio_mode(ide_drive_t *drive, byte pio)
                OUT_BYTE(0x03, IDE_FEATURE_REG);
                OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
 
-               if (ide_wait_stat(drive, DRIVE_READY,
+               if (ide_wait_stat(&startstop, drive, DRIVE_READY,
                                  BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD)) {
                        printk("%s: drive not ready for command\n",
                               drive->name);
index 536c94a44bf9dfa51fa29b48f40822ff7719598a..c0383af8d9d3098790451d41ee48af5c0007fc2e 100644 (file)
@@ -1072,6 +1072,31 @@ static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
                        return ret;
                break;
 
+       /* Get region settings */
+       case DVD_LU_SEND_RPC_STATE:
+               cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
+               setup_report_key(&cgc, 0, 8);
+
+               if ((ret = cdo->generic_packet(cdi, &cgc)))
+                       return ret;
+
+               ai->lrpcs.type = (buf[4] >> 6) & 3;
+               ai->lrpcs.vra = (buf[4] >> 3) & 7;
+               ai->lrpcs.ucca = buf[4] & 7;
+               ai->lrpcs.region_mask = buf[5];
+               ai->lrpcs.rpc_scheme = buf[6];
+               break;
+
+               /* Set region settings */
+       case DVD_HOST_SEND_RPC_STATE:
+               cdinfo(CD_DVD, "entering DVD_HOST_SEND_RPC_STATE\n");
+               setup_send_key(&cgc, 0, 6);
+               buf[4] = ai->hrpcs.pdrc;
+
+               if ((ret = cdo->generic_packet(cdi, &cgc)))
+                       return ret;
+               break;
+
        default:
                cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type);
                return -ENOTTY;
@@ -1528,6 +1553,9 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
                if (!CDROM_CAN(CDC_LOCK))
                        return -EDRIVE_CANT_DO_THIS;
                keeplocked = arg ? 1 : 0;
+               /* don't unlock the door on multiple opens */
+               if ((cdi->use_count != 1) && !arg)
+                       return -EBUSY;
                return cdo->lock_door(cdi, arg);
                }
 
@@ -1861,14 +1889,19 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
        case CDROMPLAYTRKIND: {
                struct cdrom_ti ti;
                struct cdrom_tocentry entry;
+               struct cdrom_tochdr tochdr;
 
                cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
                IOCTL_IN(arg, struct cdrom_ti, ti);
                entry.cdte_format = CDROM_MSF;
 
                /* get toc entry for start and end track */
-               entry.cdte_track = ti.cdti_trk0;
-               if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry))
+               if (cdo->audio_ioctl(cdi, CDROMREADTOCHDR, &tochdr))
+                       return -EINVAL;
+               entry.cdte_track = ti.cdti_trk1 + 1;
+               if (entry.cdte_track > tochdr.cdth_trk1)
+                       return -EINVAL;
+               if (cdo->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry))
                        return -EINVAL;
 
                cgc.cmd[3] = entry.cdte_addr.msf.minute;
index 4092d6b5589470ddd331963e90c1f4dc263b6449..d42b0f39b3bb99a095fedee4a458e8ef01503566 100644 (file)
@@ -278,7 +278,7 @@ static int lp_check_status(int minor)
        int error = 0;
        unsigned int last = lp_table[minor].last_error;
        unsigned char status = r_str(minor);
-       if (status & LP_PERRORP)
+       if ((status & LP_PERRORP) && !(LP_F(minor) & LP_CAREFUL))
                /* No error. */
                last = 0;
        else if ((status & LP_POUTPA)) {
@@ -293,12 +293,15 @@ static int lp_check_status(int minor)
                        printk(KERN_INFO "lp%d off-line\n", minor);
                }
                error = -EIO;
-       } else {
+       } else if (!(status & LP_PERRORP)) {
                if (last != LP_PERRORP) {
                        last = LP_PERRORP;
                        printk(KERN_INFO "lp%d on fire\n", minor);
                }
                error = -EIO;
+       } else {
+               last = 0; /* Come here if LP_CAREFUL is set and no
+                             errors are reported. */
        }
 
        lp_table[minor].last_error = last;
@@ -542,14 +545,12 @@ static int lp_ioctl(struct inode *inode, struct file *file,
                        else
                                LP_F(minor) &= ~LP_ABORTOPEN;
                        break;
-#ifdef OBSOLETED
                case LPCAREFUL:
                        if (arg)
                                LP_F(minor) |= LP_CAREFUL;
                        else
                                LP_F(minor) &= ~LP_CAREFUL;
                        break;
-#endif
                case LPWAIT:
                        LP_WAIT(minor) = arg;
                        break;
index 369a150c6f0d20dcdbd66289b4aca5ecfe84379f..d236c618bc8e1ecfaaba3bd57a995bf0d22681fa 100644 (file)
@@ -4142,15 +4142,6 @@ int __init rs_init(void)
 {
        int i;
        struct serial_state * state;
-       extern void atomwide_serial_init (void);
-       extern void dualsp_serial_init (void);
-
-#ifdef CONFIG_ATOMWIDE_SERIAL
-       atomwide_serial_init ();
-#endif
-#ifdef CONFIG_DUALSP_SERIAL
-       dualsp_serial_init ();
-#endif
 
        if (timer_table[RS_TIMER].fn) {
                printk("RS_TIMER already set, another serial driver "
index 3b63f3fc1db6596f1171dfa9bd40d810949ffd3f..ffb05161a72ec6cf6842e0d474a379a9b50bbd42 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/spinlock.h>
 #include <linux/ioport.h>
 #define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue * x = NULL
 #endif
 
+/*
+ * Yes, it's unfortunate that we are relying on get_cmos_time
+ * because it is slow (> 1 sec.) and i386 only.         It might be better
+ * to use some of the code from drivers/char/rtc.c in the near future
+ */
+extern unsigned long get_cmos_time(void);
+
 static int acpi_control_thread(void *context);
 static int acpi_do_ulong(ctl_table *ctl,
                         int write,
@@ -70,15 +78,13 @@ static int acpi_do_event(ctl_table *ctl,
                         struct file *file,
                         void *buffer,
                         size_t *len);
-#if 0
-static int acpi_do_sleep_wake(ctl_table *ctl,
-                             int write,
-                             struct file *file,
-                             void *buffer,
-                             size_t *len);
-#endif
+static int acpi_do_sleep(ctl_table *ctl,
+                        int write,
+                        struct file *file,
+                        void *buffer,
+                        size_t *len);
 
-DECLARE_WAIT_QUEUE_HEAD(acpi_idle_wait);
+DECLARE_WAIT_QUEUE_HEAD(acpi_control_wait);
 
 static struct ctl_table_header *acpi_sysctl = NULL;
 
@@ -88,10 +94,16 @@ static struct acpi_facs *acpi_facs = NULL;
 static unsigned long acpi_facp_addr = 0;
 static unsigned long acpi_dsdt_addr = 0;
 
+// current system sleep state (S0 - S4)
+static acpi_sstate_t acpi_sleep_state = ACPI_S0;
+// time sleep began
+static unsigned long acpi_sleep_start = 0;
+
 static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED;
 static volatile u32 acpi_pm1_status = 0;
 static volatile u32 acpi_gpe_status = 0;
 static volatile u32 acpi_gpe_level = 0;
+static volatile acpi_sstate_t acpi_event_state = ACPI_S0;
 static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait);
 
 static spinlock_t acpi_devs_lock = SPIN_LOCK_UNLOCKED;
@@ -153,14 +165,19 @@ static struct ctl_table acpi_table[] =
         &acpi_p_lvl3_lat, sizeof(acpi_p_lvl3_lat),
         0644, NULL, &acpi_do_ulong},
 
+       {ACPI_S0_SLP_TYP, "s0_slp_typ",
+        &acpi_slp_typ[ACPI_S0], sizeof(acpi_slp_typ[ACPI_S0]),
+        0600, NULL, &acpi_do_ulong},
+
+       {ACPI_S1_SLP_TYP, "s1_slp_typ",
+        &acpi_slp_typ[ACPI_S1], sizeof(acpi_slp_typ[ACPI_S1]),
+        0600, NULL, &acpi_do_ulong},
+
        {ACPI_S5_SLP_TYP, "s5_slp_typ",
-        &acpi_slp_typ[5], sizeof(acpi_slp_typ[5]),
+        &acpi_slp_typ[ACPI_S5], sizeof(acpi_slp_typ[ACPI_S5]),
         0600, NULL, &acpi_do_ulong},
 
-#if 0
-       {123, "sleep", (void*) 1, 0, 0600, NULL, &acpi_do_sleep_wake},
-       {124, "wake", NULL, 0, 0600, NULL, &acpi_do_sleep_wake},
-#endif
+       {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},
 
        {0}
 };
@@ -578,6 +595,7 @@ static void acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
        acpi_pm1_status |= pm1_status;
        acpi_gpe_status |= gpe_status;
        spin_unlock_irqrestore(&acpi_event_lock, flags);
+       acpi_event_state = acpi_sleep_state;
        wake_up_interruptible(&acpi_event_wait);
 }
 
@@ -734,6 +752,25 @@ static int acpi_enter_dx(acpi_dstate_t state)
        return status;
 }
 
+/*
+ * Update system time from real-time clock
+ */
+static void acpi_update_clock(void)
+{
+       if (acpi_sleep_start) {
+               unsigned long delta;
+               struct timeval tv;
+               
+               delta = get_cmos_time() - acpi_sleep_start;
+               do_gettimeofday(&tv);
+               tv.tv_sec += delta;
+               do_settimeofday(&tv);
+               
+               acpi_sleep_start = 0;
+       }
+}
+
+
 /*
  * Enter system sleep state
  */
@@ -751,9 +788,14 @@ static void acpi_enter_sx(acpi_sstate_t state)
                typb = ((typb << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK);
 
                if (state != ACPI_S0) {
+                       acpi_sleep_start = get_cmos_time();
                        acpi_enter_dx(ACPI_D3);
+                       acpi_sleep_state = state;
                }
 
+               // clear wake status
+               acpi_write_pm1_status(acpi_facp, ACPI_WAK);
+
                // set SLP_TYPa/b and SLP_EN
                if (acpi_facp->pm1a_cnt) {
                        value = inw(acpi_facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK;
@@ -765,7 +807,15 @@ static void acpi_enter_sx(acpi_sstate_t state)
                }
 
                if (state == ACPI_S0) {
+                       acpi_sleep_state = state;
                        acpi_enter_dx(ACPI_D0);
+                       acpi_sleep_start = 0;
+               }
+               else if (state == ACPI_S1) {
+                       // wait until S1 is entered
+                       while (!(acpi_read_pm1_status(acpi_facp) & ACPI_WAK)) ;
+                       // finished sleeping, update system time
+                       acpi_update_clock();
                }
        }
 }
@@ -983,7 +1033,8 @@ static int acpi_do_event(ctl_table *ctl,
                         size_t *len)
 {
        u32 pm1_status = 0, gpe_status = 0;
-       char str[4 * sizeof(u32) + 7];
+       acpi_sstate_t event_state = 0;
+       char str[27];
        int size;
 
        if (write)
@@ -1003,6 +1054,7 @@ static int acpi_do_event(ctl_table *ctl,
                gpe_status = acpi_gpe_status;
                acpi_gpe_status = 0;
                spin_unlock_irqrestore(&acpi_event_lock, flags);
+               event_state = acpi_event_state;
                
                if (pm1_status || gpe_status)
                        break;
@@ -1013,7 +1065,10 @@ static int acpi_do_event(ctl_table *ctl,
                        return -ERESTARTSYS;
        }
 
-       size = sprintf(str, "0x%08x 0x%08x\n", pm1_status, gpe_status);
+       size = sprintf(str, "0x%08x 0x%08x 0x%01x\n",
+                      pm1_status,
+                      gpe_status,
+                      event_state);
        copy_to_user(buffer, str, size);
        *len = size;
        file->f_pos += size;
@@ -1021,15 +1076,14 @@ static int acpi_do_event(ctl_table *ctl,
        return 0;
 }
 
-#if 0
 /*
- * Sleep or wake system
+ * Enter system sleep state
  */
-static int acpi_do_sleep_wake(ctl_table *ctl,
-                             int write,
-                             struct file *file,
-                             void *buffer,
-                             size_t *len)
+static int acpi_do_sleep(ctl_table *ctl,
+                        int write,
+                        struct file *file,
+                        void *buffer,
+                        size_t *len)
 {
        if (!write) {
                if (file->f_pos) {
@@ -1039,18 +1093,12 @@ static int acpi_do_sleep_wake(ctl_table *ctl,
        }
        else
        {
-               // just shutdown some devices for now
-               if (ctl->data) {
-                       acpi_enter_dx(ACPI_D3);
-               }
-               else {
-                       acpi_enter_dx(ACPI_D0);
-               }
+               acpi_enter_sx(ACPI_S1);
+               acpi_enter_sx(ACPI_S0);
        }
        file->f_pos += *len;
        return 0;
 }
-#endif
 
 /*
  * Initialize and enable ACPI
@@ -1184,11 +1232,11 @@ static int acpi_control_thread(void *context)
        strcpy(current->comm, "acpi");
        
        for(;;) {
-               interruptible_sleep_on(&acpi_idle_wait);
+               interruptible_sleep_on(&acpi_control_wait);
                if (signal_pending(current))
                        break;
 
-               // find all idle devices and set idle timer based on policy
+               // find all idle devices and set idle timer
        }
 
        return 0;
@@ -1199,7 +1247,7 @@ __initcall(acpi_init);
 /*
  * Module visible symbols
  */
-EXPORT_SYMBOL(acpi_idle_wait);
+EXPORT_SYMBOL(acpi_control_wait);
 EXPORT_SYMBOL(acpi_register);
 EXPORT_SYMBOL(acpi_unregister);
 EXPORT_SYMBOL(acpi_wakeup);
index cd7d1c43c003ab3e57a80cc6e6d2074835ddf8e9..19613e8833cf73d356581df8db978fb0ead9a33e 100644 (file)
       0.544   8-May-99    Fix for buggy SROM in Motorola embedded boards using
                            a 21143 by <mmporter@home.com>.
                          Change PCI/EISA bus probing order.
+      0.545  28-Nov-99    Further Moto SROM bug fix from 
+                           <mporter@eng.mcd.mot.com>
+                          Remove double checking for DEBUG_RX in de4x5_dbg_rx()
+                          from report by <geert@linux-m68k.org>
  
     =========================================================================
 */
 
-static const char *version = "de4x5.c:V0.544 1999/5/8 davies@maniac.ultranet.com\n";
+static const char *version = "de4x5.c:V0.545 1999/11/28 davies@maniac.ultranet.com\n";
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -4817,6 +4821,7 @@ type3_infoblock(struct net_device *dev, u_char count, u_char *p)
     } else if ((lp->media == INIT) && (lp->timeout < 0)) {
         lp->ibn = 3;
        lp->active = *p;
+       if (MOTO_SROM_BUG) lp->active = 0;
        lp->infoblock_csr6 = OMR_MII_100;
        lp->useMII = TRUE;
        lp->infoblock_media = ANS;
@@ -5521,14 +5526,12 @@ de4x5_dbg_rx(struct sk_buff *skb, int len)
               (u_char)skb->data[12],
               (u_char)skb->data[13],
               len);
-       if (de4x5_debug & DEBUG_RX) {
-           for (j=0; len>0;j+=16, len-=16) {
-               printk("    %03x: ",j);
-               for (i=0; i<16 && i<len; i++) {
-                   printk("%02x ",(u_char)skb->data[i+j]);
-               }
-               printk("\n");
-           }
+       for (j=0; len>0;j+=16, len-=16) {
+         printk("    %03x: ",j);
+         for (i=0; i<16 && i<len; i++) {
+           printk("%02x ",(u_char)skb->data[i+j]);
+         }
+         printk("\n");
        }
     }
 
index 9baf82381e4f89af5071c09c90ebab557b3992a0..a4b074fa012f3e2b11cca0670dfba13a0fbd2c27 100644 (file)
@@ -2,11 +2,11 @@
 ** hp100.c 
 ** HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters
 **
-** $Id: hp100.c,v 1.57 1998/04/10 16:27:23 perex Exp perex $
+** $Id: hp100.c,v 1.58 1999/11/30 17:20:20 perex Exp perex $
 **
 ** Based on the HP100 driver written by Jaroslav Kysela <perex@jcu.cz>
 ** Extended for new busmaster capable chipsets by 
-** Siegfried "Frieder" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>
+** Siegfried "Frieder" Loeffler (dg1sek) <loeffler@cdi.fr>
 **
 ** Maintained by: Jaroslav Kysela <perex@jcu.cz>
 ** 
@@ -45,6 +45,8 @@
 **   along with this program; if not, write to the Free Software
 **   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
+** 1.57 -> 1.58
+**   - 'no connection found' message is time limited now
 **
 ** 1.56 -> 1.57
 **   - updates for new PCI interface for 2.1 kernels
@@ -1668,7 +1670,20 @@ static int hp100_start_xmit_bm( struct sk_buff *skb, struct net_device *dev )
          hp100_stop_interface( dev );
          if ( ( lp->lan_type = hp100_sense_lan( dev ) ) < 0 )
            {
-             printk( "hp100: %s: no connection found - check wire\n", dev->name );
+              /* Added Mon Nov 1 06:13:19 1999 by Brian Moore
+               * (mooreb@iname.com) to prevent too much kernel IO
+               * in the case of not having a network connection
+               */
+              {
+                int thistime = jiffies;
+                static int delaytime = 10*HZ;
+                static int lasttime = thistime - delaytime;
+                // We don't worry about rollover
+                if(thistime >= (lasttime + delaytime)) {
+                  printk( "hp100: %s: no connection found - check wire\n", dev->name );
+                  lasttime = thistime;
+                }
+              }
              hp100_start_interface( dev );  /* 10Mb/s RX pkts maybe handled */
              return -EIO;
            }
index 3223f020bc35cadef610cea4c312e3727354de49..28180181afc996d4c6a84b9c218667696539bdbc 100644 (file)
@@ -437,6 +437,7 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
                dev = dev_cache;
                memset(dev, 0, sizeof(*dev));
                dev->bus = bus;
+               dev->sysdata = bus->sysdata;
                dev->devfn  = devfn;
 
                if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
@@ -556,6 +557,7 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
                        child->self = dev;
                        child->parent = bus;
                        child->ops = bus->ops;
+                       child->sysdata = bus->sysdata;
 
                        /*
                         * Set up the primary, secondary and subordinate
index 814e148e18f798caeec0d850a14dbac74500d992..3ec11f0922aac48a31233431414ebc2684997a32 100644 (file)
@@ -56,7 +56,7 @@ struct resource *isapnp_rdp_res = NULL;
 
 int isapnp_disable = 0;                        /* Disable ISA PnP */
 int isapnp_rdp = 0;                    /* Read Data Port */
-int isapnp_reset = 0;                  /* reset all PnP cards (deactivate) */
+int isapnp_reset = 1;                  /* reset all PnP cards (deactivate) */
 int isapnp_skip_pci_scan = 0;          /* skip PCI resource scanning */
 int isapnp_verbose = 1;                        /* verbose mode */
 int isapnp_reserve_irq[16] = { [0 ... 15] = -1 };      /* reserve (don't use) some IRQ */
@@ -129,7 +129,7 @@ static inline void write_data(unsigned char x)
 static inline void write_address(unsigned char x)
 {
        outb(x, _PIDXR);
-       udelay(10);
+       udelay(20);
 }
 
 static inline unsigned char read_data(void)
@@ -240,6 +240,7 @@ void isapnp_deactivate(unsigned char logdev)
 {
        isapnp_device(logdev);
        isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 0);
+       udelay(500);
 }
 
 static void __init isapnp_peek(unsigned char *data, int bytes)
@@ -252,7 +253,7 @@ static void __init isapnp_peek(unsigned char *data, int bytes)
                        d = isapnp_read_byte(0x05);
                        if (d & 1)
                                break;
-                       udelay(10);
+                       udelay(100);
                }
                if (!(d & 1)) {
                        *data++ = 0xff;
@@ -365,7 +366,10 @@ static int __init isapnp_isolate(void)
                        udelay(250);
                        iteration++;
                        isapnp_wake(0x00);
+                       isapnp_set_rdp();
+                       udelay(1000);
                        write_address(0x01);
+                       udelay(1000);
                        goto __next;
                }
                if (iteration == 1) {
index 32352c1e7113383fce0b9153ee8f171c9010006c..19f3d0a8f4110220f547edffae30348b16bca47e 100644 (file)
@@ -605,11 +605,11 @@ static char *isapnp_get_str(char *dest, char *src, int len)
 
 static unsigned char isapnp_get_hex(unsigned char c)
 {
-       if (c >= '0' || c <= '9')
+       if (c >= '0' && c <= '9')
                return c - '0';
-       if (c >= 'a' || c <= 'f')
+       if (c >= 'a' && c <= 'f')
                return (c - 'a') + 10;
-       if (c >= 'A' || c <= 'F')
+       if (c >= 'A' && c <= 'F')
                return (c - 'A') + 10;
        return 0;
 }
index fc0c8ec1c5517c316f2f93bce27a34e8ae5d3781..7f9c04246dbcb20b1bbd795de2206dac9937980e 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/blk.h>
 #include <linux/tqueue.h>
+#include <linux/init.h>
 #include "sd.h"
 #include "scsi.h"
 #include "hosts.h"
@@ -1499,8 +1500,8 @@ aic_outb(struct aic7xxx_host *p, unsigned char val, long port)
  *   to a parameter with a ':' between the parameter and the value.
  *   ie. aic7xxx=unpause:0x0A,extended
  *-F*************************************************************************/
-void
-aic7xxx_setup(char *s, int *dummy)
+static void
+aic7xxx_setup(char *s)
 {
   int   i, n;
   char *p;
@@ -1639,6 +1640,8 @@ aic7xxx_setup(char *s, int *dummy)
   }
 }
 
+__setup("aic7xxx=", aix7xxx_setup);
+
 /*+F*************************************************************************
  * Function:
  *   pause_sequencer
index 972dea19d7d7f436c40209bbe2fc88c1e7760814..938fdd6af3256448c95ffb6accaf9d62dfaa71ba 100644 (file)
@@ -126,11 +126,30 @@ struct {
 #define PCI_ID_LOW     0x00    /* vendor id */
 #define PCI_ID_HIGH    0x02    /* device id */
 #define ISP_CFG0       0x04    /* configuration register #0 */
+#define  ISP_CFG0_HWMSK  0x000f        /* Hardware revision mask */
+#define  ISP_CFG0_1020  0x0001 /* ISP1020 */
+#define  ISP_CFG0_1020A         0x0002 /* ISP1020A */
+#define  ISP_CFG0_1040  0x0003 /* ISP1040 */
+#define  ISP_CFG0_1040A         0x0004 /* ISP1040A */
+#define  ISP_CFG0_1040B         0x0005 /* ISP1040B */
+#define  ISP_CFG0_1040C         0x0006 /* ISP1040C */
 #define ISP_CFG1       0x06    /* configuration register #1 */
+#define  ISP_CFG1_F128  0x0040 /* 128-byte FIFO threshold */
+#define  ISP_CFG1_F64   0x0030 /* 128-byte FIFO threshold */
+#define  ISP_CFG1_F32   0x0020 /* 128-byte FIFO threshold */
+#define  ISP_CFG1_F16   0x0010 /* 128-byte FIFO threshold */
+#define  ISP_CFG1_BENAB         0x0004 /* Global Bus burst enable */
+#define  ISP_CFG1_SXP   0x0001 /* SXP register select */
 #define PCI_INTF_CTL   0x08    /* pci interface control */
 #define PCI_INTF_STS   0x0a    /* pci interface status */
 #define PCI_SEMAPHORE  0x0c    /* pci semaphore */
 #define PCI_NVRAM      0x0e    /* pci nvram interface */
+#define CDMA_CONF      0x20    /* Command DMA Config */
+#define DDMA_CONF      0x40    /* Data DMA Config */
+#define  DMA_CONF_SENAB         0x0008 /* SXP to DMA Data enable */
+#define  DMA_CONF_RIRQ  0x0004 /* RISC interrupt enable */
+#define  DMA_CONF_BENAB         0x0002 /* Bus burst enable */
+#define  DMA_CONF_DIR   0x0001 /* DMA direction (0=fifo->host 1=host->fifo) */
 
 /* mailbox registers */
 #define MBOX0          0x70    /* mailbox 0 */
@@ -489,6 +508,7 @@ struct dev_param {
 #define QUEUE_ENTRY_LEN                64
 
 struct isp1020_hostdata {
+       u_long  memaddr;
        u_char  revision;
        struct  host_param host_param;
        struct  dev_param dev_param[MAX_TARGETS];
@@ -535,15 +555,33 @@ static void       isp1020_print_scsi_cmd(Scsi_Cmnd *);
 static void    isp1020_print_status_entry(struct Status_Entry *);
 #endif
 
+static inline u_short isp_inw(struct Scsi_Host *host, long offset)
+{
+       struct isp1020_hostdata *h = (struct isp1020_hostdata *)host->hostdata;
+       if (h->memaddr)
+               return readw(h->memaddr + offset);
+       else
+               return inw(host->io_port + offset);
+}
+
+static inline void isp_outw(u_short val, struct Scsi_Host *host, long offset)
+{
+       struct isp1020_hostdata *h = (struct isp1020_hostdata *)host->hostdata;
+       if (h->memaddr)
+               writew(val, h->memaddr + offset);
+       else
+               outw(val, host->io_port + offset);
+}
+
 static inline void isp1020_enable_irqs(struct Scsi_Host *host)
 {
-       outw(ISP_EN_INT|ISP_EN_RISC, host->io_port + PCI_INTF_CTL);
+       isp_outw(ISP_EN_INT|ISP_EN_RISC, host, PCI_INTF_CTL);
 }
 
 
 static inline void isp1020_disable_irqs(struct Scsi_Host *host)
 {
-       outw(0x0, host->io_port + PCI_INTF_CTL);
+       isp_outw(0x0, host, PCI_INTF_CTL);
 }
 
 
@@ -604,8 +642,8 @@ int isp1020_detect(Scsi_Host_Template *tmpt)
 
                request_region(host->io_port, 0xff, "qlogicisp");
 
-               outw(0x0, host->io_port + PCI_SEMAPHORE);
-               outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+               isp_outw(0x0, host, PCI_SEMAPHORE);
+               isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
                isp1020_enable_irqs(host);
 
                hosts++;
@@ -625,7 +663,7 @@ int isp1020_release(struct Scsi_Host *host)
 
        hostdata = (struct isp1020_hostdata *) host->hostdata;
 
-       outw(0x0, host->io_port + PCI_INTF_CTL);
+       isp_outw(0x0, host, PCI_INTF_CTL);
        free_irq(host->irq, host);
 
        release_region(host->io_port, 0xff);
@@ -645,9 +683,10 @@ const char *isp1020_info(struct Scsi_Host *host)
 
        hostdata = (struct isp1020_hostdata *) host->hostdata;
        sprintf(buf,
-               "QLogic ISP1020 SCSI on PCI bus %02x device %02x irq %d base 0x%lx",
+               "QLogic ISP1020 SCSI on PCI bus %02x device %02x irq %d %s base 0x%lx",
                hostdata->pci_dev->bus->number, hostdata->pci_dev->devfn, host->irq,
-               host->io_port);
+               (host->io_port ? "I/O" : "MEM"),
+               (host->io_port ? host->io_port : hostdata->memaddr));
 
        LEAVE("isp1020_info");
 
@@ -680,7 +719,7 @@ int isp1020_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
 
        DEBUG(isp1020_print_scsi_cmd(Cmnd));
 
-       out_ptr = inw(host->io_port + MBOX4);
+       out_ptr = isp_inw(host, + MBOX4);
        in_ptr  = hostdata->req_in_ptr;
 
        DEBUG(printk("qlogicisp : request queue depth %d\n",
@@ -709,7 +748,7 @@ int isp1020_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
                hostdata->send_marker = 0;
 
                if (((in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN) == out_ptr) {
-                       outw(in_ptr, host->io_port + MBOX4);
+                       isp_outw(in_ptr, host, MBOX4);
                        hostdata->req_in_ptr = in_ptr;
                        printk("qlogicisp : request queue overflow\n");
                        return 1;
@@ -785,7 +824,7 @@ int isp1020_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
                cmd->segment_cnt = cpu_to_le16(1);
        }
 
-       outw(in_ptr, host->io_port + MBOX4);
+       isp_outw(in_ptr, host, MBOX4);
        hostdata->req_in_ptr = in_ptr;
 
        num_free = QLOGICISP_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
@@ -824,16 +863,16 @@ void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
 
        DEBUG_INTR(printk("qlogicisp : interrupt on line %d\n", irq));
 
-       if (!(inw(host->io_port + PCI_INTF_STS) & 0x04)) {
+       if (!(isp_inw(host, PCI_INTF_STS) & 0x04)) {
                /* spurious interrupts can happen legally */
                DEBUG_INTR(printk("qlogicisp: got spurious interrupt\n"));
                return;
        }
-       in_ptr = inw(host->io_port + MBOX5);
-       outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+       in_ptr = isp_inw(host, MBOX5);
+       isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
 
-       if ((inw(host->io_port + PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) {
-               status = inw(host->io_port + MBOX0);
+       if ((isp_inw(host, PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) {
+               status = isp_inw(host, MBOX0);
 
                DEBUG_INTR(printk("qlogicisp : mbox completion status: %x\n",
                                  status));
@@ -850,7 +889,7 @@ void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
                        printk("qlogicisp : bad mailbox return status\n");
                        break;
                }
-               outw(0x0, host->io_port + PCI_SEMAPHORE);
+               isp_outw(0x0, host, PCI_SEMAPHORE);
        }
        out_ptr = hostdata->res_out_ptr;
 
@@ -882,7 +921,7 @@ void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
                else
                        Cmnd->result = DID_ERROR << 16;
 
-               outw(out_ptr, host->io_port + MBOX5);
+               isp_outw(out_ptr, host, MBOX5);
                (*Cmnd->scsi_done)(Cmnd);
        }
        hostdata->res_out_ptr = out_ptr;
@@ -1078,28 +1117,28 @@ static int isp1020_reset_hardware(struct Scsi_Host *host)
 
        ENTER("isp1020_reset_hardware");
 
-       outw(ISP_RESET, host->io_port + PCI_INTF_CTL);
+       isp_outw(ISP_RESET, host, PCI_INTF_CTL);
        udelay(100);
-       outw(HCCR_RESET, host->io_port + HOST_HCCR);
+       isp_outw(HCCR_RESET, host, HOST_HCCR);
        udelay(100);
-       outw(HCCR_RELEASE, host->io_port + HOST_HCCR);
-       outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR);
+       isp_outw(HCCR_RELEASE, host, HOST_HCCR);
+       isp_outw(HCCR_BIOS_DISABLE, host, HOST_HCCR);
 
        loop_count = DEFAULT_LOOP_COUNT;
-       while (--loop_count && inw(host->io_port + HOST_HCCR) == RISC_BUSY)
+       while (--loop_count && isp_inw(host, HOST_HCCR) == RISC_BUSY)
                barrier();
        if (!loop_count)
                printk("qlogicisp: reset_hardware loop timeout\n");
 
-       outw(0, host->io_port + ISP_CFG1);
+       isp_outw(0, host, ISP_CFG1);
 
 #if DEBUG_ISP1020
-       printk("qlogicisp : mbox 0 0x%04x \n", inw(host->io_port + MBOX0));
-       printk("qlogicisp : mbox 1 0x%04x \n", inw(host->io_port + MBOX1));
-       printk("qlogicisp : mbox 2 0x%04x \n", inw(host->io_port + MBOX2));
-       printk("qlogicisp : mbox 3 0x%04x \n", inw(host->io_port + MBOX3));
-       printk("qlogicisp : mbox 4 0x%04x \n", inw(host->io_port + MBOX4));
-       printk("qlogicisp : mbox 5 0x%04x \n", inw(host->io_port + MBOX5));
+       printk("qlogicisp : mbox 0 0x%04x \n", isp_inw(host, MBOX0));
+       printk("qlogicisp : mbox 1 0x%04x \n", isp_inw(host, MBOX1));
+       printk("qlogicisp : mbox 2 0x%04x \n", isp_inw(host, MBOX2));
+       printk("qlogicisp : mbox 3 0x%04x \n", isp_inw(host, MBOX3));
+       printk("qlogicisp : mbox 4 0x%04x \n", isp_inw(host, MBOX4));
+       printk("qlogicisp : mbox 5 0x%04x \n", isp_inw(host, MBOX5));
 #endif /* DEBUG_ISP1020 */
 
        param[0] = MBOX_NO_OP;
@@ -1164,7 +1203,7 @@ static int isp1020_reset_hardware(struct Scsi_Host *host)
 
 static int isp1020_init(struct Scsi_Host *sh)
 {
-       u_long io_base, io_flags;
+       u_long io_base, mem_base, io_flags, mem_flags;
        struct isp1020_hostdata *hostdata;
        u_char revision;
        u_int irq;
@@ -1184,7 +1223,9 @@ static int isp1020_init(struct Scsi_Host *sh)
        }
 
        io_base = pdev->resource[0].start;
+       mem_base = pdev->resource[1].start;
        io_flags = pdev->resource[0].flags;
+       mem_flags = pdev->resource[1].flags;
        irq = pdev->irq;
 
        if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) {
@@ -1200,6 +1241,8 @@ static int isp1020_init(struct Scsi_Host *sh)
        }
 
 #ifdef __sparc__
+       if (mem_base)
+               mem_base = __pa(mem_base);
        command |= (PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY|
                    PCI_COMMAND_INVALIDATE|PCI_COMMAND_SERR);
        pci_write_config_word(pdev, PCI_COMMAND, command);
@@ -1208,11 +1251,20 @@ static int isp1020_init(struct Scsi_Host *sh)
        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
 #endif
 
-       if (! ((command & PCI_COMMAND_IO)
-              && ((io_flags & PCI_BASE_ADDRESS_SPACE)
-                  == PCI_BASE_ADDRESS_SPACE_IO))) {
-               printk("qlogicisp : i/o mapping is disabled\n");
-               return 1;
+       if ((command & PCI_COMMAND_MEMORY) &&
+           ((mem_flags & 1) == 0)) {
+               mem_base = (u_long) ioremap(mem_base, PAGE_SIZE);
+               hostdata->memaddr = mem_base;
+               io_base = 0;
+       } else {
+               if (command & PCI_COMMAND_IO && (io_flags & 3) != 1)
+               {
+                       printk("qlogicisp : i/o mapping is disabled\n");
+                       return 1;
+               }
+               hostdata->memaddr = 0;
+               sh->io_port = io_base;
+               mem_base = 0;
        }
 
        if (!(command & PCI_COMMAND_MASTER)) {
@@ -1223,18 +1275,18 @@ static int isp1020_init(struct Scsi_Host *sh)
        if (revision != ISP1020_REV_ID)
                printk("qlogicisp : new isp1020 revision ID (%d)\n", revision);
 
-       if (inw(io_base + PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC
-           || inw(io_base + PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020)
+       if (isp_inw(sh,  PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC
+           || isp_inw(sh, PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020)
        {
-               printk("qlogicisp : can't decode i/o address space 0x%lx\n",
-                      io_base);
+               printk("qlogicisp : can't decode %s address space 0x%lx\n",
+                      (io_base ? "I/O" : "MEM"),
+                      (io_base ? io_base : mem_base));
                return 1;
        }
 
        hostdata->revision = revision;
 
        sh->irq = irq;
-       sh->io_port = io_base;
        sh->max_id = MAX_TARGETS;
        sh->max_lun = MAX_LUNS;
 
@@ -1391,20 +1443,20 @@ u_short isp1020_read_nvram_word(struct Scsi_Host *host, u_short byte)
 
        for (i = 8; i >= 0; i--) {
                output = ((byte >> i) & 0x1) ? 0x4 : 0x0;
-               outw(output | 0x2, host->io_port + PCI_NVRAM); NVRAM_DELAY();
-               outw(output | 0x3, host->io_port + PCI_NVRAM); NVRAM_DELAY();
-               outw(output | 0x2, host->io_port + PCI_NVRAM); NVRAM_DELAY();
+               isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY();
+               isp_outw(output | 0x3, host, PCI_NVRAM); NVRAM_DELAY();
+               isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY();
        }
 
        for (i = 0xf, value = 0; i >= 0; i--) {
                value <<= 1;
-               outw(0x3, host->io_port + PCI_NVRAM); NVRAM_DELAY();
-               input = inw(host->io_port + PCI_NVRAM); NVRAM_DELAY();
-               outw(0x2, host->io_port + PCI_NVRAM); NVRAM_DELAY();
+               isp_outw(0x3, host, PCI_NVRAM); NVRAM_DELAY();
+               input = isp_inw(host, PCI_NVRAM); NVRAM_DELAY();
+               isp_outw(0x2, host, PCI_NVRAM); NVRAM_DELAY();
                if (input & 0x8) value |= 1;
        }
 
-       outw(0x0, host->io_port + PCI_NVRAM); NVRAM_DELAY();
+       isp_outw(0x0, host, PCI_NVRAM); NVRAM_DELAY();
 
        return value;
 }
@@ -1454,7 +1506,7 @@ static int isp1020_load_parameters(struct Scsi_Host *host)
        int i, k;
        u_int queue_addr;
        u_short param[6];
-       u_short isp_cfg1;
+       u_short isp_cfg1, hwrev;
        unsigned long flags;
        struct isp1020_hostdata *hostdata =
                (struct isp1020_hostdata *) host->hostdata;
@@ -1464,7 +1516,16 @@ static int isp1020_load_parameters(struct Scsi_Host *host)
        save_flags(flags);
        cli();
 
-       outw(hostdata->host_param.fifo_threshold, host->io_port + ISP_CFG1);
+       hwrev = isp_inw(host, ISP_CFG0) & ISP_CFG0_HWMSK;
+       isp_cfg1 = ISP_CFG1_F64 | ISP_CFG1_BENAB;
+       if (hwrev == ISP_CFG0_1040A) {
+               /* Busted fifo, says mjacob. */
+               isp_cfg1 &= ISP_CFG1_BENAB;
+       }
+
+       isp_outw(isp_inw(host, ISP_CFG1) | isp_cfg1, host, ISP_CFG1);
+       isp_outw(isp_inw(host, CDMA_CONF) | DMA_CONF_BENAB, host, CDMA_CONF);
+       isp_outw(isp_inw(host, DDMA_CONF) | DMA_CONF_BENAB, host, DDMA_CONF);
 
        param[0] = MBOX_SET_INIT_SCSI_ID;
        param[1] = hostdata->host_param.initiator_scsi_id;
@@ -1524,16 +1585,6 @@ static int isp1020_load_parameters(struct Scsi_Host *host)
                return 1;
        }
 
-       isp_cfg1 = inw(host->io_port + ISP_CFG1);
-
-       if (hostdata->host_param.data_dma_burst_enable 
-            || hostdata->host_param.command_dma_burst_enable)
-               isp_cfg1 |= 0x0004;
-       else
-               isp_cfg1 &= 0xfffb;
-
-       outw(isp_cfg1, host->io_port + ISP_CFG1);
-
        param[0] = MBOX_SET_TAG_AGE_LIMIT;
        param[1] = hostdata->host_param.tag_aging;
 
@@ -1646,47 +1697,47 @@ static int isp1020_mbox_command(struct Scsi_Host *host, u_short param[])
                return 1;
 
        loop_count = DEFAULT_LOOP_COUNT;
-       while (--loop_count && inw(host->io_port + HOST_HCCR) & 0x0080)
+       while (--loop_count && isp_inw(host, HOST_HCCR) & 0x0080)
                barrier();
        if (!loop_count)
                printk("qlogicisp: mbox_command loop timeout #1\n");
 
        switch(mbox_param[param[0]] >> 4) {
-             case 6: outw(param[5], host->io_port + MBOX5);
-             case 5: outw(param[4], host->io_port + MBOX4);
-             case 4: outw(param[3], host->io_port + MBOX3);
-             case 3: outw(param[2], host->io_port + MBOX2);
-             case 2: outw(param[1], host->io_port + MBOX1);
-             case 1: outw(param[0], host->io_port + MBOX0);
+             case 6: isp_outw(param[5], host, MBOX5);
+             case 5: isp_outw(param[4], host, MBOX4);
+             case 4: isp_outw(param[3], host, MBOX3);
+             case 3: isp_outw(param[2], host, MBOX2);
+             case 2: isp_outw(param[1], host, MBOX1);
+             case 1: isp_outw(param[0], host, MBOX0);
        }
 
-       outw(0x0, host->io_port + PCI_SEMAPHORE);
-       outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
-       outw(HCCR_SET_HOST_INTR, host->io_port + HOST_HCCR);
+       isp_outw(0x0, host, PCI_SEMAPHORE);
+       isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
+       isp_outw(HCCR_SET_HOST_INTR, host, HOST_HCCR);
 
        loop_count = DEFAULT_LOOP_COUNT;
-       while (--loop_count && !(inw(host->io_port + PCI_INTF_STS) & 0x04))
+       while (--loop_count && !(isp_inw(host, PCI_INTF_STS) & 0x04))
                barrier();
        if (!loop_count)
                printk("qlogicisp: mbox_command loop timeout #2\n");
 
        loop_count = DEFAULT_LOOP_COUNT;
-       while (--loop_count && inw(host->io_port + MBOX0) == 0x04)
+       while (--loop_count && isp_inw(host, MBOX0) == 0x04)
                barrier();
        if (!loop_count)
                printk("qlogicisp: mbox_command loop timeout #3\n");
 
        switch(mbox_param[param[0]] & 0xf) {
-             case 6: param[5] = inw(host->io_port + MBOX5);
-             case 5: param[4] = inw(host->io_port + MBOX4);
-             case 4: param[3] = inw(host->io_port + MBOX3);
-             case 3: param[2] = inw(host->io_port + MBOX2);
-             case 2: param[1] = inw(host->io_port + MBOX1);
-             case 1: param[0] = inw(host->io_port + MBOX0);
+             case 6: param[5] = isp_inw(host, MBOX5);
+             case 5: param[4] = isp_inw(host, MBOX4);
+             case 4: param[3] = isp_inw(host, MBOX3);
+             case 3: param[2] = isp_inw(host, MBOX2);
+             case 2: param[1] = isp_inw(host, MBOX1);
+             case 1: param[0] = isp_inw(host, MBOX0);
        }
 
-       outw(0x0, host->io_port + PCI_SEMAPHORE);
-       outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+       isp_outw(0x0, host, PCI_SEMAPHORE);
+       isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
 
        return 0;
 }
index e65bbccaaad5aeb554d703e0237e143dea71a791..91f511dea0b91711b987e822cbecc4e01a253acf 100644 (file)
@@ -691,10 +691,10 @@ static inline int port_detect \
    char *bus_type, dma_name[16];
 
    /* Allowed BIOS base addresses (NULL indicates reserved) */
-   void *bios_segment_table[8] = {
-      NULL,
-      (void *) 0xc4000, (void *) 0xc8000, (void *) 0xcc000, (void *) 0xd0000,
-      (void *) 0xd4000, (void *) 0xd8000, (void *) 0xdc000
+   unsigned long bios_segment_table[8] = {
+      0,
+      0xc4000, 0xc8000, 0xcc000, 0xd0000,
+      0xd4000, 0xd8000, 0xdc000
       };
 
    /* Allowed IRQs */
index 8949eaa81ee6fc219925428b8ee3c9352e0f76de..2942d4ffc9718a46a6be198190cc2436684ad5b4 100644 (file)
@@ -82,6 +82,7 @@
  *    03.09.99   0.21  change read semantics for MIDI to match
  *                     OSS more closely; remove possible wakeup race
  *    28.10.99   0.22  More waitqueue races fixed
+ *    01.12.99   0.23  New argument to allocate_resource
  *
  */
 
@@ -2433,7 +2434,7 @@ static int __init init_sonicvibes(void)
 
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
-       printk(KERN_INFO "sv: version v0.22 time " __TIME__ " " __DATE__ "\n");
+       printk(KERN_INFO "sv: version v0.23 time " __TIME__ " " __DATE__ "\n");
 #if 0
        if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
                printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
@@ -2457,7 +2458,7 @@ static int __init init_sonicvibes(void)
                        memcpy(ddmaname, sv_ddma_name, ddmanamelen);
                        pcidev->resource[RESOURCE_DDMA].name = ddmaname;
                        if (allocate_resource(&ioport_resource, pcidev->resource+RESOURCE_DDMA, 
-                                             2*SV_EXTENT_DMA, 0x1000, 0x10000-2*SV_EXTENT_DMA, 1024)) {
+                                             2*SV_EXTENT_DMA, 0x1000, 0x10000-2*SV_EXTENT_DMA, 1024, pcidev)) {
                                pcidev->resource[RESOURCE_DDMA].name = NULL;
                                kfree(ddmaname);
                                printk(KERN_ERR "sv: cannot allocate DDMA controller io ports\n");
index 0d2145347ed664c7e83de4354c834a4ae44f2c06..5af458b68579a10c7cf9dbb4c7853f75d99cdd9f 100644 (file)
@@ -1656,7 +1656,7 @@ vnc_private_ioctl(int dev, unsigned int cmd, caddr_t arg)
 
                if (prev_auto_state != devc->no_autoselect)
                        vnc_configure_mixer(devc);
-               waveartist_mixer_set(devc, SOUND_MIXER_RECSRC, SOUND_MASK_MIC);
+
                return 0;
        }
 
index 176dbd768151cd97e4e18088ba7108fcb1f960d0..0a0f5ad0b24106ae1fd963231fc8ed8ef14b4c0c 100644 (file)
@@ -212,6 +212,8 @@ static ssize_t write_mouse(struct file * file,
 
 /*
  * Look like a PS/2 mouse, please..
+ * In XFree86 (3.3.5 tested) you must select Protocol "NetMousePS/2",
+ *  then use your wheel as Button 4 and 5 via ZAxisMapping 4 5.
  *
  * The PS/2 protocol is fairly strange, but
  * oh, well, it's at least common..
index 14a36172df840ec8426494e7bcf9ea2d798cd5f5..d8591ef17026ff29fc5a80d90965a6d91535daa2 100644 (file)
@@ -275,7 +275,7 @@ if [ "$CONFIG_FB" = "y" ]; then
              "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
              "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
              "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
-             "$CONFIG_FB_ATY128" = "m" -o \    
+             "$CONFIG_FB_ATY128" = "m" -o \
               "$CONFIG_FB_SGIVW" = "m" ]; then
            define_tristate CONFIG_FBCON_CFB32 m
         fi
index eec19a2858d7d567cf6e0214bfe2adf59d6d15d2..304efa31dcd9bcb75a2439760f782f724fc21b6d 100644 (file)
@@ -418,15 +418,19 @@ acornfb_set_timing(struct fb_var_screeninfo *var)
 
        ext_ctl = acornfb_default_econtrol();
 
-       if (var->sync & FB_SYNC_HOR_HIGH_ACT)
-               ext_ctl |= VIDC20_ECTL_HS_HSYNC;
-       else
-               ext_ctl |= VIDC20_ECTL_HS_NHSYNC;
+       if (var->sync & FB_SYNC_COMP_HIGH_ACT) /* should be FB_SYNC_COMP */
+               ext_ctl |= VIDC20_ECTL_HS_NCSYNC | VIDC20_ECTL_VS_NCSYNC;
+       else {
+               if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+                       ext_ctl |= VIDC20_ECTL_HS_HSYNC;
+               else
+                       ext_ctl |= VIDC20_ECTL_HS_NHSYNC;
 
-       if (var->sync & FB_SYNC_VERT_HIGH_ACT)
-               ext_ctl |= VIDC20_ECTL_VS_VSYNC;
-       else
-               ext_ctl |= VIDC20_ECTL_VS_NVSYNC;
+               if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+                       ext_ctl |= VIDC20_ECTL_VS_VSYNC;
+               else
+                       ext_ctl |= VIDC20_ECTL_VS_NVSYNC;
+       }
 
        outl(VIDC20_ECTL | ext_ctl, IO_VIDC_BASE);
 
@@ -1211,43 +1215,55 @@ acornfb_blank(int blank, struct fb_info *info)
  * Everything after here is initialisation!!!
  */
 static struct fb_videomode modedb[] __initdata = {
-       {       /* 640x250 @ 50Hz, 15.6 kHz hsync */
-               NULL, 50, 640, 250, 62500, 185, 123,  38, 21,  76, 3,
+       {       /* 320x256 @ 50Hz */
+               NULL, 50,  320,  256, 125000,  92,  62,  35, 19,  38, 2,
+               FB_SYNC_COMP_HIGH_ACT,
+               FB_VMODE_NONINTERLACED
+       }, {    /* 640x250 @ 50Hz, 15.6 kHz hsync */
+               NULL, 50,  640,  250,  62500, 185, 123,  38, 21,  76, 3,
                0,
                FB_VMODE_NONINTERLACED
        }, {    /* 640x256 @ 50Hz, 15.6 kHz hsync */
-               NULL, 50, 640, 256, 62500, 185, 123,  35, 18,  76, 3,
+               NULL, 50,  640,  256,  62500, 185, 123,  35, 18,  76, 3,
                0,
                FB_VMODE_NONINTERLACED
        }, {    /* 640x512 @ 50Hz, 26.8 kHz hsync */
-               NULL, 50, 640, 512, 41667, 113,  87,  18,  1,  56, 3,
+               NULL, 50,  640,  512,  41667, 113,  87,  18,  1,  56, 3,
                0,
                FB_VMODE_NONINTERLACED
        }, {    /* 640x250 @ 70Hz, 31.5 kHz hsync */
-               NULL, 70, 640, 250, 39722,  48,  16, 109, 88,  96, 2,
+               NULL, 70,  640,  250,  39722,  48,  16, 109, 88,  96, 2,
                0,
                FB_VMODE_NONINTERLACED
        }, {    /* 640x256 @ 70Hz, 31.5 kHz hsync */
-               NULL, 70, 640, 256, 39722,  48,  16, 106, 85,  96, 2,
+               NULL, 70,  640,  256,  39722,  48,  16, 106, 85,  96, 2,
                0,
                FB_VMODE_NONINTERLACED
        }, {    /* 640x352 @ 70Hz, 31.5 kHz hsync */
-               NULL, 70, 640, 352, 39722,  48,  16,  58, 37,  96, 2,
+               NULL, 70,  640,  352,  39722,  48,  16,  58, 37,  96, 2,
                0,
                FB_VMODE_NONINTERLACED
        }, {    /* 640x480 @ 60Hz, 31.5 kHz hsync */
-               NULL, 60, 640, 480, 39722,  48,  16,  32, 11,  96, 2,
+               NULL, 60,  640,  480,  39722,  48,  16,  32, 11,  96, 2,
                0,
                FB_VMODE_NONINTERLACED
        }, {    /* 800x600 @ 56Hz, 35.2 kHz hsync */
-               NULL, 56, 800, 600, 27778, 101,  23,  22,  1, 100, 2,
+               NULL, 56,  800,  600,  27778, 101,  23,  22,  1, 100, 2,
                0,
                FB_VMODE_NONINTERLACED
        }, {    /* 896x352 @ 60Hz, 21.8 kHz hsync */
-               NULL, 60, 896, 352, 41667,  59,  27,   9,  0, 118, 3,
+               NULL, 60,  896,  352,  41667,  59,  27,   9,  0, 118, 3,
+               0,
+               FB_VMODE_NONINTERLACED
+       }, {    /* 1024x 768 @ 60Hz, 48.4 kHz hsync */
+               NULL, 60, 1024,  768,  15385, 160,  24,  29,  3, 136, 6,
                0,
                FB_VMODE_NONINTERLACED
-       },
+       }, {    /* 1280x1024 @ 60Hz, 63.8 kHz hsync */
+               NULL, 60, 1280, 1024,   9090, 186,  96,  38,  1, 160, 3,
+               0,
+               FB_VMODE_NONINTERLACED
+       }
 };
 
 static struct fb_videomode __initdata
index 51d1cb05ed797aac7de61970a5cc1acfd2cc52e5..905e8524aac99c5d246558068fa666fb35b1452c 100644 (file)
@@ -71,6 +71,7 @@
 #include <linux/fb.h>
 #include <asm/atarikb.h>
 
+#include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
 #include <video/fbcon-iplan2p2.h>
index fdf3647abd06eae53b4c62955a4898807bc15d76..1b93ccb4eb899cf67e4169066196ebbb021c84db 100644 (file)
@@ -622,18 +622,32 @@ static int cyber2000fb_decode_crtc(struct par_info *hw, struct fb_var_screeninfo
 static int
 cyber2000fb_decode_clock(struct par_info *hw, struct fb_var_screeninfo *var)
 {
+       static unsigned int divisors_2000[] = { 1, 2, 4, 8 };
+       static unsigned int divisors_2010[] = { 1, 2, 4, 6 };
        unsigned long pll_ps = var->pixclock;
        unsigned long ref_ps = 69842;
+       unsigned int *divisors;
        int div2, div1, mult;
 
        /*
         * Step 1:
-        *   find div2 such that 150MHz < fpll < 220MHz
+        *   find div2 such that 115MHz < fpll < 257MHz
         *   and 0 <= div2 < 4
         */
-       for (div2 = 0; div2 < 4; div2++, pll_ps >>= 1)
-               if (6667 > pll_ps && pll_ps > 4545)
+       if (current_par.dev_id == PCI_DEVICE_ID_INTERG_2010)
+               divisors = divisors_2010;
+       else
+               divisors = divisors_2000;
+
+       for (div2 = 0; div2 < 4; div2++) {
+               unsigned long new_pll;
+
+               new_pll = pll_ps / divisors[div2];
+               if (8696 > new_pll && new_pll > 3891) {
+                       pll_ps = new_pll;
                        break;
+               }
+       }
 
        if (div2 == 4)
                return -EINVAL;
@@ -656,20 +670,22 @@ cyber2000fb_decode_clock(struct par_info *hw, struct fb_var_screeninfo *var)
                        break;
        }
 #else
-       if (pll_ps == 4630) {           /* 216.0, 108.0, 54.00, 27.000 */
-               mult = 181;             /* 4630   9260   18520  37040  */
+                                       /*  /1     /2     /4     /6     /8    */
+                                       /*                      (2010) (2000) */
+       if (pll_ps == 4630) {           /* 216.0, 108.0, 54.00, 36.000 27.000 */
+               mult = 181;             /* 4630   9260   18520  27780  37040  */
                div1 = 12;
-       } else if (pll_ps == 4965) {    /* 201.0, 100.5, 50.25, 25.125 */
-               mult = 211;             /* 4965   9930   19860  39720  */
+       } else if (pll_ps == 4965) {    /* 201.0, 100.5, 50.25, 33.500 25.125 */
+               mult = 211;             /* 4965   9930   19860  29790  39720  */
                div1 = 15;
-       } else if (pll_ps == 5050) {    /* 198.0,  99.0, 49.50, 24.750 */
-               mult = 83;              /* 5050   10100  20200  40400  */
+       } else if (pll_ps == 5050) {    /* 198.0,  99.0, 49.50, 33.000 24.750 */
+               mult = 83;              /* 5050   10100  20200  30300  40400  */
                div1 = 6;
-       } else if (pll_ps == 6349) {    /* 158.0,  79.0, 39.50, 19.750 */
-               mult = 209;             /* 6349   12698  25396  50792  */
+       } else if (pll_ps == 6349) {    /* 158.0,  79.0, 39.50, 26.333 19.750 */
+               mult = 209;             /* 6349   12698  25396  38094  50792  */
                div1 = 19;
-       } else if (pll_ps == 6422) {    /* 156.0,  78.0, 39.00, 19.500 */
-               mult = 190;             /* 6422   12844  25688  51376  */
+       } else if (pll_ps == 6422) {    /* 156.0,  78.0, 39.00, 26.000 19.500 */
+               mult = 190;             /* 6422   12844  25688  38532  51376  */
                div1 = 17;
        } else
                return -EINVAL;
@@ -1043,6 +1059,29 @@ static struct fb_ops cyber2000fb_ops =
        cyber2000fb_ioctl
 };
 
+int cyber2000fb_attach(struct cyberpro_info *info)
+{
+       if (current_par.initialised) {
+               info->regs    = CyberRegs;
+               info->fb      = current_par.screen_base;
+               info->fb_size = current_par.screen_size;
+
+               strncpy(info->dev_name, current_par.dev_name, sizeof(info->dev_name));
+
+               MOD_INC_USE_COUNT;
+       }
+
+       return current_par.initialised;
+}
+
+void cyber2000fb_detach(void)
+{
+       MOD_DEC_USE_COUNT;
+}
+
+EXPORT_SYMBOL(cyber2000fb_attach);
+EXPORT_SYMBOL(cyber2000fb_detach);
+
 /*
  * These parameters give
  * 640x480, hsync 31.5kHz, vsync 60Hz
@@ -1244,6 +1283,7 @@ int __init cyber2000fb_init(void)
 
        smem_base = dev->resource[0].start;
        mmio_base = dev->resource[0].start + 0x00800000;
+       current_par.dev_id = dev->device;
 
        /*
         * Map in the registers
index 0fb1f596c8e0ff07ccc2af2ae536acf7b83c8ce2..5810b089a92642cbfbb2afc3c04c168e047315e6 100644 (file)
@@ -51,6 +51,7 @@ struct cyber2000fb_par {
          signed int    currcon;
        char            dev_name[32];
        unsigned int    initialised;
+       unsigned int    dev_id;
 
        /*
         * palette
@@ -82,6 +83,120 @@ struct cyber2000fb_par {
 #define VISUALID_16M           4
 #define VISUALID_32K           6
 
+#define K_CAP_X2_CTL1          0x49
+
+#define CAP_X_START            0x60
+#define CAP_X_END              0x62
+#define CAP_Y_START            0x64
+#define CAP_Y_END              0x66
+#define CAP_DDA_X_INIT         0x68
+#define CAP_DDA_X_INC          0x6a
+#define CAP_DDA_Y_INIT         0x6c
+#define CAP_DDA_Y_INC          0x6e
+
+#define EXT_FIFO_CTL           0x74
+
+#define CAP_PIP_X_START                0x80
+#define CAP_PIP_X_END          0x82
+#define CAP_PIP_Y_START                0x84
+#define CAP_PIP_Y_END          0x86
+
+#define CAP_NEW_CTL1           0x88
+
+#define CAP_NEW_CTL2           0x89
+
+#define CAP_MODE1              0xa4
+#define CAP_MODE1_8BIT                 0x01    /* enable 8bit capture mode     */
+#define CAP_MODE1_CCIR656              0x02    /* CCIR656 mode                 */
+#define CAP_MODE1_IGNOREVGT            0x04    /* ignore VGT                   */
+#define CAP_MODE1_ALTFIFO              0x10    /* use alternate FIFO for capture */
+#define CAP_MODE1_SWAPUV               0x20    /* swap UV bytes                */
+#define CAP_MODE1_MIRRORY              0x40    /* mirror vertically            */
+#define CAP_MODE1_MIRRORX              0x80    /* mirror horizontally          */
+
+#define CAP_MODE2              0xa5
+
+#define Y_TV_CTL               0xae
+
+#define EXT_MEM_START          0xc0            /* ext start address 21 bits */
+#define HOR_PHASE_SHIFT                0xc2            /* high 3 bits */
+#define EXT_SRC_WIDTH          0xc3            /* ext offset phase  10 bits */
+#define EXT_SRC_HEIGHT         0xc4            /* high 6 bits */
+#define EXT_X_START            0xc5            /* ext->screen, 16 bits */
+#define EXT_X_END              0xc7            /* ext->screen, 16 bits */
+#define EXT_Y_START            0xc9            /* ext->screen, 16 bits */
+#define EXT_Y_END              0xcb            /* ext->screen, 16 bits */
+#define EXT_SRC_WIN_WIDTH      0xcd            /* 8 bits */
+#define EXT_COLOUR_COMPARE     0xce            /* 24 bits */
+#define EXT_DDA_X_INIT         0xd1            /* ext->screen 16 bits */
+#define EXT_DDA_X_INC          0xd3            /* ext->screen 16 bits */
+#define EXT_DDA_Y_INIT         0xd5            /* ext->screen 16 bits */
+#define EXT_DDA_Y_INC          0xd7            /* ext->screen 16 bits */
+
+#define VID_FIFO_CTL           0xd9
+
+#define VID_CAP_VFC            0xdb
+#define VID_CAP_VFC_YUV422             0x00    /* formats - does this cause conversion? */
+#define VID_CAP_VFC_RGB555             0x01
+#define VID_CAP_VFC_RGB565             0x02
+#define VID_CAP_VFC_RGB888_24          0x03
+#define VID_CAP_VFC_RGB888_32          0x04
+#define VID_CAP_VFC_DUP_PIX_ZOON       0x08    /* duplicate pixel zoom                 */
+#define VID_CAP_VFC_MOD_3RD_PIX                0x20    /* modify 3rd duplicated pixel          */
+#define VID_CAP_VFC_DBL_H_PIX          0x40    /* double horiz pixels                  */
+#define VID_CAP_VFC_UV128              0x80    /* UV data offset by 128                */
+
+#define VID_DISP_CTL1          0xdc
+#define VID_DISP_CTL1_INTRAM           0x01    /* video pixels go to internal RAM      */
+#define VID_DISP_CTL1_IGNORE_CCOMP     0x02    /* ignore colour compare registers      */
+#define VID_DISP_CTL1_NOCLIP           0x04    /* do not clip to 16235,16240           */
+#define VID_DISP_CTL1_UV_AVG           0x08    /* U/V data is averaged                 */
+#define VID_DISP_CTL1_Y128             0x10    /* Y data offset by 128                 */
+#define VID_DISP_CTL1_VINTERPOL_OFF    0x20    /* vertical interpolation off           */
+#define VID_DISP_CTL1_VID_OUT_WIN_FULL 0x40    /* video out window full                */
+#define VID_DISP_CTL1_ENABLE_VID_WINDOW        0x80    /* enable video window                  */
+
+#define VID_FIFO_CTL1          0xdd
+
+#define VFAC_CTL1              0xe8
+#define VFAC_CTL1_CAPTURE              0x01    /* capture enable                       */
+#define VFAC_CTL1_VFAC_ENABLE          0x02    /* vfac enable                          */
+#define VFAC_CTL1_FREEZE_CAPTURE       0x04    /* freeze capture                       */
+#define VFAC_CTL1_FREEZE_CAPTURE_SYNC  0x08    /* sync freeze capture                  */
+#define VFAC_CTL1_VALIDFRAME_SRC       0x10    /* select valid frame source            */
+#define VFAC_CTL1_PHILIPS              0x40    /* select Philips mode                  */
+#define VFAC_CTL1_MODVINTERPOLCLK      0x80    /* modify vertical interpolation clocl  */
+
+#define VFAC_CTL2              0xe9
+#define VFAC_CTL2_INVERT_VIDDATAVALID  0x01    /* invert video data valid              */
+#define VFAC_CTL2_INVERT_GRAPHREADY    0x02    /* invert graphic ready output sig      */
+#define VFAC_CTL2_INVERT_DATACLK       0x04    /* invert data clock signal             */
+#define VFAC_CTL2_INVERT_HSYNC         0x08    /* invert hsync input                   */
+#define VFAC_CTL2_INVERT_VSYNC         0x10    /* invert vsync input                   */
+#define VFAC_CTL2_INVERT_FRAME         0x20    /* invert frame odd/even input          */
+#define VFAC_CTL2_INVERT_BLANK         0x40    /* invert blank output                  */
+#define VFAC_CTL2_INVERT_OVSYNC                0x80    /* invert other vsync input             */
+
+#define VFAC_CTL3              0xea
+
+#define CAP_MEM_START          0xeb            /* 18 bits */
+#define CAP_MAP_WIDTH          0xed            /* high 6 bits */
+#define CAP_PITCH              0xee            /* 8 bits */
+
+#define CAP_CTL_MISC           0xef
+#define CAP_CTL_MISC_HDIV              0x01
+#define CAP_CTL_MISC_HDIV4             0x02
+#define CAP_CTL_MISC_ODDEVEN           0x04
+#define CAP_CTL_MISC_HSYNCDIV2         0x08
+#define CAP_CTL_MISC_SYNCTZHIGH                0x10
+#define CAP_CTL_MISC_SYNCTZOR          0x20
+#define CAP_CTL_MISC_DISPUSED          0x80
+
+#define REG_BANK               0xfa
+#define REG_BANK_Y                     0x01
+#define REG_BANK_K                     0x05
+
+
 #define CO_CMD_L_PATTERN_FGCOL 0x8000
 #define CO_CMD_L_INC_LEFT      0x0004
 #define CO_CMD_L_INC_UP                0x0002
@@ -102,3 +217,18 @@ struct cyber2000fb_par {
 #define CO_REG_SRC_PTR         0xbf170
 #define CO_REG_DEST_PTR                0xbf178
 #define CO_REG_DEST_WIDTH      0xbf218
+
+struct cyberpro_info {
+       unsigned char   *regs;
+       char            *fb;
+       char            dev_name[32];
+       unsigned int    fb_size;
+};
+
+/*
+ * Note! Writing to the Cyber20x0 registers from an interrupt
+ * routine is definitely a bad idea atm.
+ */
+int cyber2000fb_attach(struct cyberpro_info *info);
+void cyber2000fb_detach(void);
+
index c8a550eb827b4fe88eb6615863114ccdf1fd0e9e..3730695ddcd9e46747233760d0cf53398e0f6849 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/fb.h>
 #include <linux/module.h>
 
+#include <video/fbcon.h>
 #include <video/fbcon-mfb.h>
 
 
index 77336e2231dc9edc39a33af768b644ec7364a074..dfb019fdd4219f30a8b796d42085c747596b19b3 100644 (file)
 #define LOGO_LINE      (LOGO_W/8)
 
 struct display fb_display[MAX_NR_CONSOLES];
+char con2fb_map[MAX_NR_CONSOLES];
 static int logo_lines;
 static int logo_shown = -1;
 /* Software scrollback */
-extern int fbcon_softback_size;
+int fbcon_softback_size = 32768;
 static unsigned long softback_buf, softback_curr;
 static unsigned long softback_in;
 static unsigned long softback_top, softback_end;
@@ -240,6 +241,84 @@ static void cursor_timer_handler(unsigned long dev_addr)
       add_timer(&cursor_timer);
 }
 
+int PROC_CONSOLE(const struct fb_info *info)
+{
+        int fgc;
+        
+        if (info->display_fg != NULL)
+                fgc = info->display_fg->vc_num;
+        else
+                return -1;
+                
+        if (!current->tty)
+                return fgc;
+
+        if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
+                /* XXX Should report error here? */
+                return fgc;
+
+        if (MINOR(current->tty->device) < 1)
+                return fgc;
+
+        return MINOR(current->tty->device) - 1;
+}
+
+int set_all_vcs(int fbidx, struct fb_ops *fb, struct fb_var_screeninfo *var,
+                struct fb_info *info)
+{
+    int unit, err;
+
+    var->activate |= FB_ACTIVATE_TEST;
+    err = fb->fb_set_var(var, PROC_CONSOLE(info), info);
+    var->activate &= ~FB_ACTIVATE_TEST;
+    if (err)
+            return err;
+    for (unit = 0; unit < MAX_NR_CONSOLES; unit++)
+            if (fb_display[unit].conp && con2fb_map[unit] == fbidx)
+                    fb->fb_set_var(var, unit, info);
+    return 0;
+}
+
+void set_con2fb_map(int unit, int newidx)
+{
+    int oldidx = con2fb_map[unit];
+    struct fb_info *oldfb, *newfb;
+    struct vc_data *conp;
+    char *fontdata;
+    unsigned short fontwidth, fontheight, fontwidthlog, fontheightlog;
+    int userfont;
+
+    if (newidx != con2fb_map[unit]) {
+       oldfb = registered_fb[oldidx];
+       newfb = registered_fb[newidx];
+       if (newfb->fbops->fb_open(newfb,0))
+           return;
+       oldfb->fbops->fb_release(oldfb,0);
+       conp = fb_display[unit].conp;
+       fontdata = fb_display[unit].fontdata;
+       fontwidth = fb_display[unit]._fontwidth;
+       fontheight = fb_display[unit]._fontheight;
+       fontwidthlog = fb_display[unit]._fontwidthlog;
+       fontheightlog = fb_display[unit]._fontheightlog;
+       userfont = fb_display[unit].userfont;
+       con2fb_map[unit] = newidx;
+       fb_display[unit] = *(newfb->disp);
+       fb_display[unit].conp = conp;
+       fb_display[unit].fontdata = fontdata;
+       fb_display[unit]._fontwidth = fontwidth;
+       fb_display[unit]._fontheight = fontheight;
+       fb_display[unit]._fontwidthlog = fontwidthlog;
+       fb_display[unit]._fontheightlog = fontheightlog;
+       fb_display[unit].userfont = userfont;
+       fb_display[unit].fb_info = newfb;
+       if (!newfb->changevar)
+           newfb->changevar = oldfb->changevar;
+       /* tell console var has changed */
+       if (newfb->changevar)
+           newfb->changevar(unit);
+   }
+}
+
 /*
  *  Low Level Operations
  */
index 568153a77674fe0eb2068b7d89e93c7939a27b9a..152115043c543d351370ea6a1e017d4cbae5d639 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/mman.h>
 #include <linux/tty.h>
 #include <linux/console.h>
-#include <linux/console_struct.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #ifdef CONFIG_KMOD
 #if defined(__mc68000__) || defined(CONFIG_APUS)
 #include <asm/setup.h>
 #endif
-#ifdef __powerpc__
+
 #include <asm/io.h>
-#endif
 #include <asm/uaccess.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
 #include <linux/fb.h>
-
+#include <video/fbcon.h>
 
     /*
      *  Frame buffer device initialization and setup routines
@@ -228,36 +226,12 @@ static int num_pref_init_funcs __initdata = 0;
 
 struct fb_info *registered_fb[FB_MAX];
 int num_registered_fb = 0;
-int fbcon_softback_size = 32768;
-
-char con2fb_map[MAX_NR_CONSOLES];
+extern int fbcon_softback_size; 
 
 static int first_fb_vc = 0;
 static int last_fb_vc = MAX_NR_CONSOLES-1;
 static int fbcon_is_default = 1;
 
-static int PROC_CONSOLE(const struct fb_info *info)
-{
-       int fgc;
-       
-       if (info->display_fg != NULL)
-               fgc = info->display_fg->vc_num;
-       else
-               return -1;
-               
-       if (!current->tty)
-               return fgc;
-
-       if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
-               /* XXX Should report error here? */
-               return fgc;
-
-       if (MINOR(current->tty->device) < 1)
-               return fgc;
-
-       return MINOR(current->tty->device) - 1;
-}
-
 static int fbmem_read_proc(char *buf, char **start, off_t offset,
                           int len, int *eof, void *private)
 {
@@ -321,63 +295,6 @@ fb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
        return copy_size;
 }
 
-
-static int set_all_vcs(int fbidx, struct fb_ops *fb,
-                      struct fb_var_screeninfo *var, struct fb_info *info)
-{
-    int unit, err;
-
-    var->activate |= FB_ACTIVATE_TEST;
-    err = fb->fb_set_var(var, PROC_CONSOLE(info), info);
-    var->activate &= ~FB_ACTIVATE_TEST;
-    if (err)
-           return err;
-    for (unit = 0; unit < MAX_NR_CONSOLES; unit++)
-           if (fb_display[unit].conp && con2fb_map[unit] == fbidx)
-                   fb->fb_set_var(var, unit, info);
-    return 0;
-}
-
-static void set_con2fb_map(int unit, int newidx)
-{
-    int oldidx = con2fb_map[unit];
-    struct fb_info *oldfb, *newfb;
-    struct vc_data *conp;
-    char *fontdata;
-    unsigned short fontwidth, fontheight, fontwidthlog, fontheightlog;
-    int userfont;
-
-    if (newidx != con2fb_map[unit]) {
-       oldfb = registered_fb[oldidx];
-       newfb = registered_fb[newidx];
-       if (newfb->fbops->fb_open(newfb,0))
-          return;
-       oldfb->fbops->fb_release(oldfb,0);
-       conp = fb_display[unit].conp;
-       fontdata = fb_display[unit].fontdata;
-       fontwidth = fb_display[unit]._fontwidth;
-       fontheight = fb_display[unit]._fontheight;
-       fontwidthlog = fb_display[unit]._fontwidthlog;
-       fontheightlog = fb_display[unit]._fontheightlog;
-       userfont = fb_display[unit].userfont;
-       con2fb_map[unit] = newidx;
-       fb_display[unit] = *(newfb->disp);
-       fb_display[unit].conp = conp;
-       fb_display[unit].fontdata = fontdata;
-       fb_display[unit]._fontwidth = fontwidth;
-       fb_display[unit]._fontheight = fontheight;
-       fb_display[unit]._fontwidthlog = fontwidthlog;
-       fb_display[unit]._fontheightlog = fontheightlog;
-       fb_display[unit].userfont = userfont;
-       fb_display[unit].fb_info = newfb;
-       if (!newfb->changevar)
-          newfb->changevar = oldfb->changevar;
-       /* tell console var has changed */
-       if (newfb->changevar)
-          newfb->changevar(unit);
-    }
-}
-
 #ifdef CONFIG_KMOD
 static void try_to_load(int fb)
 {
index 27a383ece24bd59906c03e932eb1f9f31e19a5cb..5314ece8b1745b86e371c0c7ac75cb1d73f42cad 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/blinken.h>
 #include <asm/hwtest.h>
 
+#include <video/fbcon.h>
 #include <video/fbcon-mfb.h>
 #include <video/fbcon-cfb2.h>
 #include <video/fbcon-cfb4.h>
index 3135ea589d4359a8217c560ce9d96d2a6caa8257..4f8b14d61f2fca7fbcd05f5cc211d3df17631e4a 100644 (file)
@@ -1378,24 +1378,17 @@ out:
        return err;
 }
 
-int block_write_partial_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
+int block_write_range(struct dentry *dentry, struct page *page,
+               unsigned zerofrom, unsigned from, unsigned to,
+               const char * buf)
 {
-       struct dentry *dentry = file->f_dentry;
        struct inode *inode = dentry->d_inode;
+       unsigned zeroto = 0, block_start, block_end;
        unsigned long block;
-       int err, partial;
-       unsigned long blocksize, start_block, end_block;
-       unsigned long start_offset, start_bytes, end_bytes;
-       unsigned long bbits, blocks, i, len;
-       struct buffer_head *bh, *head;
-       char *target_buf, *kaddr;
-       int need_balance_dirty;
-
-       kaddr = (char *)kmap(page);
-       target_buf = kaddr + offset;
-
-       if (!PageLocked(page))
-               BUG();
+       int err = 0, partial = 0, need_balance_dirty = 0;
+       unsigned blocksize, bbits;
+       struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;
+       char *kaddr = (char *)kmap(page);
 
        blocksize = inode->i_sb->s_blocksize;
        if (!page->buffers)
@@ -1404,49 +1397,21 @@ int block_write_partial_page(struct file *file, struct page *page, unsigned long
 
        bbits = inode->i_sb->s_blocksize_bits;
        block = page->index << (PAGE_CACHE_SHIFT - bbits);
-       blocks = PAGE_CACHE_SIZE >> bbits;
-       start_block = offset >> bbits;
-       end_block = (offset + bytes - 1) >> bbits;
-       start_offset = offset & (blocksize - 1);
-       start_bytes = blocksize - start_offset;
-       if (start_bytes > bytes)
-               start_bytes = bytes;
-       end_bytes = (offset+bytes) & (blocksize - 1);
-       if (end_bytes > bytes)
-               end_bytes = bytes;
-
-       if (offset < 0 || offset >= PAGE_SIZE)
-               BUG();
-       if (bytes+offset < 0 || bytes+offset > PAGE_SIZE)
-               BUG();
-       if (start_block < 0 || start_block >= blocks)
-               BUG();
-       if (end_block < 0 || end_block >= blocks)
-               BUG();
 
-       i = 0;
-       bh = head;
-       partial = 0;
-       need_balance_dirty = 0;
-       do {
+       /*
+        * First pass - map what needs to be mapped, initiate reads
+        * on the boundaries if needed (i.e. if block is partially covered
+        * _and_ is not up-to-date _and_ is not new).
+        */
+       for(bh = head, block_start = 0; bh != head || !block_start;
+           block++, block_start=block_end, bh = bh->b_this_page) {
                if (!bh)
                        BUG();
-
-               if ((i < start_block) || (i > end_block)) {
-                       if (!buffer_uptodate(bh))
-                               partial = 1;
-                       goto skip;
-               }
-
-               /*
-                * If the buffer is not up-to-date, we need to ask the low-level
-                * FS to do something for us (we used to have assumptions about
-                * the meaning of b_blocknr etc, that's bad).
-                *
-                * If "update" is set, that means that the low-level FS should
-                * try to make sure that the block is up-to-date because we're
-                * not going to fill it completely.
-                */
+               block_end = block_start+blocksize;
+               if (block_end <= zerofrom)
+                       continue;
+               if (block_start >= to)
+                       break;
                bh->b_end_io = end_buffer_io_sync;
                if (!buffer_mapped(bh)) {
                        err = inode->i_op->get_block(inode, block, bh, 1);
@@ -1454,71 +1419,71 @@ int block_write_partial_page(struct file *file, struct page *page, unsigned long
                                goto out;
                        unmap_underlying_metadata(bh);
                }
-
-               if (!buffer_uptodate(bh) && (start_offset || (end_bytes && (i == end_block)))) {
-                       if (buffer_new(bh)) {
-                               memset(kaddr + i*blocksize, 0, blocksize);
-                       } else {
-                               ll_rw_block(READ, 1, &bh);
-                               wait_on_buffer(bh);
-                               err = -EIO;
-                               if (!buffer_uptodate(bh))
-                                       goto out;
-                       }
-               }
-
-               len = blocksize;
-               if (start_offset) {
-                       len = start_bytes;
-                       start_offset = 0;
-               } else if (end_bytes && (i == end_block)) {
-                       len = end_bytes;
-                       end_bytes = 0;
+               if (buffer_new(bh)) {
+                       zeroto = block_end;
+                       if (block_start < zerofrom)
+                               zerofrom = block_start;
+                       continue;
                }
-               if (target_buf >= kaddr + PAGE_SIZE)
-                       BUG();
-               if (target_buf+len-1 >= kaddr + PAGE_SIZE)
-                       BUG();
-               err = copy_from_user(target_buf, buf, len);
-               target_buf += len;
-               buf += len;
-
-               /*
-                * we dirty buffers only after copying the data into
-                * the page - this way we can dirty the buffer even if
-                * the bh is still doing IO.
-                *
-                * NOTE! This also does a direct dirty balace check,
-                * rather than relying on bdflush just waking up every
-                * once in a while. This is to catch (and slow down)
-                * the processes that write tons of buffer..
-                *
-                * Note how we do NOT want to do this in the full block
-                * case: full pages are flushed not by the people who
-                * dirtied them, but by people who need memory. And we
-                * should not penalize them for somebody else writing
-                * lots of dirty pages.
-                */
-               set_bit(BH_Uptodate, &bh->b_state);
-               if (!test_and_set_bit(BH_Dirty, &bh->b_state)) {
-                       __mark_dirty(bh, 0);
-                       need_balance_dirty = 1;
+               if (!buffer_uptodate(bh) &&
+                    (block_start < zerofrom || block_end > to)) {
+                       ll_rw_block(READ, 1, &bh);
+                       *wait_bh++=bh;
                }
-
-               if (err) {
-                       err = -EFAULT;
+       }
+       /*
+        * If we issued read requests - let them complete.
+        */
+       while(wait_bh > wait) {
+               wait_on_buffer(*--wait_bh);
+               err = -EIO;
+               if (!buffer_uptodate(*wait_bh))
                        goto out;
+       }
+       /*
+        * Now we can copy the data.
+        */
+       if (zerofrom < from)
+               memset(kaddr+zerofrom, 0, from-zerofrom);
+       if (from < to)
+               err = copy_from_user(kaddr+from, buf, to-from);
+       if (to < zeroto)
+               memset(kaddr+to, 0, zeroto-to);
+       if (err < 0)
+               goto out;
+       /*
+        * Second pass: check if all out-of-range blocks are up-to-date
+        * and mark the rest up-to-date and dirty.
+        *
+        * NOTE! This also does a direct dirty balace check,
+        * rather than relying on bdflush just waking up every
+        * once in a while. This is to catch (and slow down)
+        * the processes that write tons of buffer..
+        *
+        * Note how we do NOT want to do this in the full block
+        * case: full pages are flushed not by the people who
+        * dirtied them, but by people who need memory. And we
+        * should not penalize them for somebody else writing
+        * lots of dirty pages.
+        */
+       for(bh = head, block_start = 0;
+           bh != head || !block_start;
+           block_start=block_end, bh = bh->b_this_page) {
+               block_end = block_start + blocksize;
+               if (block_end <= zerofrom || block_start >= zeroto) {
+                       if (!buffer_uptodate(bh))
+                               partial = 1;
+               } else {
+                       set_bit(BH_Uptodate, &bh->b_state);
+                       if (!test_and_set_bit(BH_Dirty, &bh->b_state)) {
+                               __mark_dirty(bh, 0);
+                               need_balance_dirty = 1;
+                       }
                }
-
-skip:
-               i++;
-               block++;
-               bh = bh->b_this_page;
-       } while (bh != head);
+       }
 
        if (need_balance_dirty)
                balance_dirty(bh->b_dev);
-
        /*
         * is this a partial write that happened to make all buffers
         * uptodate then we can optimize away a bogus readpage() for
@@ -1528,183 +1493,48 @@ skip:
        if (!partial)
                SetPageUptodate(page);
        kunmap(page);
-       return bytes;
+       return 0;
 out:
        ClearPageUptodate(page);
        kunmap(page);
        return err;
 }
 
-/*
- * For moronic filesystems that do not allow holes in file.
- * we allow offset==PAGE_SIZE, bytes==0
- */
-
-int block_write_cont_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
+int block_write_partial_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
 {
        struct dentry *dentry = file->f_dentry;
-       struct inode *inode = dentry->d_inode;
-       unsigned long block;
-       int err, partial;
-       unsigned long blocksize, start_block, end_block;
-       unsigned long start_offset, start_bytes, end_bytes;
-       unsigned long bbits, blocks, i, len;
-       struct buffer_head *bh, *head;
-       char * target_buf, *target_data;
-       unsigned long data_offset = offset;
-       int need_balance_dirty;
-
-       offset = inode->i_size - (page->index << PAGE_CACHE_SHIFT);
-       if (page->index > (inode->i_size >> PAGE_CACHE_SHIFT))
-               offset = 0;
-       else if (offset >= data_offset)
-               offset = data_offset;
-       bytes += data_offset - offset;
-
-       target_buf = (char *)page_address(page) + offset;
-       target_data = (char *)page_address(page) + data_offset;
+       int err;
 
        if (!PageLocked(page))
                BUG();
-
-       blocksize = inode->i_sb->s_blocksize;
-       if (!page->buffers)
-               create_empty_buffers(page, inode, blocksize);
-       head = page->buffers;
-
-       bbits = inode->i_sb->s_blocksize_bits;
-       block = page->index << (PAGE_CACHE_SHIFT - bbits);
-       blocks = PAGE_CACHE_SIZE >> bbits;
-       start_block = offset >> bbits;
-       end_block = (offset + bytes - 1) >> bbits;
-       start_offset = offset & (blocksize - 1);
-       start_bytes = blocksize - start_offset;
-       if (start_bytes > bytes)
-               start_bytes = bytes;
-       end_bytes = (offset+bytes) & (blocksize - 1);
-       if (end_bytes > bytes)
-               end_bytes = bytes;
-
-       if (offset < 0 || offset > PAGE_SIZE)
+       if (offset < 0 || offset >= PAGE_SIZE)
                BUG();
        if (bytes+offset < 0 || bytes+offset > PAGE_SIZE)
                BUG();
-       if (start_block < 0 || start_block > blocks)
-               BUG();
-       if (end_block < 0 || end_block >= blocks)
-               BUG();
-
-       i = 0;
-       bh = head;
-       partial = 0;
-       need_balance_dirty = 0;
-       do {
-               if (!bh)
-                       BUG();
 
-               if ((i < start_block) || (i > end_block)) {
-                       if (!buffer_uptodate(bh))
-                               partial = 1;
-                       goto skip;
-               }
-
-               /*
-                * If the buffer is not up-to-date, we need to ask the low-level
-                * FS to do something for us (we used to have assumptions about
-                * the meaning of b_blocknr etc, that's bad).
-                *
-                * If "update" is set, that means that the low-level FS should
-                * try to make sure that the block is up-to-date because we're
-                * not going to fill it completely.
-                */
-               bh->b_end_io = end_buffer_io_sync;
-               if (!buffer_mapped(bh)) {
-                       err = inode->i_op->get_block(inode, block, bh, 1);
-                       if (err)
-                               goto out;
-                       unmap_underlying_metadata(bh);
-               }
-
-               if (!buffer_uptodate(bh) && (start_offset || (end_bytes && (i == end_block)))) {
-                       if (buffer_new(bh)) {
-                               memset(bh->b_data, 0, bh->b_size);
-                       } else {
-                               ll_rw_block(READ, 1, &bh);
-                               wait_on_buffer(bh);
-                               err = -EIO;
-                               if (!buffer_uptodate(bh))
-                                       goto out;
-                       }
-               }
-
-               len = blocksize;
-               if (start_offset) {
-                       len = start_bytes;
-                       start_offset = 0;
-               } else if (end_bytes && (i == end_block)) {
-                       len = end_bytes;
-                       end_bytes = 0;
-               }
-               err = 0;
-               if (target_buf+len<=target_data)
-                       memset(target_buf, 0, len);
-               else if (target_buf<target_data) {
-                       memset(target_buf, 0, target_data-target_buf);
-                       copy_from_user(target_data, buf,
-                                       len+target_buf-target_data);
-               } else
-                       err = copy_from_user(target_buf, buf, len);
-               target_buf += len;
-               buf += len;
-
-               /*
-                * we dirty buffers only after copying the data into
-                * the page - this way we can dirty the buffer even if
-                * the bh is still doing IO.
-                *
-                * NOTE! This also does a direct dirty balace check,
-                * rather than relying on bdflush just waking up every
-                * once in a while. This is to catch (and slow down)
-                * the processes that write tons of buffer..
-                *
-                * Note how we do NOT want to do this in the full block
-                * case: full pages are flushed not by the people who
-                * dirtied them, but by people who need memory. And we
-                * should not penalize them for somebody else writing
-                * lots of dirty pages.
-                */
-               set_bit(BH_Uptodate, &bh->b_state);
-               if (!test_and_set_bit(BH_Dirty, &bh->b_state)) {
-                       __mark_dirty(bh, 0);
-                       need_balance_dirty = 1;
-               }
-
-               if (err) {
-                       err = -EFAULT;
-                       goto out;
-               }
+       err = block_write_range(dentry, page, offset,offset,offset+bytes, buf);
+       return err ? err : bytes;
+}
 
-skip:
-               i++;
-               block++;
-               bh = bh->b_this_page;
-       } while (bh != head);
+/*
+ * For moronic filesystems that do not allow holes in file.
+ * we allow offset==PAGE_SIZE, bytes==0
+ */
 
-       if (need_balance_dirty)
-               balance_dirty(bh->b_dev);
+int block_write_cont_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
+{
+       struct dentry *dentry = file->f_dentry;
+       struct inode *inode = dentry->d_inode;
+       int err;
+       unsigned zerofrom = offset;
 
-       /*
-        * is this a partial write that happened to make all buffers
-        * uptodate then we can optimize away a bogus readpage() for
-        * the next read(). Here we 'discover' wether the page went
-        * uptodate as a result of this (potentially partial) write.
-        */
-       if (!partial)
-               SetPageUptodate(page);
-       return bytes;
-out:
-       ClearPageUptodate(page);
-       return err;
+       if (page->index > (inode->i_size >> PAGE_CACHE_SHIFT))
+               zerofrom = 0;
+       else if (page->index == (inode->i_size >> PAGE_CACHE_SHIFT) &&
+                offset > (inode->i_size & ~PAGE_CACHE_MASK))
+               zerofrom = inode->i_size & ~PAGE_CACHE_MASK;
+       err = block_write_range(dentry, page, zerofrom,offset,offset+bytes,buf);
+       return err ? err : bytes;
 }
 
 
index 5ec306fdfd6039a65fe1e1a5e4904be58edd108a..26db0a62398b698b53d97a9619114c3137200254 100644 (file)
@@ -7,7 +7,6 @@
  * Universite Pierre et Marie Curie (Paris VI)
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 
index e0f7a655c97356eaf52545ba0068758f745e21c3..6c232ce793f2c6fc3ff868f20cf596c58c4e5e27 100644 (file)
@@ -11,7 +11,6 @@
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 #include <linux/quotaops.h>
index ddd0ac12cd80751cf3db6364d709b629b2ae18e8..c0ffb68cdac9905e97deff79e772b6dfbd8cd35e 100644 (file)
@@ -7,7 +7,6 @@
  * Universite Pierre et Marie Curie (Paris VI)
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 
 
index e1f45105e55fbb601f6418347a34504dc4ca8868..131702e3d57fca450f03baa4c4eabdc81ee9684c 100644 (file)
@@ -18,7 +18,6 @@
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 
 
index 987b55f94e917601dda24e59d10621e0930eeb42..cc2d40ab3e381a1de5264ef3b4601afb7234a6a7 100644 (file)
@@ -18,7 +18,6 @@
  *     (jj@sunsite.ms.mff.cuni.cz)
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 
index cd12a68bd1df70f8c58ffb9cbf44861206794e28..f4e02c2e8673ba083bb14d0de79ed294076dfae5 100644 (file)
@@ -22,7 +22,6 @@
  * we can depend on generic_block_fdatasync() to sync the data blocks.
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 
 
index d6953e4cb5fd38f313a2e69ca00e838ecc43855a..ea297d43c4f701aac6b876a82efc6b8f208a23e6 100644 (file)
@@ -12,7 +12,6 @@
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 #include <linux/quotaops.h>
index a980df858823704d8fa785921e86ec30927d440d..e86557e039312fa54e299d2f85c0d515fc8d1375 100644 (file)
@@ -20,7 +20,6 @@
  *     (jj@sunsite.ms.mff.cuni.cz)
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
index a582fd5459ae3fd08dc07f00de54063f97b7de8e..0b456820aeb33f54e11c4fd7a4f7ec354a28608c 100644 (file)
@@ -7,7 +7,6 @@
  * Universite Pierre et Marie Curie (Paris VI)
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <asm/uaccess.h>
index 8bc7532de6e169d98a52d71e3c54693d94ce8534..81a4368484af26c004175fdad9011a68f494f682 100644 (file)
@@ -18,7 +18,6 @@
  *     for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 #include <linux/quotaops.h>
index bf880e68a6b5ebdf862c1402cfa5282fb22b1ccf..03633b2e446378d84a3e68e9b653da243b20f337 100644 (file)
@@ -15,7 +15,6 @@
  *  ext2 symlink handling code
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <asm/uaccess.h>
 
index 653936278dfc64145fa76bc4c42400759830fe35..ba839719669e06359c3323226ca413514a58cc05 100644 (file)
@@ -18,7 +18,6 @@
  *  General cleanup and race fixes, wsh, 1998
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 
index da67d4d52dac3d3fbcf6d6f1170d8f6927c4fa9f..08d4aaf1b97f1d3df18c88e8e10695161bb2659e 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/hfs_fs.h>
 #include <linux/devpts_fs.h>
 #include <linux/bfs_fs.h>
+#include <linux/adfs_fs.h>
 #include <linux/major.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
index acc59370bffc6e4ce709132dd2ae9311d6878b1d..e8f216e26d7281b234e3b69d77021523f0f741b2 100644 (file)
@@ -585,8 +585,8 @@ read_really:
        ctl.head.eof = ctl.valid;
 finished:
        if (page) {
-               kunmap(page);
                cache->head = ctl.head;
+               kunmap(page);
                SetPageUptodate(page);
                UnlockPage(page);
                page_cache_release(page);
index 14bc80e2db6d155d9447bc129c90ab73e51ca305..5bfa4d658befdd7c40ff0fc05b9f236aeade659f 100644 (file)
@@ -291,6 +291,8 @@ union TPchipPERRMASK {
 #define TSUNAMI_IO_BIAS          TSUNAMI_IO(0)
 #define TSUNAMI_MEM_BIAS         TSUNAMI_MEM(0)
 
+/* The IO address space is larger than 0xffff */
+#define TSUNAMI_IO_SPACE       (TSUNAMI_CONF(0) - TSUNAMI_IO(0))
 
 /*
  * Data structure for handling TSUNAMI machine checks:
index 5e56e7db2304c0edc0733f107739da098eee308b..118941b3c86f8560fc20318e70776fab1e7cb247 100644 (file)
@@ -4,6 +4,8 @@
 /*
  * Alpha floating-point control register defines:
  */
+#define FPCR_DNOD      (1UL<<47)       /* denorm INV trap disable */
+#define FPCR_DNZ       (1UL<<48)       /* denorms to zero */
 #define FPCR_INVD      (1UL<<49)       /* invalid op disable (opt.) */
 #define FPCR_DZED      (1UL<<50)       /* division by zero disable (opt.) */
 #define FPCR_OVFD      (1UL<<51)       /* overflow disable (optional) */
 #define IEEE_TRAP_ENABLE_OVF   (1UL<<3)        /* overflow */
 #define IEEE_TRAP_ENABLE_UNF   (1UL<<4)        /* underflow */
 #define IEEE_TRAP_ENABLE_INE   (1UL<<5)        /* inexact */
+#define IEEE_TRAP_ENABLE_DNO   (1UL<<6)        /* denorm */
 #define IEEE_TRAP_ENABLE_MASK  (IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE |\
                                 IEEE_TRAP_ENABLE_OVF | IEEE_TRAP_ENABLE_UNF |\
-                                IEEE_TRAP_ENABLE_INE)
+                                IEEE_TRAP_ENABLE_INE | IEEE_TRAP_ENABLE_DNO)
+
+/* Denorm and Underflow flushing */
+#define IEEE_MAP_DMZ           (1UL<<12)       /* Map denorm inputs to zero */
+#define IEEE_MAP_UMZ           (1UL<<13)       /* Map underflowed outputs to zero */
+
+#define IEEE_MAP_MASK          (IEEE_MAP_DMZ | IEEE_MAP_UMZ)
 
 /* status bits coming from fpcr: */
 #define IEEE_STATUS_INV                (1UL<<17)
 #define IEEE_STATUS_OVF                (1UL<<19)
 #define IEEE_STATUS_UNF                (1UL<<20)
 #define IEEE_STATUS_INE                (1UL<<21)
+#define IEEE_STATUS_DNO                (1UL<<22)
 
 #define IEEE_STATUS_MASK       (IEEE_STATUS_INV | IEEE_STATUS_DZE |    \
                                 IEEE_STATUS_OVF | IEEE_STATUS_UNF |    \
-                                IEEE_STATUS_INE)
+                                IEEE_STATUS_INE | IEEE_STATUS_DNO)
+
+#define IEEE_SW_MASK           (IEEE_TRAP_ENABLE_MASK | IEEE_STATUS_MASK | IEEE_MAP_MASK)
 
-#define IEEE_SW_MASK           (IEEE_TRAP_ENABLE_MASK | IEEE_STATUS_MASK)
+#define IEEE_CURRENT_RM_SHIFT  32
+#define IEEE_CURRENT_RM_MASK   (3UL<<IEEE_CURRENT_RM_SHIFT)
 
 #define IEEE_STATUS_TO_EXCSUM_SHIFT    16
 
@@ -78,6 +91,7 @@ ieee_swcr_to_fpcr(unsigned long sw)
                      | IEEE_TRAP_ENABLE_DZE
                      | IEEE_TRAP_ENABLE_OVF)) << 48;
        fp |= (~sw & (IEEE_TRAP_ENABLE_UNF | IEEE_TRAP_ENABLE_INE)) << 57;
+       fp |= (~sw & IEEE_TRAP_ENABLE_DNO) << 41;
        return fp;
 }
 
@@ -90,6 +104,7 @@ ieee_fpcr_to_swcr(unsigned long fp)
                             | IEEE_TRAP_ENABLE_DZE
                             | IEEE_TRAP_ENABLE_OVF);
        sw |= (~fp >> 57) & (IEEE_TRAP_ENABLE_UNF | IEEE_TRAP_ENABLE_INE);
+       sw |= (~fp >> 41) & IEEE_TRAP_ENABLE_DNO;
        return sw;
 }
 
@@ -124,6 +139,8 @@ static inline void wrfpcr(unsigned long val)
 
 extern unsigned long alpha_read_fp_reg (unsigned long reg);
 extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
+extern unsigned long alpha_read_fp_reg_s (unsigned long reg);
+extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val);
 
 #endif /* __KERNEL__ */
 
index 1f3dc74cded8fcb33bad9d93ba3e01511be6f55b..2c2f82bbd82122a8b6853cfc65e824199ecc8075 100644 (file)
@@ -82,7 +82,7 @@ struct alpha_machine_vector
        void (*init_irq)(void);
        void (*init_pit)(void);
        void (*init_pci)(void);
-       void (*kill_arch)(int, char *);
+       void (*kill_arch)(int);
 
        u8 (*pci_swizzle)(struct pci_dev *, u8 *);
        int (*pci_map_irq)(struct pci_dev *, u8, u8);
index 64d550938066701047607443ea55db3abce4499b..18e316751fd1b781b0c119036e5ee36e756723c4 100644 (file)
@@ -160,6 +160,8 @@ ev4_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm, long cpu)
 
         current->thread.ptbr
          = ((unsigned long) next_mm->pgd - IDENT_ADDR) >> PAGE_SHIFT;
+
+       __reload_thread(&current->thread);
 }
 
 __EXTERN_INLINE void
diff --git a/include/asm-alpha/sfp-machine.h b/include/asm-alpha/sfp-machine.h
new file mode 100644 (file)
index 0000000..8adc0e7
--- /dev/null
@@ -0,0 +1,84 @@
+/* Machine-dependent software floating-point definitions.
+   Alpha kernel version.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jakub@redhat.com) and
+                 David S. Miller (davem@redhat.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _SFP_MACHINE_H
+#define _SFP_MACHINE_H
+   
+#define _FP_W_TYPE_SIZE                64
+#define _FP_W_TYPE             unsigned long
+#define _FP_WS_TYPE            signed long
+#define _FP_I_TYPE             long
+
+#define _FP_MUL_MEAT_S(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_1_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          _FP_QNANBIT_S
+#define _FP_NANFRAC_D          _FP_QNANBIT_D
+#define _FP_NANFRAC_Q          _FP_QNANBIT_Q
+#define _FP_NANSIGN_S          1
+#define _FP_NANSIGN_D          1
+#define _FP_NANSIGN_Q          1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Alpha Architecture Handbook, 4.7.10.4 sais that
+ * we should prefer any type of NaN in Fb, then Fa.
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    R##_s = Y##_s;                                             \
+    _FP_FRAC_COPY_##wc(R,X);                                   \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+/* Obtain the current rounding mode. */
+#define FP_ROUNDMODE   mode
+#define FP_RND_NEAREST (FPCR_DYN_NORMAL >> FPCR_DYN_SHIFT)
+#define FP_RND_ZERO    (FPCR_DYN_CHOPPED >> FPCR_DYN_SHIFT)
+#define FP_RND_PINF    (FPCR_DYN_PLUS >> FPCR_DYN_SHIFT)
+#define FP_RND_MINF    (FPCR_DYN_MINUS >> FPCR_DYN_SHIFT)
+
+/* Exception flags. */
+#define FP_EX_INVALID          IEEE_TRAP_ENABLE_INV
+#define FP_EX_OVERFLOW         IEEE_TRAP_ENABLE_OVF
+#define FP_EX_UNDERFLOW                IEEE_TRAP_ENABLE_UNF
+#define FP_EX_DIVZERO          IEEE_TRAP_ENABLE_DZE
+#define FP_EX_INEXACT          IEEE_TRAP_ENABLE_INE
+#define FP_EX_DENORM           IEEE_TRAP_ENABLE_DNO
+
+#define FP_DENORM_ZERO         (fpcw & IEEE_MAP_DMZ)
+
+#define FP_HANDLE_EXCEPTIONS return _fex
+
+/* We write the results always */
+#define FP_INHIBIT_RESULTS 0
+
+#endif
index 1478a8f235a0287ea3a5e484f9da96900aabfd79..767730a4cdad1a30899470cc18f46c49fbe1be09 100644 (file)
@@ -8,20 +8,20 @@
 
 #include <asm/iomd.h>
 
-#define arch_reset(mode) {                                             \
-       outb (0, IOMD_ROMCR0);                                          \
-       cli();                                                          \
-       __asm__ __volatile__("msr  spsr, r1;"                           \
-                            "mcr  p15, 0, %0, c1, c0, 0;"              \
-                            "movs pc, #0"                              \
-                        :                                              \
-                        : "r" (cpu_reset()));                          \
+#define arch_reset(mode) {                     \
+       outb (0, IOMD_ROMCR0);                  \
+       cli();                                  \
+       __asm__ __volatile__(                   \
+               "mcr    p15, 0, %0, c1, c0, 0;" \
+               "mov    pc, #0"                 \
+        :                                      \
+        : "r" (cpu_reset()));                  \
        }
 
 /*
  * We can wait for an interrupt...
  */
-#define proc_idle()                                            \
+#define arch_do_idle()                         \
        outb(0, IOMD_SUSMODE)
 
 #endif
index 0642276270af6f4e88fc79c0568f2df0fc4640d7..05e2be70719cceb9aa86d601b0ce4208497032c8 100644 (file)
@@ -6,7 +6,16 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#define arch_do_idle()         do { } while (0)
-#define arch_reset(mode)       do { } while (0)
+#define arch_do_idle()         cpu_do_idle()
+
+extern __inline__ void arch_reset(char mode)
+{
+       if (mode == 's') {
+               __asm__ volatile(
+               "mcr    p15, 0, %0, c1, c0, 0   @ MMU off
+                mov    pc, #0x80000000         @ jump to flash"
+               : : "r" (cpu_reset()) : "cc");
+       }
+}
 
 #endif
index 24a22d31c7990416361f6ca496cbe9780580d029..ee7573804c7c775ed335e11bba5ac89dac26661c 100644 (file)
@@ -14,9 +14,9 @@ extern __inline__ void arch_reset(char mode)
 {
        if (mode == 's') {
                __asm__ volatile (
-               "mov    lr, #0x41000000         @ prepare to jump to ROM
-                mcr    p15, 0, %0, c1, c0, 0   @ MMU off
-                mov    pc, lr" : : "r" (cpu_reset()) : "cc");
+               "mcr    p15, 0, %0, c1, c0, 0   @ MMU off
+                mov    pc, #0x41000000         @ jump to ROM" : :
+               "r" (cpu_reset()) : "cc");
        } else {
                if (machine_is_netwinder()) {
                        /* open up the SuperIO chip
index 2ff5aba7e9d45c5c9e19a6e78491ec4190212a18..24072c298d67fa972f46a853671a4b740d40fd68 100644 (file)
 
 #else
 
-#define arch_reset( x ) {                                      \
+#define arch_reset(x) {                                                \
        __asm__ volatile (                                      \
 "      mcr     p15, 0, %0, c1, c0      @ MMU off\n"            \
-"      mov     pc, #0\n" : : "r" (cpu_reset()));               \
+"      mov     pc, #0\n" : : "r" (cpu_reset()) : "cc");        \
        }
 
 #endif
index 12f25731f11d2ee03409cd4ac09519c349007212..0964c435d481a23faf23a4a6c49470a0763f00c3 100644 (file)
@@ -43,7 +43,7 @@ extern void kmap_init(void) __init;
  * easily, subsequent pte tables have to be allocated in one physical
  * chunk of RAM.
  */
-#define PKMAP_BASE (0xff000000UL)
+#define PKMAP_BASE (0xfe000000UL)
 #ifdef CONFIG_X86_PAE
 #define LAST_PKMAP 512
 #else
index 1cabd8a3d1c4336e13e36effe1b274504e8c17a7..48cb099b71f56aa50757741d427847fdd86d1658 100644 (file)
@@ -56,8 +56,17 @@ typedef struct {
        "jmp 1b\n" \
        ".previous"
 
+/*
+ * Sadly, some early PPro chips require the locked access,
+ * otherwise we could just always simply do
+ *
+ *     #define spin_unlock_string \
+ *             "movb $0,%0"
+ *
+ * Which is noticeably faster.
+ */
 #define spin_unlock_string \
-       "movb $0,%0"
+       "lock ; btrl $0,%0"
 
 extern inline void spin_lock(spinlock_t *lock)
 {
index 602d4370965e3d7660cf48a4d2899e882e00d91d..cc32d941ff8e5fe9800c35330f4122e5f299a570 100644 (file)
@@ -10,7 +10,7 @@
 #define _PPC_BOOTINFO_H
 
 struct bi_record {
-    unsigned short tag;                        /* tag ID */
+    unsigned long tag;                 /* tag ID */
     unsigned long size;                        /* size of record (in bytes) */
     unsigned long data[0];             /* data */
 };
index 374e0107d010728f265bc388130ed117a81b3872..76c696ca981a81ad7bcbd0e54f6e1466949a0ed8 100644 (file)
@@ -1,7 +1,82 @@
 #ifndef _PPC_PGALLOC_H
 #define _PPC_PGALLOC_H
 
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <asm/processor.h>
 
+/*
+ * This is handled very differently on the PPC since out page tables
+ * are all 0's and I want to be able to use these zero'd pages elsewhere
+ * as well - it gives us quite a speedup.
+ *
+ * Note that the SMP/UP versions are the same but we don't need a
+ * per cpu list of zero pages because we do the zero-ing with the cache
+ * off and the access routines are lock-free but the pgt cache stuff
+ * is per-cpu since it isn't done with any lock-free access routines
+ * (although I think we need arch-specific routines so I can do lock-free).
+ *
+ * I need to generalize this so we can use it for other arch's as well.
+ * -- Cort
+ */
+#ifdef __SMP__
+#define quicklists     cpu_data[smp_processor_id()]
+#else
+extern struct pgtable_cache_struct {
+       unsigned long *pgd_cache;
+       unsigned long *pte_cache;
+       unsigned long pgtable_cache_sz;
+} quicklists;
+#endif
+
+#define pgd_quicklist          (quicklists.pgd_cache)
+#define pmd_quicklist          ((unsigned long *)0)
+#define pte_quicklist          (quicklists.pte_cache)
+#define pgtable_cache_size     (quicklists.pgtable_cache_sz)
+
+extern unsigned long *zero_cache;    /* head linked list of pre-zero'd pages */
+extern atomic_t zero_sz;            /* # currently pre-zero'd pages */
+extern atomic_t zeropage_hits;      /* # zero'd pages request that we've done */
+extern atomic_t zeropage_calls;      /* # zero'd pages request that've been made */
+extern atomic_t zerototal;          /* # pages zero'd over time */
+
+#define zero_quicklist         (zero_cache)
+#define zero_cache_sz                  (zero_sz)
+#define zero_cache_calls       (zeropage_calls)
+#define zero_cache_hits        (zeropage_hits)
+#define zero_cache_total       (zerototal)
+
+/* return a pre-zero'd page from the list, return NULL if none available -- Cort */
+extern unsigned long get_zero_page_fast(void);
+
+extern void __bad_pte(pmd_t *pmd);
+
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+       struct task_struct * p;
+       pgd_t *pgd;
+#ifdef __SMP__
+       int i;
+#endif 
+        
+       read_lock(&tasklist_lock);
+       for_each_task(p) {
+               if (!p->mm)
+                       continue;
+               *pgd_offset(p->mm,address) = entry;
+       }
+       read_unlock(&tasklist_lock);
+#ifndef __SMP__
+       for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+               pgd[address >> PGDIR_SHIFT] = entry;
+#else
+       /* To pgd_alloc/pgd_free, one holds master kernel lock and so does our callee, so we can
+          modify pgd caches of other CPUs as well. -jj */
+       for (i = 0; i < NR_CPUS; i++)
+               for (pgd = (pgd_t *)cpu_data[i].pgd_cache; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+                       pgd[address >> PGDIR_SHIFT] = entry;
+#endif
+}
 
 /* We don't use pmd cache, so this is a dummy routine */
 extern __inline__ pmd_t *get_pmd_fast(void)
@@ -52,9 +127,9 @@ extern __inline__ pgd_t *get_pgd_fast(void)
 {
         unsigned long *ret;
 
-        if((ret = pgd_quicklist) != NULL) {
+        if ((ret = pgd_quicklist) != NULL) {
                 pgd_quicklist = (unsigned long *)(*ret);
-                ret[0] = ret[1];
+                ret[0] = 0;
                 pgtable_cache_size--;
         } else
                 ret = (unsigned long *)get_pgd_slow();
@@ -63,7 +138,7 @@ extern __inline__ pgd_t *get_pgd_fast(void)
 
 extern __inline__ void free_pgd_fast(pgd_t *pgd)
 {
-        *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+        *(unsigned long **)pgd = pgd_quicklist;
         pgd_quicklist = (unsigned long *) pgd;
         pgtable_cache_size++;
 }
@@ -79,9 +154,9 @@ extern __inline__ pte_t *get_pte_fast(void)
 {
         unsigned long *ret;
 
-        if((ret = (unsigned long *)pte_quicklist) != NULL) {
+        if ((ret = pte_quicklist) != NULL) {
                 pte_quicklist = (unsigned long *)(*ret);
-                ret[0] = ret[1];
+                ret[0] = 0;
                 pgtable_cache_size--;
        }
         return (pte_t *)ret;
@@ -89,7 +164,7 @@ extern __inline__ pte_t *get_pte_fast(void)
 
 extern __inline__ void free_pte_fast(pte_t *pte)
 {
-        *(unsigned long *)pte = (unsigned long) pte_quicklist;
+        *(unsigned long **)pte = pte_quicklist;
         pte_quicklist = (unsigned long *) pte;
         pgtable_cache_size++;
 }
@@ -98,6 +173,7 @@ extern __inline__ void free_pte_slow(pte_t *pte)
 {
        free_page((unsigned long)pte);
 }
+
 #define pte_free_kernel(pte)    free_pte_fast(pte)
 #define pte_free(pte)           free_pte_fast(pte)
 #define pgd_free(pgd)           free_pgd_fast(pgd)
@@ -123,29 +199,4 @@ extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
 
 extern int do_check_pgt_cache(int, int);
 
-extern __inline__ pte_t *find_pte(struct mm_struct *mm,unsigned long va)
-{
-       pgd_t *dir;
-       pmd_t *pmd;
-       pte_t *pte;
-
-       va &= PAGE_MASK;
-       
-       dir = pgd_offset( mm, va );
-       if (dir)
-       {
-               pmd = pmd_offset(dir, va & PAGE_MASK);
-               if (pmd && pmd_present(*pmd))
-               {
-                       pte = pte_offset(pmd, va);
-                       if (pte && pte_present(*pte))
-                       {                       
-                               pte_uncache(*pte);
-                               flush_tlb_page(find_vma(mm,va),va);
-                       }
-               }
-       }
-       return pte;
-}
-
 #endif /* _PPC_PGALLOC_H */
index bcbf7100b92ec6b1c4716524a4abbbad01e8a36c..d671e2f6e174e22e60acedd743de73d5872368d5 100644 (file)
@@ -1,12 +1,10 @@
-#include <linux/config.h>
-
 #ifndef _PPC_PGTABLE_H
 #define _PPC_PGTABLE_H
 
+#include <linux/config.h>
+
 #ifndef __ASSEMBLY__
 #include <linux/threads.h>
-#include <linux/sched.h>
-#include <asm/atomic.h>
 #include <asm/processor.h>             /* For TASK_SIZE */
 #include <asm/mmu.h>
 #include <asm/page.h>
@@ -276,8 +274,8 @@ extern pte_t * __bad_pagetable(void);
 /*
  * Permanent address of a page.
  */
-#define page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define __page_address(page) ({ if (PageHighMem(page)) BUG(); PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT); })
+#define page_address(page)  ({ if (!(page)->virtual) BUG(); (page)->virtual; })
+#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
 #define pages_to_mb(x)         ((x) >> (20-PAGE_SHIFT))
 #define pte_page(x)            (mem_map+pte_pagenr(x))
 
@@ -290,7 +288,7 @@ extern pte_t * __bad_pagetable(void);
 extern inline int pgd_none(pgd_t pgd)          { return 0; }
 extern inline int pgd_bad(pgd_t pgd)           { return 0; }
 extern inline int pgd_present(pgd_t pgd)       { return 1; }
-#define pgd_clear(xp)                          do { } while(0)
+#define pgd_clear(xp)                          do { } while (0)
 
 #define pgd_page(pgd) \
        ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
@@ -371,19 +369,13 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
        return pte;
 }
 
-#define page_pte_prot(page,prot) mk_pte(page, prot)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
 #define pmd_page(pmd)  (pmd_val(pmd))
 
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
 /* to find an entry in a page-table-directory */
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
-{
-       return mm->pgd + (address >> PGDIR_SHIFT);
-}
+#define pgd_offset(mm, address)         ((mm)->pgd + ((address) >> PGDIR_SHIFT))
 
 /* Find an entry in the second-level page table.. */
 extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
@@ -397,79 +389,6 @@ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
        return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 }
 
-/*
- * This is handled very differently on the PPC since out page tables
- * are all 0's and I want to be able to use these zero'd pages elsewhere
- * as well - it gives us quite a speedup.
- *
- * Note that the SMP/UP versions are the same but we don't need a
- * per cpu list of zero pages because we do the zero-ing with the cache
- * off and the access routines are lock-free but the pgt cache stuff
- * is per-cpu since it isn't done with any lock-free access routines
- * (although I think we need arch-specific routines so I can do lock-free).
- *
- * I need to generalize this so we can use it for other arch's as well.
- * -- Cort
- */
-#ifdef __SMP__
-#define quicklists     cpu_data[smp_processor_id()]
-#else
-extern struct pgtable_cache_struct {
-       unsigned long *pgd_cache;
-       unsigned long *pte_cache;
-       unsigned long pgtable_cache_sz;
-} quicklists;
-#endif
-
-#define pgd_quicklist          (quicklists.pgd_cache)
-#define pmd_quicklist          ((unsigned long *)0)
-#define pte_quicklist          (quicklists.pte_cache)
-#define pgtable_cache_size     (quicklists.pgtable_cache_sz)
-
-extern unsigned long *zero_cache;    /* head linked list of pre-zero'd pages */
-extern atomic_t zero_sz;            /* # currently pre-zero'd pages */
-extern atomic_t zeropage_hits;      /* # zero'd pages request that we've done */
-extern atomic_t zeropage_calls;      /* # zero'd pages request that've been made */
-extern atomic_t zerototal;          /* # pages zero'd over time */
-
-#define zero_quicklist         (zero_cache)
-#define zero_cache_sz                  (zero_sz)
-#define zero_cache_calls       (zeropage_calls)
-#define zero_cache_hits        (zeropage_hits)
-#define zero_cache_total       (zerototal)
-
-/* return a pre-zero'd page from the list, return NULL if none available -- Cort */
-extern unsigned long get_zero_page_fast(void);
-
-extern void __bad_pte(pmd_t *pmd);
-
-extern inline void set_pgdir(unsigned long address, pgd_t entry)
-{
-       struct task_struct * p;
-       pgd_t *pgd;
-#ifdef __SMP__
-       int i;
-#endif 
-        
-       read_lock(&tasklist_lock);
-       for_each_task(p) {
-               if (!p->mm)
-                       continue;
-               *pgd_offset(p->mm,address) = entry;
-       }
-       read_unlock(&tasklist_lock);
-#ifndef __SMP__
-       for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-               pgd[address >> PGDIR_SHIFT] = entry;
-#else
-       /* To pgd_alloc/pgd_free, one holds master kernel lock and so does our callee, so we can
-          modify pgd caches of other CPUs as well. -jj */
-       for (i = 0; i < NR_CPUS; i++)
-               for (pgd = (pgd_t *)cpu_data[i].pgd_cache; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-                       pgd[address >> PGDIR_SHIFT] = entry;
-#endif
-}
-
 extern pgd_t swapper_pg_dir[1024];
 
 /*
@@ -486,11 +405,10 @@ extern pgd_t swapper_pg_dir[1024];
 extern void flush_hash_segments(unsigned low_vsid, unsigned high_vsid);
 extern void flush_hash_page(unsigned context, unsigned long va);
 
-
 /* Encode and de-code a swap entry */
-#define SWP_TYPE(entry) (((entry).val >> 1) & 0x3f)
-#define SWP_OFFSET(entry) ((entry).val >> 8)
-#define SWP_ENTRY(type,offset) ((swp_entry_t) { (((type) << 1) | ((offset) << 8)) })
+#define SWP_TYPE(entry)                        (((entry).val >> 1) & 0x3f)
+#define SWP_OFFSET(entry)              ((entry).val >> 8)
+#define SWP_ENTRY(type, offset)                ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
 #define pte_to_swp_entry(pte)          ((swp_entry_t) { pte_val(pte) })
 #define swp_entry_to_pte(x)            ((pte_t) { (x).val })
 
index c8ced55c5c2deea08146d2a68d7c0c6cdfe69bae..9f565771a7dc048c7832a952101d1d8734ec1ee5 100644 (file)
 
 #define INIT_RLIMITS                                                   \
 {                                                                      \
-    {LONG_MAX, LONG_MAX},                      /* RLIMIT_CPU */        \
-    {LONG_MAX, LONG_MAX},                      /* RLIMIT_FSIZE */      \
-    {LONG_MAX, LONG_MAX},                      /* RLIMIT_DATA */       \
-    {_STK_LIM, LONG_MAX},                      /* RLIMIT_STACK */      \
-    {       0, LONG_MAX},                      /* RLIMIT_CORE */       \
-    {LONG_MAX, LONG_MAX},                      /* RLIMIT_RSS */        \
-    {0, 0},                                                            \
-    {INR_OPEN, INR_OPEN},                      /* RLIMIT_NOFILE */     \
-    {LONG_MAX, LONG_MAX},                      /* RLIMIT_MEMLOCK */    \
-    {LONG_MAX, LONG_MAX},                      /* RLIMIT_AS */         \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       {      _STK_LIM, RLIM_INFINITY },               \
+       {             0, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       {             0,             0 },               \
+       {      INR_OPEN,     INR_OPEN  },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
+       { RLIM_INFINITY, RLIM_INFINITY },               \
 }
 
 #endif /* __KERNEL__ */
index 35641aff0c556952694ff10f2031dcaca662bc54..6b2e724f669c99b25cf58f7974ae839acfee1b8b 100644 (file)
 #define __NR_getpmsg           187     /* some people actually want streams */
 #define __NR_putpmsg           188     /* some people actually want streams */
 #define __NR_vfork             189
+#define __NR_ugetrlimit                191     /* SuS compliant getrlimit */
 
 #define __NR(n)        #n
 
diff --git a/include/asm-sparc/sfp-machine.h b/include/asm-sparc/sfp-machine.h
new file mode 100644 (file)
index 0000000..9ac17ed
--- /dev/null
@@ -0,0 +1,205 @@
+/* Machine-dependent software floating-point definitions.
+   Sparc userland (_Q_*) version.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz),
+                 David S. Miller (davem@redhat.com) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _SFP_MACHINE_H
+#define _SFP_MACHINE_H
+   
+#define _FP_W_TYPE_SIZE                32
+#define _FP_W_TYPE             unsigned long
+#define _FP_WS_TYPE            signed long
+#define _FP_I_TYPE             long
+
+#define _FP_MUL_MEAT_S(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)                                  \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
+  _FP_MUL_MEAT_5_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S          0
+#define _FP_NANSIGN_D          0
+#define _FP_NANSIGN_Q          0
+
+#define _FP_KEEPNANFRACP 1
+
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
+ */
+/* For _Qp_* and _Q_*, this should prefer X, for
+ * CPU instruction emulation this should prefer Y.
+ * (see SPAMv9 B.2.2 section).
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)         \
+       && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))     \
+      {                                                                \
+       R##_s = X##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,X);                                \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       R##_s = Y##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,Y);                                \
+      }                                                                \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+/* Some assembly to speed things up. */
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
+  __asm__ ("addcc %r7,%8,%2
+           addxcc %r5,%6,%1
+           addx %r3,%4,%0"                                             \
+          : "=r" ((USItype)(r2)),                                      \
+            "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc")
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
+  __asm__ ("subcc %r7,%8,%2
+           subxcc %r5,%6,%1
+           subx %r3,%4,%0"                                             \
+          : "=r" ((USItype)(r2)),                                      \
+            "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
+  do {                                                                 \
+    /* We need to fool gcc,  as we need to pass more than 10           \
+       input/outputs.  */                                              \
+    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");           \
+    __asm__ __volatile__ ("
+           addcc %r8,%9,%1
+           addxcc %r6,%7,%0
+           addxcc %r4,%5,%%g2
+           addx %r2,%3,%%g1"                                           \
+          : "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x3)),                                     \
+            "rI" ((USItype)(y3)),                                      \
+            "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc", "g1", "g2");                                         \
+    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));                        \
+    r3 = _t1; r2 = _t2;                                                        \
+  } while (0)
+
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
+  do {                                                                 \
+    /* We need to fool gcc,  as we need to pass more than 10           \
+       input/outputs.  */                                              \
+    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");           \
+    __asm__ __volatile__ ("
+           subcc %r8,%9,%1
+           subxcc %r6,%7,%0
+           subxcc %r4,%5,%%g2
+           subx %r2,%3,%%g1"                                           \
+          : "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x3)),                                     \
+            "rI" ((USItype)(y3)),                                      \
+            "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc", "g1", "g2");                                         \
+    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));                        \
+    r3 = _t1; r2 = _t2;                                                        \
+  } while (0)
+
+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0)
+
+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
+
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)                                        \
+  __asm__ ("addcc %3,%4,%3
+           addxcc %2,%%g0,%2
+           addxcc %1,%%g0,%1
+           addx %0,%%g0,%0"                                            \
+          : "=&r" ((USItype)(x3)),                                     \
+            "=&r" ((USItype)(x2)),                                     \
+            "=&r" ((USItype)(x1)),                                     \
+            "=&r" ((USItype)(x0))                                      \
+          : "rI" ((USItype)(i)),                                       \
+            "0" ((USItype)(x3)),                                       \
+            "1" ((USItype)(x2)),                                       \
+            "2" ((USItype)(x1)),                                       \
+            "3" ((USItype)(x0))                                        \
+          : "cc")
+
+#ifndef __SMP__
+extern struct task_struct *last_task_used_math;
+#endif
+
+/* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
+#ifdef __SMP__
+#define FP_ROUNDMODE   ((current->thread.fsr >> 30) & 0x3)
+#else
+#define FP_ROUNDMODE   ((last_task_used_math->thread.fsr >> 30) & 0x3)
+#endif
+#endif
+
+/* Exception flags. */
+#define FP_EX_INVALID          (1 << 4)
+#define FP_EX_OVERFLOW         (1 << 3)
+#define FP_EX_UNDERFLOW                (1 << 2)
+#define FP_EX_DIVZERO          (1 << 1)
+#define FP_EX_INEXACT          (1 << 0)
+
+#define FP_HANDLE_EXCEPTIONS return _fex
+
+#ifdef __SMP__
+#define FP_INHIBIT_RESULTS ((current->thread.fsr >> 23) & _fex)
+#else
+#define FP_INHIBIT_RESULTS ((last_task_used_math->thread.fsr >> 23) & _fex)
+#endif
+
+#endif
diff --git a/include/asm-sparc64/sfp-machine.h b/include/asm-sparc64/sfp-machine.h
new file mode 100644 (file)
index 0000000..edb3098
--- /dev/null
@@ -0,0 +1,91 @@
+/* Machine-dependent software floating-point definitions.
+   Sparc64 kernel version.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz) and
+                 David S. Miller (davem@redhat.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _SFP_MACHINE_H
+#define _SFP_MACHINE_H
+   
+#define _FP_W_TYPE_SIZE                64
+#define _FP_W_TYPE             unsigned long
+#define _FP_WS_TYPE            signed long
+#define _FP_I_TYPE             long
+
+#define _FP_MUL_MEAT_S(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
+  _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_1_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1)
+#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1
+#define _FP_NANSIGN_S          0
+#define _FP_NANSIGN_D          0
+#define _FP_NANSIGN_Q          0
+
+#define _FP_KEEPNANFRACP 1
+
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
+ */
+/* For _Qp_* and _Q_*, this should prefer X, for
+ * CPU instruction emulation this should prefer Y.
+ * (see SPAMv9 B.2.2 section).
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)         \
+       && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))     \
+      {                                                                \
+       R##_s = X##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,X);                                \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       R##_s = Y##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,Y);                                \
+      }                                                                \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+/* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
+#define FP_ROUNDMODE   ((current->thread.xfsr[0] >> 30) & 0x3)
+#endif
+
+/* Exception flags. */
+#define FP_EX_INVALID          (1 << 4)
+#define FP_EX_OVERFLOW         (1 << 3)
+#define FP_EX_UNDERFLOW                (1 << 2)
+#define FP_EX_DIVZERO          (1 << 1)
+#define FP_EX_INEXACT          (1 << 0)
+
+#define FP_HANDLE_EXCEPTIONS return _fex
+
+#define FP_INHIBIT_RESULTS ((current->thread.xfsr[0] >> 23) & _fex)
+
+#endif
index 094fa0b51e59230002d0893353c3a6d12d3df967..22a3f377949d4a09fbce861637c4aabebd5483b7 100644 (file)
 
 #include <linux/types.h>
 #include <linux/ioctl.h>
-
 #ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
+#endif /* __KERNEL__ */
 
 /*
- * Device types
+ * System sleep states
  */
 enum
 {
-       ACPI_SYS_DEV,   /* system device (fan, KB controller, ...) */
-       ACPI_PCI_DEV,   /* generic PCI device */
-       ACPI_PCI_BUS,   /* PCI bus */
-       ACPI_ISA_DEV,   /* generic ISA device */
-       ACPI_ISA_BUS,   /* ISA bus */
-       ACPI_USB_DEV,   /* generic USB device */
-       ACPI_USB_HUB,   /* USB hub device */
-       ACPI_USB_CTRL,  /* USB controller */
-       ACPI_SCSI_DEV,  /* generic SCSI device */
-       ACPI_SCSI_CTRL, /* SCSI controller */
+       ACPI_S0, /* working */
+       ACPI_S1, /* sleep */
+       ACPI_S2, /* sleep */
+       ACPI_S3, /* sleep */
+       ACPI_S4, /* non-volatile sleep */
+       ACPI_S5, /* soft-off */
 };
 
-typedef int acpi_dev_t;
+typedef int acpi_sstate_t;
 
 /*
- * Device addresses
+ * Device states
  */
-#define ACPI_PCI_ADR(dev) ((dev)->bus->number << 16 | (dev)->devfn)
+enum
+{
+       ACPI_D0, /* fully-on */
+       ACPI_D1, /* partial-on */
+       ACPI_D2, /* partial-on */
+       ACPI_D3, /* fully-off */
+};
+
+typedef int acpi_dstate_t;
 
 /*
  * HID (PnP) values
@@ -71,33 +74,31 @@ enum
 
 typedef int acpi_hid_t;
 
+#ifdef __KERNEL__
+
 /*
- * Device states
+ * Device types
  */
 enum
 {
-       ACPI_D0, /* fully-on */
-       ACPI_D1, /* partial-on */
-       ACPI_D2, /* partial-on */
-       ACPI_D3, /* fully-off */
+       ACPI_SYS_DEV,   /* system device (fan, KB controller, ...) */
+       ACPI_PCI_DEV,   /* generic PCI device */
+       ACPI_PCI_BUS,   /* PCI bus */
+       ACPI_ISA_DEV,   /* generic ISA device */
+       ACPI_ISA_BUS,   /* ISA bus */
+       ACPI_USB_DEV,   /* generic USB device */
+       ACPI_USB_HUB,   /* USB hub device */
+       ACPI_USB_CTRL,  /* USB controller */
+       ACPI_SCSI_DEV,  /* generic SCSI device */
+       ACPI_SCSI_CTRL, /* SCSI controller */
 };
 
-typedef int acpi_dstate_t;
+typedef int acpi_dev_t;
 
 /*
- * System sleep states
+ * Device addresses
  */
-enum
-{
-       ACPI_S0, /* working */
-       ACPI_S1, /* sleep */
-       ACPI_S2, /* sleep */
-       ACPI_S3, /* sleep */
-       ACPI_S4, /* non-volatile sleep */
-       ACPI_S5, /* soft-off */
-};
-
-typedef int acpi_sstate_t;
+#define ACPI_PCI_ADR(dev) ((dev)->bus->number << 16 | (dev)->devfn)
 
 struct acpi_dev;
 
@@ -136,7 +137,7 @@ struct acpi_dev
 
 #ifdef CONFIG_ACPI
 
-extern wait_queue_head_t acpi_idle_wait;
+extern wait_queue_head_t acpi_control_wait;
 
 /*
  * Register a device with the ACPI subsystem
@@ -168,8 +169,8 @@ extern inline void acpi_dev_idle(struct acpi_dev *dev)
 {
        if (dev) {
                dev->idle = jiffies;
-               if (waitqueue_active(&acpi_idle_wait))
-                       wake_up(&acpi_idle_wait);
+               if (waitqueue_active(&acpi_control_wait))
+                       wake_up(&acpi_control_wait);
        }
 }
 
@@ -361,7 +362,10 @@ enum
        ACPI_P_BLK,
        ACPI_P_LVL2_LAT,
        ACPI_P_LVL3_LAT,
+       ACPI_S0_SLP_TYP,
+       ACPI_S1_SLP_TYP,
        ACPI_S5_SLP_TYP,
+       ACPI_SLEEP,
 };
 
 #define ACPI_SLP_TYP_DISABLED  (~0UL)
index 9331f9a2dabd3ef861cf3b43e896cee6504485e7..7b48a5be823773d9d987f8f2c1bb49e48ca725d9 100644 (file)
@@ -584,6 +584,8 @@ typedef union {
 #define DVD_LU_SEND_TITLE_KEY  7
 #define DVD_LU_SEND_ASF                8
 #define DVD_INVALIDATE_AGID    9
+#define DVD_LU_SEND_RPC_STATE  10
+#define DVD_HOST_SEND_RPC_STATE        11
 
 /* State data */
 typedef __u8 dvd_key[5];               /* 40-bit value, MSB is first elem. */
@@ -643,6 +645,18 @@ struct dvd_lu_send_asf {
        unsigned asf            : 1;
 };
 
+struct dvd_host_send_rpcstate {
+       __u8 pdrc;
+};
+
+struct dvd_lu_send_rpcstate {
+       __u8 type               : 2;
+       __u8 vra                : 3;
+       __u8 ucca               : 3;
+       __u8 region_mask;
+       __u8 rpc_scheme;
+};
+
 typedef union {
        __u8 type;
 
@@ -653,6 +667,8 @@ typedef union {
        struct dvd_send_key             hsk;
        struct dvd_lu_send_title_key    lstk;
        struct dvd_lu_send_asf          lsasf;
+       struct dvd_host_send_rpcstate   hrpcs;
+       struct dvd_lu_send_rpcstate     lrpcs;
 } dvd_authinfo;
 
 #ifdef __KERNEL__
index f948070ebdd3df5cf0ea86826e752334c92ef3eb..78fb24d237bc9d7ef1a45fdb94c0cc06593e4b50 100644 (file)
@@ -255,61 +255,6 @@ struct fb_ops {
     int (*fb_rasterimg)(struct fb_info *info, int start);
 };
 
-
-   /*
-    *    This is the interface between the low-level console driver and the
-    *    low-level frame buffer device
-    */
-
-struct display {
-    /* Filled in by the frame buffer device */
-
-    struct fb_var_screeninfo var;   /* variable infos. yoffset and vmode */
-                                   /* are updated by fbcon.c */
-    struct fb_cmap cmap;            /* colormap */
-    char *screen_base;              /* pointer to top of virtual screen */    
-                                   /* (virtual address) */
-    int visual;
-    int type;                       /* see FB_TYPE_* */
-    int type_aux;                   /* Interleave for interleaved Planes */
-    u_short ypanstep;               /* zero if no hardware ypan */
-    u_short ywrapstep;              /* zero if no hardware ywrap */
-    u_long line_length;             /* length of a line in bytes */
-    u_short can_soft_blank;         /* zero if no hardware blanking */
-    u_short inverse;                /* != 0 text black on white as default */
-    struct display_switch *dispsw;  /* low level operations */
-    void *dispsw_data;             /* optional dispsw helper data */
-
-#if 0
-    struct fb_fix_cursorinfo fcrsr;
-    struct fb_var_cursorinfo *vcrsr;
-    struct fb_cursorstate crsrstate;
-#endif
-
-    /* Filled in by the low-level console driver */
-
-    struct vc_data *conp;           /* pointer to console data */
-    struct fb_info *fb_info;        /* frame buffer for this console */
-    int vrows;                      /* number of virtual rows */
-    unsigned short cursor_x;       /* current cursor position */
-    unsigned short cursor_y;
-    int fgcol;                      /* text colors */
-    int bgcol;
-    u_long next_line;               /* offset to one line below */
-    u_long next_plane;              /* offset to next plane */
-    u_char *fontdata;               /* Font associated to this display */
-    unsigned short _fontheightlog;
-    unsigned short _fontwidthlog;
-    unsigned short _fontheight;
-    unsigned short _fontwidth;
-    int userfont;                   /* != 0 if fontdata kmalloc()ed */
-    u_short scrollmode;             /* Scroll Method */
-    short yscroll;                  /* Hardware scrolling */
-    unsigned char fgshift, bgshift;
-    unsigned short charmask;       /* 0xff or 0x1ff */
-};
-
-
 struct fb_info {
    char modename[40];                  /* default video mode */
    kdev_t node;
@@ -415,16 +360,12 @@ extern int unregister_framebuffer(const struct fb_info *fb_info);
 
 extern int num_registered_fb;
 extern struct fb_info *registered_fb[FB_MAX];
-extern char con2fb_map[MAX_NR_CONSOLES];
 
 /* drivers/video/fbmon.c */
 extern int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal,
                               const struct fb_info *fb_info);
 extern int fbmon_dpms(const struct fb_info *fb_info);
 
-/* drivers/video/fbcon.c */
-extern struct display fb_display[MAX_NR_CONSOLES];
-
 /* drivers/video/fbcmap.c */
 extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
 extern void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to,
index c2e69282f80f828a711986099e0a1d6f61580888..72ae514ee6a499abb634f5884df46eb95df939d4 100644 (file)
@@ -84,20 +84,20 @@ extern int last_pid;
 #define TASK_EXCLUSIVE         32
 
 #define __set_task_state(tsk, state_value)             \
-       do { tsk->state = state_value; } while (0)
+       do { (tsk)->state = (state_value); } while (0)
 #ifdef __SMP__
 #define set_task_state(tsk, state_value)               \
-       set_mb(tsk->state, state_value)
+       set_mb((tsk)->state, (state_value))
 #else
 #define set_task_state(tsk, state_value)               \
-       __set_task_state(tsk, state_value)
+       __set_task_state((tsk), (state_value))
 #endif
 
 #define __set_current_state(state_value)                       \
-       do { current->state = state_value; } while (0)
+       do { current->state = (state_value); } while (0)
 #ifdef __SMP__
 #define set_current_state(state_value)         \
-       set_mb(current->state, state_value)
+       set_mb(current->state, (state_value))
 #else
 #define set_current_state(state_value)         \
        __set_current_state(state_value)
index 8e9e729890e4a023095f73976a03bd87cbd671c3..1eb17e3ec2a507adc8a60842dfa46e19517047e6 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _LINUX_SWAP_H
 #define _LINUX_SWAP_H
 
+#include <linux/spinlock.h>
 #include <asm/page.h>
 
 #define SWAP_FLAG_PREFER       0x8000  /* set if swap priority specified */
@@ -48,6 +49,7 @@ union swap_header {
 struct swap_info_struct {
        unsigned int flags;
        kdev_t swap_device;
+       spinlock_t sdev_lock;
        struct dentry * swap_file;
        unsigned short * swap_map;
        unsigned int lowest_bit;
@@ -94,13 +96,10 @@ extern void rw_swap_page_nolock(int, swp_entry_t, char *, int);
 /* linux/mm/swap_state.c */
 extern void show_swap_cache_info(void);
 extern void add_to_swap_cache(struct page *, swp_entry_t);
-extern int swap_duplicate(swp_entry_t);
 extern int swap_check_entry(unsigned long);
 extern struct page * lookup_swap_cache(swp_entry_t);
 extern struct page * read_swap_cache_async(swp_entry_t, int);
 #define read_swap_cache(entry) read_swap_cache_async(entry, 1);
-extern int swap_count(struct page *);
-extern swp_entry_t acquire_swap_entry(struct page *page);
 
 /*
  * Make these inline later once they are working properly.
@@ -115,6 +114,12 @@ extern struct swap_info_struct swap_info[];
 extern int is_swap_partition(kdev_t);
 extern void si_swapinfo(struct sysinfo *);
 extern swp_entry_t __get_swap_page(unsigned short);
+extern void get_swaphandle_info(swp_entry_t, unsigned long *, kdev_t *, 
+                                       struct inode **);
+extern int swap_duplicate(swp_entry_t);
+extern int swap_count(struct page *);
+extern swp_entry_t acquire_swap_entry(struct page *page);
+extern int valid_swaphandles(swp_entry_t, unsigned long *);
 #define get_swap_page() __get_swap_page(1)
 extern void __swap_free(swp_entry_t, unsigned short);
 #define swap_free(entry) __swap_free((entry), 1)
@@ -173,6 +178,13 @@ do {                                               \
        spin_unlock(&pagemap_lru_lock);         \
 } while (0)
 
+extern spinlock_t swaplock;
+
+#define swap_list_lock()       spin_lock(&swaplock)
+#define swap_list_unlock()     spin_unlock(&swaplock)
+#define swap_device_lock(p)    spin_lock(&p->sdev_lock)
+#define swap_device_unlock(p)  spin_unlock(&p->sdev_lock)
+
 #endif /* __KERNEL__*/
 
 #endif /* _LINUX_SWAP_H */
index ee581c2da4c0a99349c58da865fea4787a170977..04c4c0f4584cd931301b95b8dc2c9d9bae7cb2a0 100644 (file)
@@ -115,6 +115,7 @@ union _FP_UNION_D
 #define FP_CMP_EQ_D(r,X,Y)     _FP_CMP_EQ(D,2,r,X,Y)
 
 #define FP_TO_INT_D(r,X,rsz,rsg)       _FP_TO_INT(D,2,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_D(r,X,rsz,rsg) _FP_TO_INT_ROUND(D,2,r,X,rsz,rsg)
 #define FP_FROM_INT_D(X,r,rs,rt)       _FP_FROM_INT(D,2,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_D(X)     _FP_FRAC_HIGH_2(X)
@@ -189,6 +190,7 @@ union _FP_UNION_D
 #define FP_CMP_EQ_D(r,X,Y)     _FP_CMP_EQ(D,1,r,X,Y)
 
 #define FP_TO_INT_D(r,X,rsz,rsg)       _FP_TO_INT(D,1,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_D(r,X,rsz,rsg) _FP_TO_INT_ROUND(D,1,r,X,rsz,rsg)
 #define FP_FROM_INT_D(X,r,rs,rt)       _FP_FROM_INT(D,1,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_D(X)     _FP_FRAC_HIGH_1(X)
index 4a1d7e711c59fa54605d41f15147c689e93930dc..ae73cecb399bb12936c580abfb0f480996c0d2e1 100644 (file)
@@ -226,6 +226,7 @@ union _FP_UNION_E
 #define FP_CMP_EQ_E(r,X,Y)     _FP_CMP_EQ(E,4,r,X,Y)
 
 #define FP_TO_INT_E(r,X,rsz,rsg)       _FP_TO_INT(E,4,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,4,r,X,rsz,rsg)
 #define FP_FROM_INT_E(X,r,rs,rt)       _FP_FROM_INT(E,4,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_E(X)     (X##_f[2])
@@ -380,6 +381,7 @@ union _FP_UNION_E
 #define FP_CMP_EQ_E(r,X,Y)     _FP_CMP_EQ(E,2,r,X,Y)
 
 #define FP_TO_INT_E(r,X,rsz,rsg)       _FP_TO_INT(E,2,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,2,r,X,rsz,rsg)
 #define FP_FROM_INT_E(X,r,rs,rt)       _FP_FROM_INT(E,2,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_E(X)     (X##_f1)
index ad3fbc538a0049dc77f2501b360ef8a208f33c3c..184eb3c3b4341b21bbd3104467567d78ecb489e4 100644 (file)
 #define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
 #define _FP_FRAC_EQ_2(X, Y)    (X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
 #define _FP_FRAC_GT_2(X, Y)    \
-  (X##_f1 > Y##_f1 || X##_f1 == Y##_f1 && X##_f0 > Y##_f0)
+  (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
 #define _FP_FRAC_GE_2(X, Y)    \
-  (X##_f1 > Y##_f1 || X##_f1 == Y##_f1 && X##_f0 >= Y##_f0)
+  (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
 
 #define _FP_ZEROFRAC_2         0, 0
 #define _FP_MINFRAC_2          0, 1
index 207aa77383b5ec98a36058b3f4bc840372072a54..e03e40e656bc3943994031587477384cd628e3b3 100644 (file)
@@ -54,6 +54,11 @@ do {                                                                 \
        X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;                         \
        X##_c = FP_CLS_NORMAL;                                          \
        FP_SET_EXCEPTION(FP_EX_DENORM);                                 \
+       if (FP_DENORM_ZERO)                                             \
+         {                                                             \
+           FP_SET_EXCEPTION(FP_EX_INEXACT);                            \
+           X##_c = FP_CLS_ZERO;                                        \
+         }                                                             \
       }                                                                        \
     break;                                                             \
                                                                        \
@@ -618,6 +623,8 @@ do {                                                                        \
  * 1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
  *     on the sign in such case.
+ * 2:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
+ *     set plus the result is truncated to fit into destination.
  * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
  *     on the sign in such case.
@@ -638,12 +645,25 @@ do {                                                                      \
          {     /* overflow */                                                  \
          case FP_CLS_NAN:                                                      \
          case FP_CLS_INF:                                                      \
-           if (rsigned)                                                        \
+           if (rsigned == 2)                                                   \
+             {                                                                 \
+               if (X##_c != FP_CLS_NORMAL                                      \
+                   || X##_e >= rsize - 1 + _FP_WFRACBITS_##fs)                 \
+                 r = 0;                                                        \
+               else                                                            \
+                 {                                                             \
+                   _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));     \
+                   _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                        \
+                 }                                                             \
+             }                                                                 \
+           else if (rsigned)                                                   \
              {                                                                 \
                r = 1;                                                          \
                r <<= rsize - 1;                                                \
                r -= 1 - X##_s;                                                 \
-             } else {                                                          \
+             }                                                                 \
+           else                                                                \
+             {                                                                 \
                r = 0;                                                          \
                if (X##_s)                                                      \
                  r = ~r;                                                       \
@@ -678,6 +698,67 @@ do {                                                                       \
       }                                                                                \
   } while (0)
 
+#define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned)                         \
+  do {                                                                         \
+    r = 0;                                                                     \
+    switch (X##_c)                                                             \
+      {                                                                                \
+      case FP_CLS_NORMAL:                                                      \
+       if (X##_e >= _FP_FRACBITS_##fs - 1)                                     \
+         {                                                                     \
+           if (X##_e < rsize - 1 + _FP_WFRACBITS_##fs)                         \
+             {                                                                 \
+               if (X##_e >= _FP_WFRACBITS_##fs - 1)                            \
+                 {                                                             \
+                   _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                        \
+                   r <<= X##_e - _FP_WFRACBITS_##fs + 1;                       \
+                 }                                                             \
+               else                                                            \
+                 {                                                             \
+                   _FP_FRAC_SRL_##wc(X, _FP_WORKBITS - X##_e                   \
+                                     + _FP_FRACBITS_##fs - 1);                 \
+                   _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                        \
+                 }                                                             \
+             }                                                                 \
+         }                                                                     \
+       else                                                                    \
+         {                                                                     \
+           if (X##_e <= -_FP_WORKBITS - 1)                                     \
+             _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);                           \
+           else                                                                \
+             _FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e,               \
+                               _FP_WFRACBITS_##fs);                            \
+           _FP_ROUND(wc, X);                                                   \
+           _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);                                 \
+           _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                                \
+         }                                                                     \
+       if (rsigned && X##_s)                                                   \
+         r = -r;                                                               \
+       if (X##_e >= rsize - (rsigned > 0 || X##_s)                             \
+           || (!rsigned && X##_s))                                             \
+         {     /* overflow */                                                  \
+         case FP_CLS_NAN:                                                      \
+         case FP_CLS_INF:                                                      \
+           if (!rsigned)                                                       \
+             {                                                                 \
+               r = 0;                                                          \
+               if (X##_s)                                                      \
+                 r = ~r;                                                       \
+             }                                                                 \
+           else if (rsigned != 2)                                              \
+             {                                                                 \
+               r = 1;                                                          \
+               r <<= rsize - 1;                                                \
+               r -= 1 - X##_s;                                                 \
+             }                                                                 \
+           FP_SET_EXCEPTION(FP_EX_INVALID);                                    \
+         }                                                                     \
+       break;                                                                  \
+      case FP_CLS_ZERO:                                                                \
+        break;                                                                 \
+      }                                                                                \
+  } while (0)
+
 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)                       \
   do {                                                                 \
     if (r)                                                             \
index 92a1e2b4869e59f48e01a8771ecc05f05a00c49d..23b20c3e672fc016415b6859de6c9c1eb88e85b4 100644 (file)
@@ -121,6 +121,7 @@ union _FP_UNION_Q
 #define FP_CMP_EQ_Q(r,X,Y)     _FP_CMP_EQ(Q,4,r,X,Y)
 
 #define FP_TO_INT_Q(r,X,rsz,rsg)       _FP_TO_INT(Q,4,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_Q(r,X,rsz,rsg) _FP_TO_INT_ROUND(Q,4,r,X,rsz,rsg)
 #define FP_FROM_INT_Q(X,r,rs,rt)       _FP_FROM_INT(Q,4,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_Q(X)     _FP_FRAC_HIGH_4(X)
@@ -193,6 +194,7 @@ union _FP_UNION_Q
 #define FP_CMP_EQ_Q(r,X,Y)     _FP_CMP_EQ(Q,2,r,X,Y)
 
 #define FP_TO_INT_Q(r,X,rsz,rsg)       _FP_TO_INT(Q,2,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_Q(r,X,rsz,rsg) _FP_TO_INT_ROUND(Q,2,r,X,rsz,rsg)
 #define FP_FROM_INT_Q(X,r,rs,rt)       _FP_FROM_INT(Q,2,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_Q(X)     _FP_FRAC_HIGH_2(X)
index 6504e52834389b71f93ede096162dbda192c3f25..ea12cb8b0a31179d99f7ecbc00af0c590ed3e523 100644 (file)
@@ -104,6 +104,7 @@ union _FP_UNION_S
 #define FP_CMP_EQ_S(r,X,Y)     _FP_CMP_EQ(S,1,r,X,Y)
 
 #define FP_TO_INT_S(r,X,rsz,rsg)       _FP_TO_INT(S,1,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_S(r,X,rsz,rsg) _FP_TO_INT_ROUND(S,1,r,X,rsz,rsg)
 #define FP_FROM_INT_S(X,r,rs,rt)       _FP_FROM_INT(S,1,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_S(X)     _FP_FRAC_HIGH_1(X)
index 3c5072e51662389e2a7b1e98d24b80d91e23480f..1d13451346b5ea177bc70be6ec96b892b08b6286 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef SOFT_FP_H
 #define SOFT_FP_H
 
-#include "sfp-machine.h"
+#include <asm/sfp-machine.h>
 
 /* Allow sfp-machine to have its own byte order definitions. */
 #ifndef __BYTE_ORDER
 #define FP_HANDLE_EXCEPTIONS do {} while (0)
 #endif
 
+/* By default we never flush denormal input operands to signed zero. */
+#ifndef FP_DENORM_ZERO
+#define FP_DENORM_ZERO 0
+#endif
+
 #ifndef FP_INHIBIT_RESULTS
 /* By default we write the results always.
  * sfp-machine may override this and e.g.
index 1cca4c90f73e5bc357fb0d958ed1e48c81f8fcad..7ceb380abc875b8ef2331b7acb9785d7c06d413e 100644 (file)
@@ -44,6 +44,67 @@ struct display_switch {
 
 extern struct display_switch fbcon_dummy;
 
+   /*
+    *    This is the interface between the low-level console driver and the
+    *    low-level frame buffer device
+    */
+
+struct display {
+    /* Filled in by the frame buffer device */
+
+    struct fb_var_screeninfo var;   /* variable infos. yoffset and vmode */
+                                    /* are updated by fbcon.c */
+    struct fb_cmap cmap;            /* colormap */
+    char *screen_base;              /* pointer to top of virtual screen */    
+                                    /* (virtual address) */
+    int visual;
+    int type;                       /* see FB_TYPE_* */
+    int type_aux;                   /* Interleave for interleaved Planes */
+    u_short ypanstep;               /* zero if no hardware ypan */
+    u_short ywrapstep;              /* zero if no hardware ywrap */
+    u_long line_length;             /* length of a line in bytes */
+    u_short can_soft_blank;         /* zero if no hardware blanking */
+    u_short inverse;                /* != 0 text black on white as default */
+    struct display_switch *dispsw;  /* low level operations */
+    void *dispsw_data;              /* optional dispsw helper data */
+
+#if 0
+    struct fb_fix_cursorinfo fcrsr;
+    struct fb_var_cursorinfo *vcrsr;
+    struct fb_cursorstate crsrstate;
+#endif
+
+    /* Filled in by the low-level console driver */
+
+    struct vc_data *conp;           /* pointer to console data */
+    struct fb_info *fb_info;        /* frame buffer for this console */
+    int vrows;                      /* number of virtual rows */
+    unsigned short cursor_x;        /* current cursor position */
+    unsigned short cursor_y;
+    int fgcol;                      /* text colors */
+    int bgcol;
+    u_long next_line;               /* offset to one line below */
+    u_long next_plane;              /* offset to next plane */
+    u_char *fontdata;               /* Font associated to this display */
+    unsigned short _fontheightlog;
+    unsigned short _fontwidthlog;
+    unsigned short _fontheight;
+    unsigned short _fontwidth;
+    int userfont;                   /* != 0 if fontdata kmalloc()ed */
+    u_short scrollmode;             /* Scroll Method */
+    short yscroll;                  /* Hardware scrolling */
+    unsigned char fgshift, bgshift;
+    unsigned short charmask;        /* 0xff or 0x1ff */
+};
+
+/* drivers/video/fbcon.c */
+extern struct display fb_display[MAX_NR_CONSOLES];
+extern char con2fb_map[MAX_NR_CONSOLES];
+extern int PROC_CONSOLE(const struct fb_info *info);
+extern void set_con2fb_map(int unit, int newidx);
+extern int set_all_vcs(int fbidx, struct fb_ops *fb,
+                      struct fb_var_screeninfo *var, struct fb_info *info);
+
 #define fontheight(p) ((p)->_fontheight)
 #define fontheightlog(p) ((p)->_fontheightlog)
 
index 6017f841a83254ef32d0f4f3efbae37e79de8bc9..5e1517d4ec9375c215258f101ec941a36d1255e3 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -289,9 +289,7 @@ out_up:
                        __free_page (pte_page(pte));
                        rss++;
                } else {
-                       lock_kernel();
                        swap_free(pte_to_swp_entry(pte));
-                       unlock_kernel();
                        swp++;
                }
        }
@@ -772,9 +770,7 @@ static struct page * shm_nopage(struct vm_area_struct * shmd, unsigned long addr
                        }
                        delete_from_swap_cache(page);
                        page = replace_with_highmem(page);
-                       lock_kernel();
                        swap_free(entry);
-                       unlock_kernel();
                        if(shp != shm_lock(shp->id))
                                BUG();
                        shm_swp--;
@@ -862,9 +858,7 @@ check_table:
        if (--counter < 0) { /* failed */
 failed:
                shm_unlockall();
-               lock_kernel();
                __swap_free(swap_entry, 2);
-               unlock_kernel();
                return 0;
        }
        if (page_count(page_map) != 1)
index e40eba4b587b9e3c76e2d059f5d20d6d7a28444e..ccd1f33b3b5d148661695369df618e8519443754 100644 (file)
@@ -96,7 +96,7 @@ struct page * replace_with_highmem(struct page * page)
  */
 static int pkmap_count[LAST_PKMAP];
 static unsigned int last_pkmap_nr = 0;
-static spinlock_t kmap_lock;
+static spinlock_t kmap_lock = SPIN_LOCK_UNLOCKED;
 
 pte_t * pkmap_page_table;
 
index 4c82355daf16239c2b7bf76177be385d0acbda93..61a8dd0a44348f2852fb9bec96338180bb553bd3 100644 (file)
@@ -947,33 +947,28 @@ out_unlock:
  */
 void swapin_readahead(swp_entry_t entry)
 {
-       int i;
+       int i, num;
        struct page *new_page;
-       unsigned long offset = SWP_OFFSET(entry);
-       struct swap_info_struct *swapdev = SWP_TYPE(entry) + swap_info;
-       
-       offset = (offset >> page_cluster) << page_cluster;
+       unsigned long offset;
 
-       i = 1 << page_cluster;
-       do {
-               /* Don't read-ahead past the end of the swap area */
-               if (offset >= swapdev->max)
-                       break;
+       /*
+        * Get the number of handles we should do readahead io to. Also,
+        * grab temporary references on them, releasing them as io completes.
+        */
+       num = valid_swaphandles(entry, &offset);
+       for (i = 0; i < num; offset++, i++) {
                /* Don't block on I/O for read-ahead */
-               if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster)
+               if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster) {
+                       while (i++ < num)
+                               swap_free(SWP_ENTRY(SWP_TYPE(entry), offset++));
                        break;
-               /* Don't read in bad or busy pages */
-               if (!swapdev->swap_map[offset])
-                       break;
-               if (swapdev->swap_map[offset] == SWAP_MAP_BAD)
-                       break;
-
+               }
                /* Ok, do the async read-ahead now */
                new_page = read_swap_cache_async(SWP_ENTRY(SWP_TYPE(entry), offset), 0);
                if (new_page != NULL)
                        __free_page(new_page);
-               offset++;
-       } while (--i);
+               swap_free(SWP_ENTRY(SWP_TYPE(entry), offset));
+       }
        return;
 }
 
@@ -997,9 +992,7 @@ static int do_swap_page(struct task_struct * tsk,
 
        vma->vm_mm->rss++;
        tsk->min_flt++;
-       lock_kernel();
        swap_free(entry);
-       unlock_kernel();
 
        pte = mk_pte(page, vma->vm_page_prot);
 
index 0012fe23451abf4b001f1c83bd935150d4ecca6c..23acf5af4272be8c58dab7433d7d9da0dd92ca30 100644 (file)
 
 static int rw_swap_page_base(int rw, swp_entry_t entry, struct page *page, int wait)
 {
-       unsigned long type, offset;
-       struct swap_info_struct * p;
+       unsigned long offset;
        int zones[PAGE_SIZE/512];
        int zones_used;
        kdev_t dev = 0;
        int block_size;
-
-       type = SWP_TYPE(entry);
-       if (type >= nr_swapfiles) {
-               printk("Internal error: bad swap-device\n");
-               return 0;
-       }
+       struct inode *swapf = 0;
 
        /* Don't allow too many pending pages in flight.. */
        if (atomic_read(&nr_async_pages) > pager_daemon.swap_cluster)
                wait = 1;
 
-       p = &swap_info[type];
-       offset = SWP_OFFSET(entry);
-       if (offset >= p->max) {
-               printk("rw_swap_page: weirdness\n");
-               return 0;
-       }
-       if (p->swap_map && !p->swap_map[offset]) {
-               printk("VM: Bad swap entry %08lx\n", entry.val);
-               return 0;
-       }
-       if (!(p->flags & SWP_USED)) {
-               printk(KERN_ERR "rw_swap_page: "
-                       "Trying to swap to unused swap-device\n");
-               return 0;
-       }
-
        if (rw == READ) {
                ClearPageUptodate(page);
                kstat.pswpin++;
        } else
                kstat.pswpout++;
 
-       if (p->swap_device) {
+       get_swaphandle_info(entry, &offset, &dev, &swapf);
+       if (dev) {
                zones[0] = offset;
                zones_used = 1;
-               dev = p->swap_device;
                block_size = PAGE_SIZE;
-       } else if (p->swap_file) {
-               struct inode *swapf = p->swap_file->d_inode;
-               int i;
-               int j;
+       } else if (swapf) {
+               int i, j;
                unsigned int block = offset
                        << (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits);
 
@@ -95,7 +71,6 @@ static int rw_swap_page_base(int rw, swp_entry_t entry, struct page *page, int w
                zones_used = i;
                dev = swapf->i_dev;
        } else {
-               printk(KERN_ERR "rw_swap_page: no swap file or device\n");
                return 0;
        }
        if (!wait) {
index f63eca66a72654088e0b57fefb84f1558bd93fd3..fdcad63f3285f6e2b676e622eb822a299b389889 100644 (file)
@@ -52,93 +52,6 @@ void add_to_swap_cache(struct page *page, swp_entry_t entry)
        add_to_page_cache(page, &swapper_space, entry.val);
 }
 
-/*
- * Verify that a swap entry is valid and increment its swap map count.
- *
- * Note: if swap_map[] reaches SWAP_MAP_MAX the entries are treated as
- * "permanent", but will be reclaimed by the next swapoff.
- */
-int swap_duplicate(swp_entry_t entry)
-{
-       struct swap_info_struct * p;
-       unsigned long offset, type;
-       int result = 0;
-
-       /* Swap entry 0 is illegal */
-       if (!entry.val)
-               goto out;
-       type = SWP_TYPE(entry);
-       if (type >= nr_swapfiles)
-               goto bad_file;
-       p = type + swap_info;
-       offset = SWP_OFFSET(entry);
-       if (offset >= p->max)
-               goto bad_offset;
-       if (!p->swap_map[offset])
-               goto bad_unused;
-       /*
-        * Entry is valid, so increment the map count.
-        */
-       if (p->swap_map[offset] < SWAP_MAP_MAX)
-               p->swap_map[offset]++;
-       else {
-               static int overflow = 0;
-               if (overflow++ < 5)
-                       printk("VM: swap entry overflow\n");
-               p->swap_map[offset] = SWAP_MAP_MAX;
-       }
-       result = 1;
-out:
-       return result;
-
-bad_file:
-       printk("Bad swap file entry %08lx\n", entry.val);
-       goto out;
-bad_offset:
-       printk("Bad swap offset entry %08lx\n", entry.val);
-       goto out;
-bad_unused:
-       printk("Unused swap offset entry %08lx\n", entry.val);
-       goto out;
-}
-
-int swap_count(struct page *page)
-{
-       struct swap_info_struct * p;
-       unsigned long offset, type;
-       swp_entry_t entry;
-       int retval = 0;
-
-       entry.val = page->index;
-       if (!entry.val)
-               goto bad_entry;
-       type = SWP_TYPE(entry);
-       if (type >= nr_swapfiles)
-               goto bad_file;
-       p = type + swap_info;
-       offset = SWP_OFFSET(entry);
-       if (offset >= p->max)
-               goto bad_offset;
-       if (!p->swap_map[offset])
-               goto bad_unused;
-       retval = p->swap_map[offset];
-out:
-       return retval;
-
-bad_entry:
-       printk(KERN_ERR "swap_count: null entry!\n");
-       goto out;
-bad_file:
-       printk("Bad swap file entry %08lx\n", entry.val);
-       goto out;
-bad_offset:
-       printk("Bad swap offset entry %08lx\n", entry.val);
-       goto out;
-bad_unused:
-       printk("Unused swap offset entry %08lx\n", entry.val);
-       goto out;
-}
-
 static inline void remove_from_swap_cache(struct page *page)
 {
        struct address_space *mapping = page->mapping;
@@ -166,9 +79,7 @@ void __delete_from_swap_cache(struct page *page)
        swap_cache_del_total++;
 #endif
        remove_from_swap_cache(page);
-       lock_kernel();
        swap_free(entry);
-       unlock_kernel();
 }
 
 static void delete_from_swap_cache_nolock(struct page *page)
index c34a5316ac6b6af793dda70171b23076f07ba38f..96bcf9fa81fc8a965c8e919b019e884486d783d5 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <asm/pgtable.h>
 
+spinlock_t swaplock = SPIN_LOCK_UNLOCKED;
 unsigned int nr_swapfiles = 0;
 
 struct swap_list_t swap_list = {-1, -1};
@@ -89,24 +90,29 @@ swp_entry_t __get_swap_page(unsigned short count)
        int type, wrapped = 0;
 
        entry.val = 0;  /* Out of memory */
+       if (count >= SWAP_MAP_MAX)
+               goto bad_count;
+       swap_list_lock();
        type = swap_list.next;
        if (type < 0)
                goto out;
        if (nr_swap_pages == 0)
                goto out;
-       if (count >= SWAP_MAP_MAX)
-               goto bad_count;
 
        while (1) {
                p = &swap_info[type];
                if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
+                       swap_device_lock(p);
                        offset = scan_swap_map(p, count);
+                       swap_device_unlock(p);
                        if (offset) {
+                               int curtp = type;
+
                                entry = SWP_ENTRY(type,offset);
                                type = swap_info[type].next;
                                if (type < 0 ||
                                        p->prio != swap_info[type].prio) {
-                                               swap_list.next = swap_list.head;
+                                               swap_list.next = curtp;
                                } else {
                                        swap_list.next = type;
                                }
@@ -124,6 +130,7 @@ swp_entry_t __get_swap_page(unsigned short count)
                                goto out;       /* out of swap space */
        }
 out:
+       swap_list_unlock();
        return entry;
 
 bad_count:
@@ -133,6 +140,10 @@ bad_count:
 }
 
 
+/*
+ * Caller has made sure that the swapdevice corresponding to entry
+ * is still around or has not been recycled.
+ */
 void __swap_free(swp_entry_t entry, unsigned short count)
 {
        struct swap_info_struct * p;
@@ -147,13 +158,15 @@ void __swap_free(swp_entry_t entry, unsigned short count)
        p = & swap_info[type];
        if (!(p->flags & SWP_USED))
                goto bad_device;
-       if (p->prio > swap_info[swap_list.next].prio)
-               swap_list.next = swap_list.head;
        offset = SWP_OFFSET(entry);
        if (offset >= p->max)
                goto bad_offset;
        if (!p->swap_map[offset])
                goto bad_free;
+       swap_list_lock();
+       if (p->prio > swap_info[swap_list.next].prio)
+               swap_list.next = type;
+       swap_device_lock(p);
        if (p->swap_map[offset] < SWAP_MAP_MAX) {
                if (p->swap_map[offset] < count)
                        goto bad_count;
@@ -165,6 +178,8 @@ void __swap_free(swp_entry_t entry, unsigned short count)
                        nr_swap_pages++;
                }
        }
+       swap_device_unlock(p);
+       swap_list_unlock();
 out:
        return;
 
@@ -181,6 +196,8 @@ bad_free:
        printk("VM: Bad swap entry %08lx\n", entry.val);
        goto out;
 bad_count:
+       swap_device_unlock(p);
+       swap_list_unlock();
        printk(KERN_ERR "VM: Bad count %hd current count %hd\n", count, p->swap_map[offset]);
        goto out;
 }
@@ -209,14 +226,21 @@ swp_entry_t acquire_swap_entry(struct page *page)
        if (offset >= p->max)
                goto new_swap_entry;
        /* Has it been re-used for something else? */
+       swap_list_lock();
+       swap_device_lock(p);
        if (p->swap_map[offset])
-               goto new_swap_entry;
+               goto unlock_new_swap_entry;
 
        /* We're cool, we can just use the old one */
        p->swap_map[offset] = 1;
+       swap_device_unlock(p);
        nr_swap_pages--;
+       swap_list_unlock();
        return entry;
 
+unlock_new_swap_entry:
+       swap_device_unlock(p);
+       swap_list_unlock();
 new_swap_entry:
        return get_swap_page();
 }
@@ -360,11 +384,22 @@ static int try_to_unuse(unsigned int type)
                /*
                 * Find a swap page in use and read it in.
                 */
+               swap_device_lock(si);
                for (i = 1; i < si->max ; i++) {
                        if (si->swap_map[i] > 0 && si->swap_map[i] != SWAP_MAP_BAD) {
+                               /*
+                                * Prevent swaphandle from being completely
+                                * unused by swap_free while we are trying
+                                * to read in the page - this prevents warning
+                                * messages from rw_swap_page_base.
+                                */
+                               if (si->swap_map[i] != SWAP_MAP_MAX)
+                                       si->swap_map[i]++;
+                               swap_device_unlock(si);
                                goto found_entry;
                        }
                }
+               swap_device_unlock(si);
                break;
 
        found_entry:
@@ -375,11 +410,7 @@ static int try_to_unuse(unsigned int type)
                    page and read the swap into it. */
                page = read_swap_cache(entry);
                if (!page) {
-                       /*
-                        * Continue searching if the entry became unused.
-                        */
-                       if (si->swap_map[i] == 0)
-                               continue;
+                       swap_free(entry);
                        return -ENOMEM;
                }
                read_lock(&tasklist_lock);
@@ -395,12 +426,18 @@ static int try_to_unuse(unsigned int type)
                /*
                 * Check for and clear any overflowed swap map counts.
                 */
-               if (si->swap_map[i] != 0) {
+               swap_free(entry);
+               swap_list_lock();
+               swap_device_lock(si);
+               if (si->swap_map[i] > 0) {
                        if (si->swap_map[i] != SWAP_MAP_MAX)
-                               printk("VM: Undead swap entry %08lx\n", entry.val);
-                       si->swap_map[i] = 0;
+                               printk("VM: Undead swap entry %08lx\n", 
+                                                               entry.val);
                        nr_swap_pages++;
+                       si->swap_map[i] = 0;
                }
+               swap_device_unlock(si);
+               swap_list_unlock();
        }
        return 0;
 }
@@ -423,6 +460,7 @@ asmlinkage long sys_swapoff(const char * specialfile)
                goto out;
 
        prev = -1;
+       swap_list_lock();
        for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
                p = swap_info + type;
                if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
@@ -438,8 +476,10 @@ asmlinkage long sys_swapoff(const char * specialfile)
                prev = type;
        }
        err = -EINVAL;
-       if (type < 0)
+       if (type < 0) {
+               swap_list_unlock();
                goto out_dput;
+       }
 
        if (prev < 0) {
                swap_list.head = p->next;
@@ -450,10 +490,13 @@ asmlinkage long sys_swapoff(const char * specialfile)
                /* just pick something that's safe... */
                swap_list.next = swap_list.head;
        }
+       nr_swap_pages -= p->pages;
+       swap_list_unlock();
        p->flags = SWP_USED;
        err = try_to_unuse(type);
        if (err) {
                /* re-insert swap space back into swap_list */
+               swap_list_lock();
                for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
                        if (p->prio >= swap_info[i].prio)
                                break;
@@ -462,6 +505,8 @@ asmlinkage long sys_swapoff(const char * specialfile)
                        swap_list.head = swap_list.next = p - swap_info;
                else
                        swap_info[prev].next = p - swap_info;
+               nr_swap_pages += p->pages;
+               swap_list_unlock();
                p->flags = SWP_WRITEOK;
                goto out_dput;
        }
@@ -480,7 +525,6 @@ asmlinkage long sys_swapoff(const char * specialfile)
 
        dentry = p->swap_file;
        p->swap_file = NULL;
-       nr_swap_pages -= p->pages;
        p->swap_device = 0;
        vfree(p->swap_map);
        p->swap_map = NULL;
@@ -583,6 +627,7 @@ asmlinkage long sys_swapon(const char * specialfile, int swap_flags)
        p->lowest_bit = 0;
        p->highest_bit = 0;
        p->cluster_nr = 0;
+       p->sdev_lock = SPIN_LOCK_UNLOCKED;
        p->max = 1;
        p->next = -1;
        if (swap_flags & SWAP_FLAG_PREFER) {
@@ -746,6 +791,7 @@ asmlinkage long sys_swapon(const char * specialfile, int swap_flags)
        p->swap_map[0] = SWAP_MAP_BAD;
        p->flags = SWP_WRITEOK;
        p->pages = nr_good_pages;
+       swap_list_lock();
        nr_swap_pages += nr_good_pages;
        printk(KERN_INFO "Adding Swap: %dk swap-space (priority %d)\n",
               nr_good_pages<<(PAGE_SHIFT-10), p->prio);
@@ -764,6 +810,7 @@ asmlinkage long sys_swapon(const char * specialfile, int swap_flags)
        } else {
                swap_info[prev].next = p - swap_info;
        }
+       swap_list_unlock();
        error = 0;
        goto out;
 bad_swap:
@@ -811,3 +858,169 @@ void si_swapinfo(struct sysinfo *val)
        val->totalswap = totalswap;
        return;
 }
+
+/*
+ * Verify that a swap entry is valid and increment its swap map count.
+ * Kernel_lock is held, which guarantees existance of swap device.
+ *
+ * Note: if swap_map[] reaches SWAP_MAP_MAX the entries are treated as
+ * "permanent", but will be reclaimed by the next swapoff.
+ */
+int swap_duplicate(swp_entry_t entry)
+{
+       struct swap_info_struct * p;
+       unsigned long offset, type;
+       int result = 0;
+
+       /* Swap entry 0 is illegal */
+       if (!entry.val)
+               goto out;
+       type = SWP_TYPE(entry);
+       if (type >= nr_swapfiles)
+               goto bad_file;
+       p = type + swap_info;
+       offset = SWP_OFFSET(entry);
+       if (offset >= p->max)
+               goto bad_offset;
+       if (!p->swap_map[offset])
+               goto bad_unused;
+       /*
+        * Entry is valid, so increment the map count.
+        */
+       swap_device_lock(p);
+       if (p->swap_map[offset] < SWAP_MAP_MAX)
+               p->swap_map[offset]++;
+       else {
+               static int overflow = 0;
+               if (overflow++ < 5)
+                       printk("VM: swap entry overflow\n");
+               p->swap_map[offset] = SWAP_MAP_MAX;
+       }
+       swap_device_unlock(p);
+       result = 1;
+out:
+       return result;
+
+bad_file:
+       printk("Bad swap file entry %08lx\n", entry.val);
+       goto out;
+bad_offset:
+       printk("Bad swap offset entry %08lx\n", entry.val);
+       goto out;
+bad_unused:
+       printk("Unused swap offset entry in swap_dup %08lx\n", entry.val);
+       goto out;
+}
+
+/*
+ * Page lock needs to be held in all cases to prevent races with
+ * swap file deletion.
+ */
+int swap_count(struct page *page)
+{
+       struct swap_info_struct * p;
+       unsigned long offset, type;
+       swp_entry_t entry;
+       int retval = 0;
+
+       entry.val = page->index;
+       if (!entry.val)
+               goto bad_entry;
+       type = SWP_TYPE(entry);
+       if (type >= nr_swapfiles)
+               goto bad_file;
+       p = type + swap_info;
+       offset = SWP_OFFSET(entry);
+       if (offset >= p->max)
+               goto bad_offset;
+       if (!p->swap_map[offset])
+               goto bad_unused;
+       retval = p->swap_map[offset];
+out:
+       return retval;
+
+bad_entry:
+       printk(KERN_ERR "swap_count: null entry!\n");
+       goto out;
+bad_file:
+       printk("Bad swap file entry %08lx\n", entry.val);
+       goto out;
+bad_offset:
+       printk("Bad swap offset entry %08lx\n", entry.val);
+       goto out;
+bad_unused:
+       printk("Unused swap offset entry in swap_count %08lx\n", entry.val);
+       goto out;
+}
+
+/*
+ * Kernel_lock protects against swap device deletion.
+ */
+void get_swaphandle_info(swp_entry_t entry, unsigned long *offset, 
+                       kdev_t *dev, struct inode **swapf)
+{
+       unsigned long type;
+       struct swap_info_struct *p;
+
+       type = SWP_TYPE(entry);
+       if (type >= nr_swapfiles) {
+               printk("Internal error: bad swap-device\n");
+               return;
+       }
+
+       p = &swap_info[type];
+       *offset = SWP_OFFSET(entry);
+       if (*offset >= p->max) {
+               printk("rw_swap_page: weirdness\n");
+               return;
+       }
+       if (p->swap_map && !p->swap_map[*offset]) {
+               printk("VM: Bad swap entry %08lx\n", entry.val);
+               return;
+       }
+       if (!(p->flags & SWP_USED)) {
+               printk(KERN_ERR "rw_swap_page: "
+                       "Trying to swap to unused swap-device\n");
+               return;
+       }
+
+       if (p->swap_device) {
+               *dev = p->swap_device;
+       } else if (p->swap_file) {
+               *swapf = p->swap_file->d_inode;
+       } else {
+               printk(KERN_ERR "rw_swap_page: no swap file or device\n");
+       }
+       return;
+}
+
+/*
+ * Kernel_lock protects against swap device deletion. Grab an extra
+ * reference on the swaphandle so that it dos not become unused.
+ */
+int valid_swaphandles(swp_entry_t entry, unsigned long *offset)
+{
+       int ret = 0, i = 1 << page_cluster;
+       unsigned long toff;
+       struct swap_info_struct *swapdev = SWP_TYPE(entry) + swap_info;
+
+       *offset = SWP_OFFSET(entry);
+       toff = *offset = (*offset >> page_cluster) << page_cluster;
+
+       swap_device_lock(swapdev);
+       do {
+               /* Don't read-ahead past the end of the swap area */
+               if (toff >= swapdev->max)
+                       break;
+               /* Don't read in bad or busy pages */
+               if (!swapdev->swap_map[toff])
+                       break;
+               if (swapdev->swap_map[toff] == SWAP_MAP_BAD)
+                       break;
+               swapdev->swap_map[toff]++;
+               toff++;
+               ret++;
+       } while (--i);
+       swap_device_unlock(swapdev);
+       return ret;
+}