diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
commit | 012bb3e61e5eced6c610f9e036372bf0c8def2d1 (patch) | |
tree | 87efc733f9b164e8c85c0336f92c8fb7eff6d183 /arch | |
parent | 625a1589d3d6464b5d90b8a0918789e3afffd220 (diff) |
Merge with Linux 2.4.0-test9. Please check DECstation, I had a number
of rejects to fixup while integrating Linus patches. I also found
that this kernel will only boot SMP on Origin; the UP kernel freeze
soon after bootup with SCSI timeout messages. I commit this anyway
since I found that the last CVS versions had the same problem.
Diffstat (limited to 'arch')
358 files changed, 13747 insertions, 6431 deletions
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile index 3daa2c73c..44ae94a99 100644 --- a/arch/alpha/Makefile +++ b/arch/alpha/Makefile @@ -8,7 +8,7 @@ # Copyright (C) 1994 by Linus Torvalds # -NM := nm -B +NM := $(NM) -B LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N #-relax CFLAGS := $(CFLAGS) -pipe -mno-fp-regs -ffixed-8 @@ -23,6 +23,8 @@ have_mcpu_pca56 := $(shell if $(CC) -mcpu=pca56 -S -o /dev/null -xc /dev/null > have_mcpu_ev6 := $(shell if $(CC) -mcpu=ev6 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi) +have_mcpu_ev67 := $(shell if $(CC) -mcpu=ev67 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi) + # Turn on the proper cpu optimizations. ifeq ($(have_mcpu),y) # If GENERIC, make sure to turn off any instruction set extensions that @@ -117,6 +119,10 @@ archmrproper: archdep: @$(MAKEBOOT) dep + +vmlinux: arch/alpha/vmlinux.lds + +arch/alpha/vmlinux.lds: arch/alpha/vmlinux.lds.in $(CPP) $(CPPFLAGS) -xc -P arch/alpha/vmlinux.lds.in -o arch/alpha/vmlinux.lds bootpfile: diff --git a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile index 47a472524..23789a91c 100644 --- a/arch/alpha/boot/Makefile +++ b/arch/alpha/boot/Makefile @@ -68,7 +68,7 @@ vmlinux.nh: $(VMLINUX) $(OBJSTRIP) $(OBJSTRIP) -v $(VMLINUX) vmlinux.nh vmlinux: $(TOPDIR)/vmlinux - strip -o vmlinux $(VMLINUX) + $(STRIP) -o vmlinux $(VMLINUX) tools/lxboot: $(OBJSTRIP) bootloader $(OBJSTRIP) -p bootloader tools/lxboot diff --git a/arch/alpha/config.in b/arch/alpha/config.in index 6485df4af..3b0126e7d 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -239,6 +239,8 @@ source drivers/pnp/Config.in source drivers/block/Config.in +source drivers/md/Config.in + if [ "$CONFIG_NET" = "y" ]; then source net/Config.in fi diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c index 5aa00254b..c686fd29d 100644 --- a/arch/alpha/kernel/core_cia.c +++ b/arch/alpha/kernel/core_cia.c @@ -754,6 +754,364 @@ cia_pci_clr_err(void) *(vip)CIA_IOC_CIA_ERR; /* re-read to force write. */ } +static void +cia_decode_pci_error(struct el_CIA_sysdata_mcheck *cia, const char *msg) +{ + static const char * const pci_cmd_desc[16] = { + "Interrupt Acknowledge", "Special Cycle", "I/O Read", + "I/O Write", "Reserved 0x4", "Reserved 0x5", "Memory Read", + "Memory Write", "Reserved 0x8", "Reserved 0x9", + "Configuration Read", "Configuration Write", + "Memory Read Multiple", "Dual Address Cycle", + "Memory Read Line", "Memory Write and Invalidate" + }; + + if (cia->cia_err & (CIA_ERR_COR_ERR + | CIA_ERR_UN_COR_ERR + | CIA_ERR_MEM_NEM + | CIA_ERR_PA_PTE_INV)) { + static const char * const window_desc[6] = { + "No window active", "Window 0 hit", "Window 1 hit", + "Window 2 hit", "Window 3 hit", "Monster window hit" + }; + + const char *window; + const char *cmd; + unsigned long addr, tmp; + int lock, dac; + + cmd = pci_cmd_desc[cia->pci_err0 & 0x7]; + lock = (cia->pci_err0 >> 4) & 1; + dac = (cia->pci_err0 >> 5) & 1; + + tmp = (cia->pci_err0 >> 8) & 0x1F; + tmp = ffs(tmp); + window = window_desc[tmp]; + + addr = cia->pci_err1; + if (dac) { + tmp = *(vip)CIA_IOC_PCI_W_DAC & 0xFFUL; + addr |= tmp << 32; + } + + printk(KERN_CRIT "CIA machine check: %s\n", msg); + printk(KERN_CRIT " DMA command: %s\n", cmd); + printk(KERN_CRIT " PCI address: %#010lx\n", addr); + printk(KERN_CRIT " %s, Lock: %d, DAC: %d\n", + window, lock, dac); + } else if (cia->cia_err & (CIA_ERR_PERR + | CIA_ERR_PCI_ADDR_PE + | CIA_ERR_RCVD_MAS_ABT + | CIA_ERR_RCVD_TAR_ABT + | CIA_ERR_IOA_TIMEOUT)) { + static const char * const master_st_desc[16] = { + "Idle", "Drive bus", "Address step cycle", + "Address cycle", "Data cycle", "Last read data cycle", + "Last write data cycle", "Read stop cycle", + "Write stop cycle", "Read turnaround cycle", + "Write turnaround cycle", "Reserved 0xB", + "Reserved 0xC", "Reserved 0xD", "Reserved 0xE", + "Unknown state" + }; + static const char * const target_st_desc[16] = { + "Idle", "Busy", "Read data cycle", "Write data cycle", + "Read stop cycle", "Write stop cycle", + "Read turnaround cycle", "Write turnaround cycle", + "Read wait cycle", "Write wait cycle", + "Reserved 0xA", "Reserved 0xB", "Reserved 0xC", + "Reserved 0xD", "Reserved 0xE", "Unknown state" + }; + + const char *cmd; + const char *master, *target; + unsigned long addr, tmp; + int dac; + + master = master_st_desc[(cia->pci_err0 >> 16) & 0xF]; + target = target_st_desc[(cia->pci_err0 >> 20) & 0xF]; + cmd = pci_cmd_desc[(cia->pci_err0 >> 24) & 0xF]; + dac = (cia->pci_err0 >> 28) & 1; + + addr = cia->pci_err2; + if (dac) { + tmp = *(volatile int *)CIA_IOC_PCI_W_DAC & 0xFFUL; + addr |= tmp << 32; + } + + printk(KERN_CRIT "CIA machine check: %s\n", msg); + printk(KERN_CRIT " PCI command: %s\n", cmd); + printk(KERN_CRIT " Master state: %s, Target state: %s\n", + master, target); + printk(KERN_CRIT " PCI address: %#010lx, DAC: %d\n", + addr, dac); + } else { + printk(KERN_CRIT "CIA machine check: %s\n", msg); + printk(KERN_CRIT " Unknown PCI error\n"); + printk(KERN_CRIT " PCI_ERR0 = %#08lx", cia->pci_err0); + printk(KERN_CRIT " PCI_ERR1 = %#08lx", cia->pci_err1); + printk(KERN_CRIT " PCI_ERR2 = %#08lx", cia->pci_err2); + } +} + +static void +cia_decode_mem_error(struct el_CIA_sysdata_mcheck *cia, const char *msg) +{ + unsigned long mem_port_addr; + unsigned long mem_port_mask; + const char *mem_port_cmd; + const char *seq_state; + const char *set_select; + unsigned long tmp; + + /* If this is a DMA command, also decode the PCI bits. */ + if ((cia->mem_err1 >> 20) & 1) + cia_decode_pci_error(cia, msg); + else + printk(KERN_CRIT "CIA machine check: %s\n", msg); + + mem_port_addr = cia->mem_err0 & 0xfffffff0; + mem_port_addr |= (cia->mem_err1 & 0x83UL) << 32; + + mem_port_mask = (cia->mem_err1 >> 12) & 0xF; + + tmp = (cia->mem_err1 >> 8) & 0xF; + tmp |= ((cia->mem_err1 >> 20) & 1) << 4; + if ((tmp & 0x1E) == 0x06) + mem_port_cmd = "WRITE BLOCK or WRITE BLOCK LOCK"; + else if ((tmp & 0x1C) == 0x08) + mem_port_cmd = "READ MISS or READ MISS MODIFY"; + else if (tmp == 0x1C) + mem_port_cmd = "BC VICTIM"; + else if ((tmp & 0x1E) == 0x0E) + mem_port_cmd = "READ MISS MODIFY"; + else if ((tmp & 0x1C) == 0x18) + mem_port_cmd = "DMA READ or DMA READ MODIFY"; + else if ((tmp & 0x1E) == 0x12) + mem_port_cmd = "DMA WRITE"; + else + mem_port_cmd = "Unknown"; + + tmp = (cia->mem_err1 >> 16) & 0xF; + switch (tmp) { + case 0x0: + seq_state = "Idle"; + break; + case 0x1: + seq_state = "DMA READ or DMA WRITE"; + break; + case 0x2: case 0x3: + seq_state = "READ MISS (or READ MISS MODIFY) with victim"; + break; + case 0x4: case 0x5: case 0x6: + seq_state = "READ MISS (or READ MISS MODIFY) with no victim"; + break; + case 0x8: case 0x9: case 0xB: + seq_state = "Refresh"; + break; + case 0xC: + seq_state = "Idle, waiting for DMA pending read"; + break; + case 0xE: case 0xF: + seq_state = "Idle, ras precharge"; + break; + default: + seq_state = "Unknown"; + break; + } + + tmp = (cia->mem_err1 >> 24) & 0x1F; + switch (tmp) { + case 0x00: set_select = "Set 0 selected"; break; + case 0x01: set_select = "Set 1 selected"; break; + case 0x02: set_select = "Set 2 selected"; break; + case 0x03: set_select = "Set 3 selected"; break; + case 0x04: set_select = "Set 4 selected"; break; + case 0x05: set_select = "Set 5 selected"; break; + case 0x06: set_select = "Set 6 selected"; break; + case 0x07: set_select = "Set 7 selected"; break; + case 0x08: set_select = "Set 8 selected"; break; + case 0x09: set_select = "Set 9 selected"; break; + case 0x0A: set_select = "Set A selected"; break; + case 0x0B: set_select = "Set B selected"; break; + case 0x0C: set_select = "Set C selected"; break; + case 0x0D: set_select = "Set D selected"; break; + case 0x0E: set_select = "Set E selected"; break; + case 0x0F: set_select = "Set F selected"; break; + case 0x10: set_select = "No set selected"; break; + case 0x1F: set_select = "Refresh cycle"; break; + default: set_select = "Unknown"; break; + } + + printk(KERN_CRIT " Memory port command: %s\n", mem_port_cmd); + printk(KERN_CRIT " Memory port address: %#010lx, mask: %#lx\n", + mem_port_addr, mem_port_mask); + printk(KERN_CRIT " Memory sequencer state: %s\n", seq_state); + printk(KERN_CRIT " Memory set: %s\n", set_select); +} + +static void +cia_decode_ecc_error(struct el_CIA_sysdata_mcheck *cia, const char *msg) +{ + long syn; + long i; + const char *fmt; + + cia_decode_mem_error(cia, msg); + + syn = cia->cia_syn & 0xff; + if (syn == (syn & -syn)) { + fmt = KERN_CRIT " ECC syndrome %#x -- check bit %d\n"; + i = ffs(syn) - 1; + } else { + static unsigned char const data_bit[64] = { + 0xCE, 0xCB, 0xD3, 0xD5, + 0xD6, 0xD9, 0xDA, 0xDC, + 0x23, 0x25, 0x26, 0x29, + 0x2A, 0x2C, 0x31, 0x34, + 0x0E, 0x0B, 0x13, 0x15, + 0x16, 0x19, 0x1A, 0x1C, + 0xE3, 0xE5, 0xE6, 0xE9, + 0xEA, 0xEC, 0xF1, 0xF4, + 0x4F, 0x4A, 0x52, 0x54, + 0x57, 0x58, 0x5B, 0x5D, + 0xA2, 0xA4, 0xA7, 0xA8, + 0xAB, 0xAD, 0xB0, 0xB5, + 0x8F, 0x8A, 0x92, 0x94, + 0x97, 0x98, 0x9B, 0x9D, + 0x62, 0x64, 0x67, 0x68, + 0x6B, 0x6D, 0x70, 0x75 + }; + + for (i = 0; i < 64; ++i) + if (data_bit[i] == syn) + break; + + if (i < 64) + fmt = KERN_CRIT " ECC syndrome %#x -- data bit %d\n"; + else + fmt = KERN_CRIT " ECC syndrome %#x -- unknown bit\n"; + } + + printk (fmt, syn, i); +} + +static void +cia_decode_parity_error(struct el_CIA_sysdata_mcheck *cia) +{ + static const char * const cmd_desc[16] = { + "NOP", "LOCK", "FETCH", "FETCH_M", "MEMORY BARRIER", + "SET DIRTY", "WRITE BLOCK", "WRITE BLOCK LOCK", + "READ MISS0", "READ MISS1", "READ MISS MOD0", + "READ MISS MOD1", "BCACHE VICTIM", "Spare", + "READ MISS MOD STC0", "READ MISS MOD STC1" + }; + + unsigned long addr; + unsigned long mask; + const char *cmd; + int par; + + addr = cia->cpu_err0 & 0xfffffff0; + addr |= (cia->cpu_err1 & 0x83UL) << 32; + cmd = cmd_desc[(cia->cpu_err1 >> 8) & 0xF]; + mask = (cia->cpu_err1 >> 12) & 0xF; + par = (cia->cpu_err1 >> 21) & 1; + + printk(KERN_CRIT "CIA machine check: System bus parity error\n"); + printk(KERN_CRIT " Command: %s, Parity bit: %d\n", cmd, par); + printk(KERN_CRIT " Address: %#010lx, Mask: %#lx\n", addr, mask); +} + +static int +cia_decode_mchk(unsigned long la_ptr) +{ + struct el_common *com; + struct el_CIA_sysdata_mcheck *cia; + int which; + + com = (void *)la_ptr; + cia = (void *)(la_ptr + com->sys_offset); + + if ((cia->cia_err & CIA_ERR_VALID) == 0) + return 0; + + which = cia->cia_err & 0xfff; + switch (ffs(which) - 1) { + case 0: /* CIA_ERR_COR_ERR */ + cia_decode_ecc_error(cia, "Corrected ECC error"); + break; + case 1: /* CIA_ERR_UN_COR_ERR */ + cia_decode_ecc_error(cia, "Uncorrected ECC error"); + break; + case 2: /* CIA_ERR_CPU_PE */ + cia_decode_parity_error(cia); + break; + case 3: /* CIA_ERR_MEM_NEM */ + cia_decode_mem_error(cia, "Access to nonexistent memory"); + break; + case 4: /* CIA_ERR_PCI_SERR */ + cia_decode_pci_error(cia, "PCI bus system error"); + break; + case 5: /* CIA_ERR_PERR */ + cia_decode_pci_error(cia, "PCI data parity error"); + break; + case 6: /* CIA_ERR_PCI_ADDR_PE */ + cia_decode_pci_error(cia, "PCI address parity error"); + break; + case 7: /* CIA_ERR_RCVD_MAS_ABT */ + cia_decode_pci_error(cia, "PCI master abort"); + break; + case 8: /* CIA_ERR_RCVD_TAR_ABT */ + cia_decode_pci_error(cia, "PCI target abort"); + break; + case 9: /* CIA_ERR_PA_PTE_INV */ + cia_decode_pci_error(cia, "PCI invalid PTE"); + break; + case 10: /* CIA_ERR_FROM_WRT_ERR */ + cia_decode_mem_error(cia, "Write to flash ROM attempted"); + break; + case 11: /* CIA_ERR_IOA_TIMEOUT */ + cia_decode_pci_error(cia, "I/O timeout"); + break; + } + + if (cia->cia_err & CIA_ERR_LOST_CORR_ERR) + printk(KERN_CRIT "CIA lost machine check: " + "Correctable ECC error\n"); + if (cia->cia_err & CIA_ERR_LOST_UN_CORR_ERR) + printk(KERN_CRIT "CIA lost machine check: " + "Uncorrectable ECC error\n"); + if (cia->cia_err & CIA_ERR_LOST_CPU_PE) + printk(KERN_CRIT "CIA lost machine check: " + "System bus parity error\n"); + if (cia->cia_err & CIA_ERR_LOST_MEM_NEM) + printk(KERN_CRIT "CIA lost machine check: " + "Access to nonexistent memory\n"); + if (cia->cia_err & CIA_ERR_LOST_PERR) + printk(KERN_CRIT "CIA lost machine check: " + "PCI data parity error\n"); + if (cia->cia_err & CIA_ERR_LOST_PCI_ADDR_PE) + printk(KERN_CRIT "CIA lost machine check: " + "PCI address parity error\n"); + if (cia->cia_err & CIA_ERR_LOST_RCVD_MAS_ABT) + printk(KERN_CRIT "CIA lost machine check: " + "PCI master abort\n"); + if (cia->cia_err & CIA_ERR_LOST_RCVD_TAR_ABT) + printk(KERN_CRIT "CIA lost machine check: " + "PCI target abort\n"); + if (cia->cia_err & CIA_ERR_LOST_PA_PTE_INV) + printk(KERN_CRIT "CIA lost machine check: " + "PCI invalid PTE\n"); + if (cia->cia_err & CIA_ERR_LOST_FROM_WRT_ERR) + printk(KERN_CRIT "CIA lost machine check: " + "Write to flash ROM attempted\n"); + if (cia->cia_err & CIA_ERR_LOST_IOA_TIMEOUT) + printk(KERN_CRIT "CIA lost machine check: " + "I/O timeout\n"); + + return 1; +} + void cia_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) @@ -769,30 +1127,7 @@ cia_machine_check(unsigned long vector, unsigned long la_ptr, mb(); expected = mcheck_expected(0); - if (!expected && vector == 0x660) { - struct el_common *com; - struct el_common_EV5_uncorrectable_mcheck *ev5; - struct el_CIA_sysdata_mcheck *cia; - - com = (void *)la_ptr; - ev5 = (void *)(la_ptr + com->proc_offset); - cia = (void *)(la_ptr + com->sys_offset); - - if (com->code == 0x202) { - printk(KERN_CRIT "CIA PCI machine check: code=%x\n" - " cpu_err0=%08x cpu_err1=%08x cia_err=%08x\n" - " cia_stat=%08x err_mask=%08x cia_syn=%08x\n" - " mem_err0=%08x mem_err1=%08x\n" - " pci_err0=%08x pci_err1=%08x pci_err2=%08x\n", - (int) com->code, - (int) cia->cpu_err0, (int) cia->cpu_err1, - (int) cia->cia_err, (int) cia->cia_stat, - (int) cia->err_mask, (int) cia->cia_syn, - (int) cia->mem_err0, (int) cia->mem_err1, - (int) cia->pci_err0, (int) cia->pci_err1, - (int) cia->pci_err2); - expected = 1; - } - } + if (!expected && vector == 0x660) + expected = cia_decode_mchk(la_ptr); process_mcheck_info(vector, la_ptr, regs, "CIA", expected); } diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c index 453766d2e..030348747 100644 --- a/arch/alpha/kernel/core_irongate.c +++ b/arch/alpha/kernel/core_irongate.c @@ -28,12 +28,7 @@ #include "proto.h" #include "pci_impl.h" - -/* - * NOTE: Herein lie back-to-back mb instructions. They are magic. - * One plausible explanation is that the I/O controller does not properly - * handle the system transaction. Another involves timing. Ho hum. - */ +#undef DEBUG_IRONGATE /* define to enable verbose Irongate debug */ /* * BIOS32-style PCI interface: @@ -200,11 +195,12 @@ struct pci_ops irongate_pci_ops = write_dword: irongate_write_config_dword }; -#if 0 +#ifdef DEBUG_IRONGATE static void irongate_register_dump(const char *function_name) { printk("%s: Irongate registers:\n" + "\tFunction 0:\n" "\tdev_vendor\t0x%08x\n" "\tstat_cmd\t0x%08x\n" "\tclass\t\t0x%08x\n" @@ -249,7 +245,26 @@ irongate_register_dump(const char *function_name) "\tagpstat\t\t0x%08x\n" "\tagpcmd\t\t0x%08x\n" "\tagpva\t\t0x%08x\n" - "\tagpmode\t\t0x%08x\n", + "\tagpmode\t\t0x%08x\n" + + "\n\tFunction 1:\n" + "\tdev_vendor:\t0x%08x\n" + "\tcmd_status:\t0x%08x\n" + "\trevid_etc :\t0x%08x\n" + "\thtype_etc :\t0x%08x\n" + "\trsrvd0[0] :\t0x%08x\n" + "\trsrvd0[1] :\t0x%08x\n" + "\tbus_nmbers:\t0x%08x\n" + "\tio_baselim:\t0x%08x\n" + "\tmem_bselim:\t0x%08x\n" + "\tpf_baselib:\t0x%08x\n" + "\trsrvd1[0] :\t0x%08x\n" + "\trsrvd1[1] :\t0x%08x\n" + "\tio_baselim:\t0x%08x\n" + "\trsrvd2[0] :\t0x%08x\n" + "\trsrvd2[1] :\t0x%08x\n" + "\tinterrupt :\t0x%08x\n", + function_name, IRONGATE0->dev_vendor, IRONGATE0->stat_cmd, @@ -295,7 +310,23 @@ irongate_register_dump(const char *function_name) IRONGATE0->agpstat, IRONGATE0->agpcmd, IRONGATE0->agpva, - IRONGATE0->agpmode); + IRONGATE0->agpmode, + IRONGATE1->dev_vendor, + IRONGATE1->stat_cmd, + IRONGATE1->class, + IRONGATE1->htype, + IRONGATE1->rsrvd0[0], + IRONGATE1->rsrvd0[1], + IRONGATE1->busnos, + IRONGATE1->io_baselim_regs, + IRONGATE1->mem_baselim, + IRONGATE1->pfmem_baselim, + IRONGATE1->rsrvd1[0], + IRONGATE1->rsrvd1[1], + IRONGATE1->io_baselim, + IRONGATE1->rsrvd2[0], + IRONGATE1->rsrvd2[1], + IRONGATE1->interrupt ); } #else #define irongate_register_dump(x) diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 7dda5b566..5035d2ca3 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -833,7 +833,7 @@ sys_call_table: .quad alpha_ni_syscall .quad alpha_ni_syscall /* 50 */ .quad sys_acct - .quad osf_sigpending + .quad sys_sigpending .quad alpha_ni_syscall .quad sys_ioctl .quad alpha_ni_syscall /* 55 */ diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index ccf0cefbb..3b727631a 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -416,7 +416,9 @@ sg_fill(struct scatterlist *leader, struct scatterlist *end, ptes = &arena->ptes[dma_ofs]; sg = leader; do { +#if DEBUG_ALLOC > 0 struct scatterlist *last_sg = sg; +#endif size = sg->length; paddr = virt_to_phys(sg->address); diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 81d85386d..508e278b0 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -276,14 +276,14 @@ alpha_clone(unsigned long clone_flags, unsigned long usp, { if (!usp) usp = rdusp(); - return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1)); + return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1), 0); } int alpha_vfork(struct switch_stack * swstack) { return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), - (struct pt_regs *) (swstack+1)); + (struct pt_regs *) (swstack+1), 0); } /* @@ -299,6 +299,7 @@ alpha_vfork(struct switch_stack * swstack) int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, + unsigned long unused, struct task_struct * p, struct pt_regs * regs) { extern void ret_from_sys_call(void); diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index db8cacbc9..73df1e930 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -170,18 +170,6 @@ sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact, return ret; } -asmlinkage int -osf_sigpending(old_sigset_t *set) -{ - sigset_t pending; - - spin_lock_irq(¤t->sigmask_lock); - sigandsets(&pending, ¤t->blocked, ¤t->signal); - spin_unlock_irq(¤t->sigmask_lock); - - return copy_to_user(set, &pending, sizeof(*set)); -} - /* * Atomically swap in the new signal mask, and wait for a signal. */ @@ -729,7 +717,7 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, default: lock_kernel(); - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); current->flags |= PF_SIGNALED; do_exit(exit_code); /* NOTREACHED */ diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 4f7a04b3f..dd882dc14 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -420,7 +420,7 @@ static int __init fork_by_hand(void) * don't care about the regs settings since * we'll never reschedule the forked task. */ - return do_fork(CLONE_VM|CLONE_PID, 0, ®s); + return do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0); } /* @@ -1046,8 +1046,8 @@ debug_spin_lock(spinlock_t * lock, const char *base_file, int line_no) " blbs %0,2b\n" " br 1b\n" ".previous" - : "=r" (tmp), "=m" (__dummy_lock(lock)), "=r" (stuck) - : "1" (__dummy_lock(lock)), "2" (stuck)); + : "=r" (tmp), "=m" (lock->lock), "=r" (stuck) + : "1" (lock->lock), "2" (stuck) : "memory"); if (stuck < 0) { printk(KERN_WARNING @@ -1124,9 +1124,9 @@ void write_lock(rwlock_t * lock) " blt %1,8b\n" " br 1b\n" ".previous" - : "=m" (__dummy_lock(lock)), "=&r" (regx), "=&r" (regy), + : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (regy), "=&r" (stuck_lock), "=&r" (stuck_reader) - : "0" (__dummy_lock(lock)), "3" (stuck_lock), "4" (stuck_reader)); + : "0" (*(volatile int *)lock), "3" (stuck_lock), "4" (stuck_reader) : "memory"); if (stuck_lock < 0) { printk(KERN_WARNING "write_lock stuck at %p\n", inline_pc); @@ -1163,8 +1163,8 @@ void read_lock(rwlock_t * lock) " blbs %1,6b;" " br 1b\n" ".previous" - : "=m" (__dummy_lock(lock)), "=&r" (regx), "=&r" (stuck_lock) - : "0" (__dummy_lock(lock)), "2" (stuck_lock)); + : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (stuck_lock) + : "0" (*(volatile int *)lock), "2" (stuck_lock) : "memory"); if (stuck_lock < 0) { printk(KERN_WARNING "read_lock stuck at %p\n", inline_pc); diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 00120e251..0edf60839 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -36,6 +36,7 @@ #include <linux/ioport.h> #include <linux/irq.h> #include <linux/interrupt.h> +#include <linux/init.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -135,38 +136,6 @@ void timer_interrupt(int irq, void *dev, struct pt_regs * regs) write_unlock(&xtime_lock); } -/* - * Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - void common_init_rtc(void) { @@ -200,7 +169,7 @@ common_init_rtc(void) init_rtc_irq(); } -void +void __init time_init(void) { unsigned int year, mon, day, hour, min, sec, cc1, cc2, epoch; @@ -267,17 +236,14 @@ time_init(void) BCD_TO_BIN(year); } - /* PC-like is standard; used for year <= 20 || year >= 100 */ + /* PC-like is standard; used for year < 20 || year >= 70 */ epoch = 1900; - if (year > 20 && year < 48) - /* ARC console, used on some not so old boards */ + if (year >= 20 && year < 48) + /* NT epoch */ epoch = 1980; else if (year >= 48 && year < 70) - /* Digital UNIX, used on older boards (eg. AXPpxi33) */ + /* Digital UNIX epoch */ epoch = 1952; - else if (year >= 70 && year < 100) - /* Digital DECstations, very old... */ - epoch = 1928; printk(KERN_INFO "Using epoch = %d\n", epoch); diff --git a/arch/alpha/math-emu/Makefile b/arch/alpha/math-emu/Makefile index b5fc37765..91e5ba660 100644 --- a/arch/alpha/math-emu/Makefile +++ b/arch/alpha/math-emu/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := math-emu.o -O_OBJS := math.o +O_OBJS := math.o qrnnd.o CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w ifeq ($(CONFIG_MATHEMU),m) diff --git a/arch/alpha/math-emu/math.c b/arch/alpha/math-emu/math.c index ed2efe087..4e28b18cf 100644 --- a/arch/alpha/math-emu/math.c +++ b/arch/alpha/math-emu/math.c @@ -84,66 +84,6 @@ void cleanup_module(void) #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 diff --git a/arch/alpha/math-emu/qrnnd.S b/arch/alpha/math-emu/qrnnd.S new file mode 100644 index 000000000..d6373ec1b --- /dev/null +++ b/arch/alpha/math-emu/qrnnd.S @@ -0,0 +1,163 @@ + # Alpha 21064 __udiv_qrnnd + # Copyright (C) 1992, 1994, 1995, 2000 Free Software Foundation, Inc. + + # This file is part of GCC. + + # The GNU MP Library 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. + + # In addition to the permissions in the GNU General Public License, the + # Free Software Foundation gives you unlimited permission to link the + # compiled version of this file with other programs, and to distribute + # those programs without any restriction coming from the use of this + # file. (The General Public License restrictions do apply in other + # respects; for example, they cover modification of the file, and + # distribution when not linked into another program.) + + # This file 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 General Public License + # along with GCC; see the file COPYING. If not, write to the + # Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + # MA 02111-1307, USA. + + .set noreorder + .set noat + + .text + + .globl __udiv_qrnnd + .ent __udiv_qrnnd +__udiv_qrnnd: + .frame $30,0,$26,0 + .prologue 0 + +#define cnt $2 +#define tmp $3 +#define rem_ptr $16 +#define n1 $17 +#define n0 $18 +#define d $19 +#define qb $20 +#define AT $at + + ldiq cnt,16 + blt d,$largedivisor + +$loop1: cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule d,n1,qb + subq n1,d,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + subq cnt,1,cnt + bgt cnt,$loop1 + stq n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + +$largedivisor: + and n0,1,$4 + + srl n0,1,n0 + sll n1,63,tmp + or tmp,n0,n0 + srl n1,1,n1 + + and d,1,$6 + srl d,1,$5 + addq $5,$6,$5 + +$loop2: cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + cmplt n0,0,tmp + addq n1,n1,n1 + bis n1,tmp,n1 + addq n0,n0,n0 + cmpule $5,n1,qb + subq n1,$5,tmp + cmovne qb,tmp,n1 + bis n0,qb,n0 + subq cnt,1,cnt + bgt cnt,$loop2 + + addq n1,n1,n1 + addq $4,n1,n1 + bne $6,$Odd + stq n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + +$Odd: + /* q' in n0. r' in n1 */ + addq n1,n0,n1 + + cmpult n1,n0,tmp # tmp := carry from addq + subq n1,d,AT + addq n0,tmp,n0 + cmovne tmp,AT,n1 + + cmpult n1,d,tmp + addq n0,1,AT + cmoveq tmp,AT,n0 + subq n1,d,AT + cmoveq tmp,AT,n1 + + stq n1,0(rem_ptr) + bis $31,n0,$0 + ret $31,($26),1 + + .end __udiv_qrnnd diff --git a/arch/alpha/math-emu/sfp-util.h b/arch/alpha/math-emu/sfp-util.h index 7a6a8cf45..f53707f77 100644 --- a/arch/alpha/math-emu/sfp-util.h +++ b/arch/alpha/math-emu/sfp-util.h @@ -17,18 +17,13 @@ : "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; \ +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { unsigned long __r; \ + (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ + (r) = __r; \ } while (0) +extern unsigned long __udiv_qrnnd (unsigned long *, unsigned long, + unsigned long , unsigned long); #define UDIV_NEEDS_NORMALIZATION 1 diff --git a/arch/alpha/mm/extable.c b/arch/alpha/mm/extable.c index d3a02fe27..5390bd4ec 100644 --- a/arch/alpha/mm/extable.c +++ b/arch/alpha/mm/extable.c @@ -88,7 +88,7 @@ search_exception_table(unsigned long addr, unsigned long exc_gp) */ ret = search_exception_table_without_gp(addr); if (ret) { - printk(KERN_ALERT, "%s: [%lx] EX_TABLE search fail with" + printk(KERN_ALERT "%s: [%lx] EX_TABLE search fail with" "exc frame GP, success with raw GP\n", current->comm, addr); return ret; diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index bf4839b8f..c81a12d18 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -167,7 +167,7 @@ no_context: if ((fixup = search_exception_table(regs->pc, regs->gp)) != 0) { unsigned long newpc; newpc = fixup_exception(dpf_reg, fixup, regs->pc); -#if 1 +#if 0 printk("%s: Exception at [<%lx>] (%lx) handled successfully\n", current->comm, regs->pc, newpc); #endif diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 81b78feb9..c19ccddec 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -10,7 +10,7 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 1995-1999 by Russell King +# Copyright (C) 1995-2000 by Russell King OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S CPP := $(CC) -E @@ -32,38 +32,30 @@ endif GZFLAGS = -9 # Ensure this is ld "2.9.4" or later -NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi) +NEW_LINKER := $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?) -ifneq ($(NEW_LINKER),y) +ifneq ($(NEW_LINKER),0) dummy:; @echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.' @echo '*** Please upgrade your binutils to 2.9.5.' @false endif # GCC 2.7 uses different options to later compilers; sort out which we have -NEW_GCC := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then echo n; else echo y; fi) +NEW_GCC := $(shell $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; echo $$?) # # select flags depending on the compiler # -ifeq ($(NEW_GCC),y) +ifneq ($(NEW_GCC),0) CFLAGS += -mshort-load-bytes CFLAGS_PROC_CPU_26 := -mcpu=arm3 -mapcs-26 -Os CFLAGS_PROC_CPU_32v3 := -march=armv3 CFLAGS_PROC_CPU_32v4 := -march=armv4 -CFLAGS_ARM6 := -mtune=arm6 -CFLAGS_ARM7 := -mtune=arm7 -CFLAGS_ARM720 := -mtune=arm7tdmi -CFLAGS_SA110 := -mtune=strongarm110 else CFLAGS += -DNO_TEXT_SECTIONS CFLAGS_PROC_CPU_26 := -m3 -CFLAGS_PROC_CPU_32v3 := -CFLAGS_PROC_CPU_32v4 := -CFLAGS_ARM6 := -m6 -CFLAGS_ARM7 := -m6 -CFLAGS_ARM720 := -m6 -CFLAGS_SA110 := -m6 +CFLAGS_PROC_CPU_32v3 := -m6 +CFLAGS_PROC_CPU_32v4 := -m6 endif # @@ -86,27 +78,16 @@ ifeq ($(CONFIG_CPU_32),y) CFLAGS += $(CFLAGS_PROC_CPU_32v3) AFLAGS += -mapcs-32 -marmv3m endif - # - # Exactly one of the following must be selected - # - ifeq ($(CONFIG_CPU_ARM6),y) - CFLAGS += $(CFLAGS_ARM6) - else - ifeq ($(CONFIG_CPU_ARM7),y) - CFLAGS += $(CFLAGS_ARM7) - else - ifeq ($(CONFIG_CPU_ARM720),y) - CFLAGS += $(CFLAGS_ARM720) - else - ifeq ($(CONFIG_CPU_SA110),y) - CFLAGS += $(CFLAGS_SA110) - else - ifeq ($(CONFIG_CPU_SA1100),y) - CFLAGS += $(CFLAGS_SA110) - endif - endif - endif - endif + + opt-$(CONFIG_CPU_ARM6) := -mtune=arm6 + opt-$(CONFIG_CPU_ARM7) := -mtune=arm7 + opt-$(CONFIG_CPU_ARM720) := -mtune=arm7tdmi + opt-$(CONFIG_CPU_ARM920) := -mtune=arm9tdmi + opt-$(CONFIG_CPU_SA110) := -mtune=strongarm110 + opt-$(CONFIG_CPU_SA1100) := -mtune=strongarm110 + + ifneq ($(NEW_GCC),0) + CFLAGS += $(opt-y) endif endif @@ -116,51 +97,63 @@ export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS ifeq ($(CONFIG_ARCH_ARCA5K),y) MACHINE = arc -ARCHDIR = arc endif ifeq ($(CONFIG_ARCH_RPC),y) MACHINE = rpc -ARCHDIR = rpc endif ifeq ($(CONFIG_ARCH_EBSA110),y) MACHINE = ebsa110 -ARCHDIR = ebsa110 endif ifeq ($(CONFIG_ARCH_CLPS7500),y) MACHINE = clps7500 -ARCHDIR = cl7500 +INCDIR = cl7500 endif ifeq ($(CONFIG_FOOTBRIDGE),y) MACHINE = footbridge -ARCHDIR = ebsa285 +INCDIR = ebsa285 endif ifeq ($(CONFIG_ARCH_CO285),y) TEXTADDR = 0x60008000 +MACHINE = footbridge +INCDIR = ebsa285 endif ifeq ($(CONFIG_ARCH_NEXUSPCI),y) MACHINE = nexuspci -ARCHDIR = nexuspci endif ifeq ($(CONFIG_ARCH_SHARK),y) MACHINE = shark -ARCHDIR = shark endif ifeq ($(CONFIG_ARCH_SA1100),y) MACHINE = sa1100 -ARCHDIR = sa1100 endif ifeq ($(CONFIG_ARCH_L7200),y) MACHINE = l7200 -ARCHDIR = l7200 +endif + +ifeq ($(CONFIG_ARCH_INTEGRATOR),y) +MACHINE = integrator +endif + +# Only set INCDIR if its not already defined above +# Grr, ?= doesn't work as all the other assignment operators do. Make bug? +ifeq ($(origin INCDIR), undefined) +INCDIR := $(MACHINE) +endif + +# If we have a machine-specific directory, then include it in the build. +MACHDIR := arch/arm/mach-$(MACHINE) +ifeq ($(MACHDIR),$(wildcard $(MACHDIR))) +SUBDIRS += $(MACHDIR) +CORE_FILES := $(MACHDIR)/$(MACHINE).o $(CORE_FILES) endif HEAD := arch/arm/kernel/head-$(PROCESSOR).o \ @@ -193,36 +186,30 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot # to date before starting compilation $(patsubst %, _dir_%, $(SUBDIRS)) init/main.o init/version.o : \ - constants \ include/asm-arm/mach-types.h -include/asm-arm/mach-types.h: \ - arch/arm/tools/mach-types \ - arch/arm/tools/gen-mach-types +$(patsubst %, _dir_%, $(SUBDIRS)) : constants + +include/asm-arm/mach-types.h: arch/arm/tools/mach-types \ + arch/arm/tools/gen-mach-types @awk -f arch/arm/tools/gen-mach-types arch/arm/tools/mach-types > $@ -constants: $(TOPDIR)/include/asm-arm/proc-fns.h dummy +constants: dummy @$(MAKE) -C arch/arm/lib constants.h symlinks: archsymlinks archsymlinks: $(RM) include/asm-arm/arch include/asm-arm/proc - (cd include/asm-arm; ln -sf arch-$(ARCHDIR) arch; ln -sf proc-$(PROCESSOR) proc) + (cd include/asm-arm; ln -sf arch-$(INCDIR) arch; ln -sf proc-$(PROCESSOR) proc) vmlinux: arch/arm/vmlinux.lds arch/arm/vmlinux.lds: arch/arm/vmlinux-$(PROCESSOR).lds.in dummy @sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@ -arch/arm/kernel: dummy - $(MAKE) linuxsubdirs SUBDIRS=arch/arm/kernel - -arch/arm/mm: dummy - $(MAKE) linuxsubdirs SUBDIRS=arch/arm/mm - -arch/arm/lib: dummy - $(MAKE) linuxsubdirs SUBDIRS=arch/arm/lib +arch/arm/kernel arch/arm/mm arch/arm/lib: dummy + $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@) bzImage zImage zinstall Image bootpImage install: vmlinux @$(MAKEBOOT) $@ @@ -235,7 +222,7 @@ archclean: $(RM) arch/arm/lib/constants.h arch/arm/vmlinux.lds $(RM) include/asm-arm/mach-types.h -archdep: symlinks +archdep: archsymlinks @$(MAKEBOOT) dep # My testing targets (that short circuit a few dependencies) @@ -252,7 +239,7 @@ CFGS= a5k_config ebsa110_config \ brutus_config victor_config \ empeg_config thinclient_config \ assabet_config lart_config \ - cerf_config + cerf_config lusl7200_config $(CFGS): @( \ @@ -266,7 +253,3 @@ $(CFGS): echo "$$CFG does not exist"; \ fi; \ ) - -l7200_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/lusl7200 arch/arm/defconfig diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 2811e80ef..6fbdb5ea1 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -42,6 +42,13 @@ INITRD_PHYS = 0x00800000 INITRD_VIRT = 0xc0800000 endif +ifeq ($(CONFIG_ARCH_INTEGRATOR),y) +ZTEXTADDR = 0x00008000 +PARAMS = 0x00000100 +INITRD_PHYS = 0x00800000 +INITRD_VIRT = 0xc0800000 +endif + ifeq ($(CONFIG_ARCH_NEXUSPCI),y) ZTEXTADDR = 0x40200000 ZRELADDR = 0x40008000 @@ -105,10 +112,10 @@ initrd: @test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1) install: $(CONFIGURE) Image - sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) Image $(TOPDIR)/System.map "$(INSTALL_PATH)" + sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)" zinstall: $(CONFIGURE) zImage - sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" + sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" clean: $(RM) Image zImage bootpImage diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile index c513c8ad3..918e3eb9e 100644 --- a/arch/arm/boot/bootp/Makefile +++ b/arch/arm/boot/bootp/Makefile @@ -23,4 +23,4 @@ initrd.o: $(INITRD) .PHONY: $(INITRD) $(ZSYSTEM) -clean:; $(RM) bootp bootp.lds +clean:; $(RM) bootp diff --git a/arch/arm/boot/bootp/bootp.lds b/arch/arm/boot/bootp/bootp.lds new file mode 100644 index 000000000..8c4e6895f --- /dev/null +++ b/arch/arm/boot/bootp/bootp.lds @@ -0,0 +1,39 @@ +/* + * linux/arch/arm/boot/bootp/bootp.lds + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0; + _text = .; + .text : { + _stext = .; + _start = .; + init.o(.start) + kernel_start = .; + kernel.o + kernel_len = . - kernel_start; + . = ALIGN(32); + *(.text) + initrd_start = .; + initrd.o + initrd_len = . - initrd_start; + . = ALIGN(32); + _etext = .; + } + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S index c5682212f..2b498b7bb 100644 --- a/arch/arm/boot/bootp/init.S +++ b/arch/arm/boot/bootp/init.S @@ -1,6 +1,14 @@ /* - * Header file for splitting kernel + initrd. Note that we pass - * r0 through to r3 straight through. + * linux/arch/arm/boot/bootp/init.S + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Header file for splitting kernel + initrd. Note that we pass + * r0 through to r3 straight through. */ .section .start,#alloc,#execinstr .type _entry, #function diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 2a0108021..46b754ec5 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -24,6 +24,10 @@ ifeq ($(CONFIG_ARCH_NETWINDER),y) OBJS += head-netwinder.o endif +ifeq ($(CONFIG_ARCH_INTEGRATOR),y) +OBJS += head-netwinder.o +endif + ifeq ($(CONFIG_ARCH_NEXUSPCI),y) HEAD = head-nexuspci.o endif diff --git a/arch/arm/boot/compressed/head-ftvpci.S b/arch/arm/boot/compressed/head-ftvpci.S new file mode 100644 index 000000000..a8c806ef3 --- /dev/null +++ b/arch/arm/boot/compressed/head-ftvpci.S @@ -0,0 +1,40 @@ +/* + * linux/arch/arm/boot/compressed/head-ftvpci.S + * + * Copyright (C) 2000 FutureTV Labs Ltd. + * + * Special startup code for FTV PCI board. + */ + + .section ".start", #alloc, #execinstr +ftv_start: + mcr p15, 0, r0, c7, c5, 0 @ flush I cache + mrc p15, 0, r0, c1, c0 + orr r0, r0, #1 << 12 + mcr p15, 0, r0, c1, c0 @ enable I cache + mov r0, #0 + mcreq p15, 0, r0, c15, c1, 2 @ enable clock switching + + /* check to see if the kernel must be relocated */ + ldr ip, =ftv_start + adr sl, ftv_start + teq ip, sl + beq 2f @ no need to copy + + /* in the wrong place -> presumably, executing out of ROM */ + sub ip, ip, sl @ displacement + ldr lr, =_start @ destination + sub sp, lr, ip @ source + ldr fp, =_edata @ end of copied area +1: ldmia sp!, {r0, r1, r2, r3, r4, r5, r6, r10} + stmia lr!, {r0, r1, r2, r3, r4, r5, r6, r10} + cmp lr, fp + ble 1b + +2: + mov r8, #0 + mov r7, #3 + b 1f +.ltorg +1: + /* fall back into head.S */ diff --git a/arch/arm/boot/compressed/head-netwinder.S b/arch/arm/boot/compressed/head-netwinder.S index eca1d773d..5eecdec42 100644 --- a/arch/arm/boot/compressed/head-netwinder.S +++ b/arch/arm/boot/compressed/head-netwinder.S @@ -1,3 +1,12 @@ +/* + * linux/arch/arm/boot/compressed/head-netwinder.S + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ #define K(a,b,c) ((a) << 24 | (b) << 12 | (c)) .section ".start", #alloc, #execinstr diff --git a/arch/arm/boot/compressed/head-nexuspci.S b/arch/arm/boot/compressed/head-nexuspci.S deleted file mode 100644 index 1fd49a95c..000000000 --- a/arch/arm/boot/compressed/head-nexuspci.S +++ /dev/null @@ -1,101 +0,0 @@ -/* - * linux/arch/arm/boot/compressed/head-nexuspci.S - * - * Copyright (C) 1996, 1997, 1998 Philip Blundell - * - * NexusPCI is unusual because we don't have a bootloader -- the kernel is - * run directly out of ROM at the moment. Maybe this will change one day and - * then this file can go away. - * - */ - - .text - -.globl _start -_start: b reset - b undefined - b undefined - b undefined - b undefined - b undefined - b undefined - b undefined - b go_uncompress - -reset: mov r2, #0x20000000 @ LED off - mov r1, #0x1a - str r1, [r2] - - mov r2, #0x10000000 @ SCC init - - mov r1, #42 - strb r1, [r2, #8] - - mov r1, #48 - strb r1, [r2, #8] - - mov r1, #16 - strb r1, [r2, #8] - - mov r1, #0x93 - strb r1, [r2, #0] - mov r1, #0x17 - strb r1, [r2, #0] - - mov r1, #0xbb - strb r1, [r2, #0x4] - - mov r1, #0x78 - strb r1, [r2, #0x10] - - mov r1, #160 - strb r1, [r2, #0x8] - - mov r1, #5 - strb r1, [r2, #0x8] - - ldr r2, =_start - ldr r3, =_edata - mov r8, r2 - mov r0, #0 -1: - ldmia r0!, {r4, r5, r6, r7} - stmia r2!, {r4, r5, r6, r7} - cmp r2, r3 - ble 1b - - ldr r3, =_edata - ldr r1, =_end - mov r2, #0 -1: - strb r2, [r3] - cmp r3, r1 - beq 2f - add r3, r3, #1 - b 1b -2: - add pc, r8, #0x20 - -undefined: ldr r4, =undef_msg -1: ldrb r0, [r4], #1 - movs r0, r0 -2: beq 2b - bl _ll_write_char - b 1b - -undef_msg: .ascii "Undefined instruction (or other problem)\000" - .align 4 - -/* - * Uncompress the kernel - */ -go_uncompress: - mov r0, #0x40000000 - ldr sp, =user_stack - add sp, sp, #4096 - bl decompress_kernel - - mov r2, #0x40000000 - mov r0, #0 - mov r1, #3 - add pc, r2, #0x20 @ call via EXEC entry diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index ef9090f72..21bdb43c0 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -1,7 +1,11 @@ /* - * linux/arch/arm/boot/compressed/head.S + * linux/arch/arm/boot/compressed/head.S * - * Copyright (C) 1996-1999 Russell King + * Copyright (C) 1996-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> #include <linux/linkage.h> @@ -85,7 +89,7 @@ start: .word 0x016f2818 @ Magic numbers to help the loader .word start 1: mov r7, r1 @ save architecture ID - mov r8, r0 @ save r0 + mov r8, #0 @ save r0 #ifdef CONFIG_ANGELBOOT /* * Booting from Angel - need to enter SVC mode and disable @@ -198,9 +202,10 @@ cache_on: ldr r1, proc_sa110_type 1: sub r3, r4, #16384 @ Page directory size bic r3, r3, #0xff @ Align the pointer - bic r3, r3, #0x3f + bic r3, r3, #0x3f00 /* - * Initialise the page tables + * Initialise the page tables, turning on the cacheable and bufferable + * bits for the RAM area only. */ mov r0, r3 mov r8, r0, lsr #18 @@ -217,6 +222,20 @@ cache_on: ldr r1, proc_sa110_type add r1, r1, #1048576 teq r0, r2 bne 1b +/* + * If ever we are running from Flash, then we surely want the cache + * to be enabled also for our execution instance... We map 2MB of it + * so there is no map overlap problem for up to 1 MB compressed kernel. + * If the execution is in RAM then we would only be duplicating the above. + */ + mov r1, #0x1e + orr r1, r1, #3 << 10 + mov r2, pc, lsr #20 + orr r1, r1, r2, lsl #20 + add r0, r3, r2, lsl #2 + str r1, [r0], #4 + add r1, r1, #1048576 + str r1, [r0] mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer diff --git a/arch/arm/boot/compressed/ll_char_wr.S b/arch/arm/boot/compressed/ll_char_wr.S index 57865f2fd..8e1c8bc34 100644 --- a/arch/arm/boot/compressed/ll_char_wr.S +++ b/arch/arm/boot/compressed/ll_char_wr.S @@ -1,12 +1,16 @@ /* - * linux/arch/arm/lib/ll_char_wr.S + * linux/arch/arm/lib/ll_char_wr.S * - * Copyright (C) 1995, 1996 Russell King. + * Copyright (C) 1995, 1996 Russell King. * - * Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * - * 10-04-96 RMK Various cleanups & reduced register usage. - * 08-04-98 RMK Shifts re-ordered + * Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King. + * + * 10-04-96 RMK Various cleanups & reduced register usage. + * 08-04-98 RMK Shifts re-ordered */ @ Regs: [] = corruptible diff --git a/arch/arm/boot/compressed/setup-sa1100.S b/arch/arm/boot/compressed/setup-sa1100.S index f7657773b..3babde180 100644 --- a/arch/arm/boot/compressed/setup-sa1100.S +++ b/arch/arm/boot/compressed/setup-sa1100.S @@ -138,7 +138,7 @@ skip_uart: @ The machine type is passed in r0 mov r0, r3 #ifdef CONFIG_SA1100_NANOENGINE - teq r0, #32 @ MACH_TYPE_NANOENGINE + teq r0, #MACH_TYPE_NANOENGINE beq SYMBOL_NAME(bse_setup) #endif diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index f7469c634..86ed5e6e3 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in @@ -1,3 +1,12 @@ +/* + * linux/arch/arm/boot/compressed/vmlinux.lds.in + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS diff --git a/arch/arm/config.in b/arch/arm/config.in index c45998677..1a79b55b9 100644 --- a/arch/arm/config.in +++ b/arch/arm/config.in @@ -15,6 +15,7 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL bool 'Prompt for obsolete code/drivers' CONFIG_OBSOLETE endmenu + mainmenu_option next_comment comment 'Loadable module support' bool 'Enable loadable module support' CONFIG_MODULES @@ -24,6 +25,7 @@ if [ "$CONFIG_MODULES" = "y" ]; then fi endmenu + mainmenu_option next_comment comment 'System Type' @@ -33,49 +35,60 @@ choice 'ARM system type' \ Co-EBSA285 CONFIG_ARCH_CO285 \ EBSA-110 CONFIG_ARCH_EBSA110 \ FootBridge CONFIG_ARCH_FOOTBRIDGE \ + Integrator CONFIG_ARCH_INTEGRATOR \ RiscPC CONFIG_ARCH_RPC \ SA1100-based CONFIG_ARCH_SA1100" RiscPC # the following are placeholders for when they are fully integrated -# Cirrus CL-PS7500FE CONFIG_ARCH_CLPS7500 \ # LinkUp-L7200 CONFIG_ARCH_L7200 +mainmenu_option next_comment +comment 'Archimedes/A5000 Implementations' if [ "$CONFIG_ARCH_ARCA5K" = "y" ]; then # These architectures will be combined. However, until this # is complete... Note that the ARC will take precidence over # A5K comment 'Archimedes/A5000 Implementations (select only ONE)' - bool ' Archimedes support' CONFIG_ARCH_ARC - bool ' A5000 support' CONFIG_ARCH_A5K + + bool ' Archimedes' CONFIG_ARCH_ARC + bool ' A5000' CONFIG_ARCH_A5K fi +endmenu + +mainmenu_option next_comment +comment 'Footbridge Implementations' if [ "$CONFIG_ARCH_FOOTBRIDGE" = "y" ]; then - comment 'Footbridge Implementations' - bool ' CATS support' CONFIG_ARCH_CATS - bool ' Compaq Personal Server support' CONFIG_ARCH_PERSONAL_SERVER - bool ' EBSA285 (addin mode) support' CONFIG_ARCH_EBSA285_ADDIN - bool ' EBSA285 (host mode) support' CONFIG_ARCH_EBSA285_HOST - bool ' NetWinder support' CONFIG_ARCH_NETWINDER + bool ' CATS' CONFIG_ARCH_CATS + bool ' Compaq Personal Server' CONFIG_ARCH_PERSONAL_SERVER + bool ' EBSA285 (addin mode)' CONFIG_ARCH_EBSA285_ADDIN + bool ' EBSA285 (host mode)' CONFIG_ARCH_EBSA285_HOST + bool ' NetWinder' CONFIG_ARCH_NETWINDER fi +endmenu + +mainmenu_option next_comment +comment 'SA11x0 Implementations' if [ "$CONFIG_ARCH_SA1100" = "y" ]; then - comment 'SA11x0 Implementations' - bool ' Include support for Assabet' CONFIG_SA1100_ASSABET + + bool ' Assabet' CONFIG_SA1100_ASSABET if [ "$CONFIG_SA1100_ASSABET" = "y" ]; then - bool ' Include support for Neponset' CONFIG_ASSABET_NEPONSET + bool ' Include support for Neponset' CONFIG_ASSABET_NEPONSET fi - bool ' Include support for Brutus' CONFIG_SA1100_BRUTUS - bool ' Include support for CerfBoard' CONFIG_SA1100_CERF - bool ' Include support for Compaq iPAQ H3600 (Bitsy)' CONFIG_SA1100_BITSY -# bool ' Include support for Empeg' CONFIG_SA1100_EMPEG -# bool ' Include support for Itsy' CONFIG_SA1100_ITSY - bool ' Include support for LART' CONFIG_SA1100_LART -# bool ' Include support for PLEB' CONFIG_SA1100_PLEB - bool ' Include support for ThinClient' CONFIG_SA1100_THINCLIENT - bool ' Include support for GraphicsClient' CONFIG_SA1100_GRAPHICSCLIENT - bool ' Include support for nanoEngine' CONFIG_SA1100_NANOENGINE - bool ' Include support for Victor' CONFIG_SA1100_VICTOR -# bool ' Include support for Tifon' CONFIG_SA1100_TIFON - bool ' Include support for XP860' CONFIG_SA1100_XP860 - + bool ' Brutus' CONFIG_SA1100_BRUTUS + bool ' CerfBoard' CONFIG_SA1100_CERF + bool ' Compaq iPAQ H3600 (Bitsy)' CONFIG_SA1100_BITSY +# bool ' Empeg' CONFIG_SA1100_EMPEG +# bool ' Itsy' CONFIG_SA1100_ITSY + bool ' LART' CONFIG_SA1100_LART +# bool ' PLEB' CONFIG_SA1100_PLEB + bool ' ThinClient' CONFIG_SA1100_THINCLIENT + bool ' GraphicsClient' CONFIG_SA1100_GRAPHICSCLIENT + bool ' nanoEngine' CONFIG_SA1100_NANOENGINE + bool ' Victor' CONFIG_SA1100_VICTOR +# bool ' Tifon' CONFIG_SA1100_TIFON + bool ' XP860' CONFIG_SA1100_XP860 + + # Someday, we'll support this as a general option. bool ' Load kernel using Angel Debug Monitor' CONFIG_ANGELBOOT # Determine if SA1111 support is required @@ -84,6 +97,7 @@ if [ "$CONFIG_ARCH_SA1100" = "y" ]; then define_bool CONFIG_SA1111 y fi fi +endmenu # Definitions to make life easier if [ "$CONFIG_ARCH_ARCA5K" = "y" -o \ @@ -129,12 +143,14 @@ else define_bool CONFIG_CPU_26 n fi +comment 'Processor Type' + # Select CPU and optimisation dependent on architecture if [ "$CONFIG_ARCH_RPC" = "y" ]; then define_bool CONFIG_CPU_32v3 y - bool 'Support ARM610' CONFIG_CPU_ARM6 - bool 'Support ARM710' CONFIG_CPU_ARM7 - bool 'Support StrongARM110' CONFIG_CPU_SA110 + bool 'Support ARM610 processor' CONFIG_CPU_ARM6 + bool 'Support ARM710 processor' CONFIG_CPU_ARM7 + bool 'Support StrongARM(R) SA-110 processor' CONFIG_CPU_SA110 fi if [ "$CONFIG_ARCH_EBSA110" = "y" -o \ "$CONFIG_FOOTBRIDGE" = "y" -o \ @@ -152,11 +168,33 @@ if [ "$CONFIG_ARCH_L7200" = "y" ]; then define_bool CONFIG_CPU_32v4 y define_bool CONFIG_CPU_ARM720 y fi +if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then + define_bool CONFIG_CPU_32v4 y + bool 'Support ARM720 processor' CONFIG_CPU_ARM720 + bool 'Support ARM920 processor' CONFIG_CPU_ARM920 +# bool 'Support ARM10 processor' CONFIG_CPU_ARM10 +fi if [ "$CONFIG_ARCH_SA1100" = "y" ]; then define_bool CONFIG_CPU_32v4 y define_bool CONFIG_CPU_SA1100 y fi +if [ "$CONFIG_CPU_ARM920" = "y" ]; then + bool ' ARM920 CPU idle' CONFIG_CPU_ARM920_CPU_IDLE + bool ' ARM920 I-Cache on' CONFIG_CPU_ARM920_I_CACHE_ON + bool ' ARM920 D-Cache on' CONFIG_CPU_ARM920_D_CACHE_ON + if [ "$CONFIG_CPU_ARM920_D_CACHE_ON" = "y" ] ; then + bool ' Force write through caches on ARM920' CONFIG_CPU_ARM920_WRITETHROUGH + fi +fi +#if [ "$CONFIG_CPU_ARM10" = "y" ]; then +# bool ' ARM10 I-Cache on' CONFIG_CPU_ARM10_I_CACHE_ON +# bool ' ARM10 D-Cache on' CONFIG_CPU_ARM10_D_CACHE_ON +# if [ "$CONFIG_CPU_ARM10_D_CACHE_ON" = "y" ] ; then +# bool ' Force write through caches on ARM10' CONFIG_CPU_ARM10_FORCE_WRITE_THROUGH +# fi +#fi + # Select various configuration options depending on the machine type if [ "$CONFIG_ARCH_SA1100" = "y" ]; then define_bool CONFIG_DISCONTIGMEM y @@ -164,12 +202,21 @@ else define_bool CONFIG_DISCONTIGMEM n fi +endmenu + +mainmenu_option next_comment +comment 'General setup' + # Now handle the bus types if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \ "$CONFIG_FOOTBRIDGE_HOST" = "y" ]; then define_bool CONFIG_PCI y else - define_bool CONFIG_PCI n + if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then + bool 'PCI support' CONFIG_PCI + else + define_bool CONFIG_PCI n + fi fi if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \ @@ -189,10 +236,7 @@ fi if [ "$CONFIG_SA1100_ASSABET" = "y" ]; then define_bool CONFIG_PC_KEYMAP y fi -endmenu -mainmenu_option next_comment -comment 'General setup' source drivers/pci/Config.in bool 'Support hot-pluggable devices' CONFIG_HOTPLUG if [ "$CONFIG_HOTPLUG" = "y" ]; then @@ -223,20 +267,23 @@ if [ "$CONFIG_ARCH_EBSA110" = "y" -o \ "$CONFIG_ARCH_SA1100" = "y" -o \ "$CONFIG_ARCH_CLPS7500" = "y" -o \ "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \ - "$CONFIG_ARCH_CATS" = "y" ]; then + "$CONFIG_ARCH_CATS" = "y" -o \ + "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then string 'Default kernel command string' CONFIG_CMDLINE "" fi if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \ "$CONFIG_ARCH_EBSA110" = "y" -o \ "$CONFIG_ARCH_EBSA285" = "y" -o \ "$CONFIG_ARCH_CO285" = "y" -o \ - "$CONFIG_ARCH_SA1100" = "y" ]; then + "$CONFIG_ARCH_SA1100" = "y" -o \ + "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then bool 'Timer and CPU usage LEDs' CONFIG_LEDS if [ "$CONFIG_LEDS" = "y" ]; then if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \ "$CONFIG_ARCH_EBSA285" = "y" -o \ "$CONFIG_ARCH_CO285" = "y" -o \ - "$CONFIG_ARCH_SA1100" = "y" ]; then + "$CONFIG_ARCH_SA1100" = "y" -o \ + "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then bool ' Timer LED' CONFIG_LEDS_TIMER bool ' CPU usage LED' CONFIG_LEDS_CPU fi @@ -254,6 +301,7 @@ source drivers/parport/Config.in source drivers/mtd/Config.in source drivers/pnp/Config.in source drivers/block/Config.in +source drivers/md/Config.in if [ "$CONFIG_ARCH_ACORN" = "y" ]; then source drivers/acorn/block/Config.in @@ -322,10 +370,6 @@ if [ "$CONFIG_ARCH_ACORN" = "y" -a \ fi fi -#source drivers/misc/Config.in - -source drivers/media/Config.in - source fs/Config.in if [ "$CONFIG_VT" = "y" ]; then @@ -354,7 +398,6 @@ if [ "$CONFIG_ARCH_ACORN" = "y" -o \ fi source drivers/usb/Config.in -source drivers/input/Config.in mainmenu_option next_comment diff --git a/arch/arm/def-configs/assabet b/arch/arm/def-configs/assabet index 4f046fae2..7a4cd1778 100644 --- a/arch/arm/def-configs/assabet +++ b/arch/arm/def-configs/assabet @@ -2,20 +2,23 @@ # Automatically generated make config: don't edit # CONFIG_ARM=y +# CONFIG_SBUS is not set CONFIG_UID16=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set # -# System and Processor Type +# System Type # # CONFIG_ARCH_ARC is not set # CONFIG_ARCH_A5K is not set +# CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_FOOTBRIDGE is not set +# CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_RPC is not set CONFIG_ARCH_SA1100=y @@ -24,25 +27,27 @@ CONFIG_ARCH_SA1100=y # CONFIG_SA1100_ASSABET=y # CONFIG_ASSABET_NEPONSET is not set -# CONFIG_SA1100_BITSY is not set # CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_BITSY is not set # CONFIG_SA1100_LART is not set # CONFIG_SA1100_THINCLIENT is not set # CONFIG_SA1100_GRAPHICSCLIENT is not set # CONFIG_SA1100_VICTOR is not set -CONFIG_DISCONTIGMEM=y -CONFIG_SA1100_FREQUENCY_SCALE=y +CONFIG_ANGELBOOT=y +# CONFIG_SA1100_FREQUENCY_SCALE is not set # CONFIG_SA1100_VOLTAGE_SCALE is not set -# CONFIG_ARCH_ACORN is not set CONFIG_CPU_32=y # CONFIG_CPU_26 is not set CONFIG_CPU_32v4=y CONFIG_CPU_SA1100=y +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_DISCONTIGMEM=y # CONFIG_PCI is not set # CONFIG_ISA is not set # CONFIG_ISA_DMA is not set -# CONFIG_SBUS is not set -CONFIG_ALIGNMENT_TRAP=y # # Loadable module support @@ -54,6 +59,15 @@ CONFIG_MODULES=y # # General setup # +CONFIG_HOTPLUG=y + +# +# PC Card support +# +CONFIG_PCMCIA=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_SA1100_PCMCIA=y +CONFIG_VIRTUAL_BUS=y CONFIG_NET=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -64,34 +78,23 @@ CONFIG_KCORE_ELF=y # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set # CONFIG_ARTHUR is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set -CONFIG_CMDLINE="" +CONFIG_CMDLINE="keepinitrd" CONFIG_LEDS=y CONFIG_LEDS_TIMER=y CONFIG_LEDS_CPU=y -CONFIG_HOTPLUG=y +CONFIG_ALIGNMENT_TRAP=y # -# PC Card support +# Parallel port support # -CONFIG_PCMCIA=y -# CONFIG_PCMCIA_DEBUG is not set -CONFIG_SA1100_PCMCIA=y -CONFIG_VIRTUAL_BUS=y +# CONFIG_PARPORT is not set # -# I2O device support +# Memory Technology Devices (MTD) # -# CONFIG_I2O is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set +# CONFIG_MTD is not set # # Plug and Play configuration @@ -113,92 +116,14 @@ CONFIG_VIRTUAL_BUS=y # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set -# CONFIG_RAID15_DANGEROUS is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y # CONFIG_BLK_DEV_FLASH is not set # -# Character devices -# -CONFIG_VT=y -# CONFIG_VT_CONSOLE is not set -CONFIG_SERIAL_SA1100=y -CONFIG_SERIAL_SA1100_CONSOLE=y -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=32 - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set - -# -# Joysticks -# -# CONFIG_JOYSTICK is not set -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set -# CONFIG_PCMCIA_SERIAL is not set -# CONFIG_AGP is not set - -# -# Console drivers -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_FB=y - -# -# Frame-buffer support -# -CONFIG_FB=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_FB_SA1100=y -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FBCON_ADVANCED is not set -CONFIG_FBCON_CFB2=y -CONFIG_FBCON_CFB4=y -CONFIG_FBCON_CFB8=y -CONFIG_FBCON_CFB16=y -CONFIG_FBCON_FONTWIDTH8_ONLY=y -CONFIG_FBCON_FONTS=y -CONFIG_FONT_8x8=y -# CONFIG_FONT_8x16 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set - -# # Networking options # # CONFIG_PACKET is not set @@ -230,9 +155,9 @@ CONFIG_SKB_LARGE=y # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -245,16 +170,6 @@ CONFIG_SKB_LARGE=y # CONFIG_NET_SCHED is not set # -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# # Network device support # CONFIG_NETDEVICES=y @@ -329,6 +244,16 @@ CONFIG_PCMCIA_PCNET=y CONFIG_PCMCIA_NETCARD=y # +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# # ATA/IDE/MFM/RLL support # CONFIG_IDE=y @@ -368,6 +293,7 @@ CONFIG_BLK_DEV_IDECS=y # CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set # CONFIG_BLK_DEV_IDE_MODES is not set # @@ -376,22 +302,75 @@ CONFIG_BLK_DEV_IDECS=y # CONFIG_SCSI is not set # -# Sound +# I2O device support # -CONFIG_SOUND=y -CONFIG_SOUND_UDA1341=y -# CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -# CONFIG_SOUND_OSS is not set +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +# CONFIG_TOUCHSCREEN_SA1100 is not set +# CONFIG_TOUCHSCREEN_BITSY is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_DRM is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_PCMCIA_SERIAL is not set +# CONFIG_AGP is not set # # File systems @@ -409,6 +388,7 @@ CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set @@ -507,6 +487,51 @@ CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_KOI8_R is not set # +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_FB=y + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FB_SA1100=y +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB2=y +CONFIG_FBCON_CFB4=y +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_FONTWIDTH8_ONLY=y +CONFIG_FBCON_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set + +# +# Sound +# +CONFIG_SOUND=y +CONFIG_SOUND_UDA1341=y +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# # USB support # # CONFIG_USB is not set @@ -517,6 +542,6 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_FRAME_POINTER=y CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_USER=y -CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/def-configs/brutus b/arch/arm/def-configs/brutus index 67c4eeafb..34391812a 100644 --- a/arch/arm/def-configs/brutus +++ b/arch/arm/def-configs/brutus @@ -2,45 +2,51 @@ # Automatically generated make config: don't edit # CONFIG_ARM=y +# CONFIG_SBUS is not set CONFIG_UID16=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set # -# System and processor type +# System Type # # CONFIG_ARCH_ARC is not set # CONFIG_ARCH_A5K is not set -# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_FOOTBRIDGE is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_RPC is not set CONFIG_ARCH_SA1100=y + +# +# SA11x0 Implementations +# # CONFIG_SA1100_ASSABET is not set CONFIG_SA1100_BRUTUS=y -# CONFIG_SA1100_EMPEG is not set -# CONFIG_SA1100_ITSY is not set # CONFIG_SA1100_BITSY is not set # CONFIG_SA1100_LART is not set -# CONFIG_SA1100_PLEB is not set # CONFIG_SA1100_THINCLIENT is not set # CONFIG_SA1100_GRAPHICSCLIENT is not set # CONFIG_SA1100_VICTOR is not set -# CONFIG_SA1100_TIFON is not set -CONFIG_DISCONTIGMEM=y -# CONFIG_ARCH_ACORN is not set +CONFIG_ANGELBOOT=y +# CONFIG_SA1100_FREQUENCY_SCALE is not set +# CONFIG_SA1100_VOLTAGE_SCALE is not set CONFIG_CPU_32=y # CONFIG_CPU_26 is not set CONFIG_CPU_32v4=y CONFIG_CPU_SA1100=y +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_DISCONTIGMEM=y # CONFIG_PCI is not set # CONFIG_ISA is not set # CONFIG_ISA_DMA is not set -# CONFIG_SBUS is not set -# CONFIG_PCMCIA is not set -# CONFIG_ALIGNMENT_TRAP is not set # # Loadable module support @@ -52,34 +58,35 @@ CONFIG_MODULES=y # # General setup # +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set # CONFIG_NET is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y CONFIG_NWFPE=y CONFIG_KCORE_ELF=y # CONFIG_KCORE_AOUT is not set CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set # CONFIG_ARTHUR is not set +CONFIG_CMDLINE="keepinitrd" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +# CONFIG_ALIGNMENT_TRAP is not set # # Parallel port support # # CONFIG_PARPORT is not set -CONFIG_CMDLINE="" -CONFIG_LEDS=y -CONFIG_LEDS_TIMER=y -CONFIG_LEDS_CPU=y # -# I2O device support +# Memory Technology Devices (MTD) # -# CONFIG_I2O is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set +# CONFIG_MTD is not set # # Plug and Play configuration @@ -100,18 +107,48 @@ CONFIG_LEDS_CPU=y # CONFIG_BLK_DEV_LVM is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set -# CONFIG_MD_STRIPED is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y # CONFIG_BLK_DEV_FLASH is not set # +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# # Character devices # CONFIG_VT=y # CONFIG_VT_CONSOLE is not set CONFIG_SERIAL_SA1100=y CONFIG_SERIAL_SA1100_CONSOLE=y +# CONFIG_TOUCHSCREEN_SA1100 is not set +# CONFIG_TOUCHSCREEN_BITSY is not set # CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -139,6 +176,7 @@ CONFIG_UNIX98_PTY_COUNT=32 # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -159,43 +197,6 @@ CONFIG_UNIX98_PTY_COUNT=32 # CONFIG_AGP is not set # -# Console drivers -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_FB=y - -# -# Frame-buffer support -# -CONFIG_FB=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_FB_SA1100=y -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FBCON_ADVANCED is not set -CONFIG_FBCON_CFB2=y -CONFIG_FBCON_CFB4=y -CONFIG_FBCON_CFB8=y -CONFIG_FBCON_FONTWIDTH8_ONLY=y -CONFIG_FBCON_FONTS=y -CONFIG_FONT_8x8=y -# CONFIG_FONT_8x16 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# # File systems # # CONFIG_QUOTA is not set @@ -211,6 +212,7 @@ CONFIG_FONT_8x8=y # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set @@ -244,6 +246,37 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_FB=y + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FB_SA1100=y +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB2=y +CONFIG_FBCON_CFB4=y +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_FONTWIDTH8_ONLY=y +CONFIG_FBCON_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# # USB support # # CONFIG_USB is not set diff --git a/arch/arm/def-configs/cerf b/arch/arm/def-configs/cerf new file mode 100644 index 000000000..accb50b3f --- /dev/null +++ b/arch/arm/def-configs/cerf @@ -0,0 +1,423 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_SBUS is not set +CONFIG_UID16=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_BRUTUS is not set +CONFIG_SA1100_CERF=y +# CONFIG_SA1100_BITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_THINCLIENT is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_ANGELBOOT is not set +# CONFIG_SA1100_FREQUENCY_SCALE is not set +# CONFIG_SA1100_VOLTAGE_SCALE is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +CONFIG_CPU_32v4=y +CONFIG_CPU_SA1100=y +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_DISCONTIGMEM=y +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set + +# +# General setup +# +CONFIG_HOTPLUG=y + +# +# PC Card support +# +CONFIG_PCMCIA=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_SA1100_PCMCIA=y +CONFIG_VIRTUAL_BUS=y +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_NWFPE=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="keepinitrd" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_FLASH=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_CERF_CS8900A=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI 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 +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +CONFIG_BLK_DEV_IDECS=y +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +# CONFIG_TOUCHSCREEN_UCB1200 is not set +# CONFIG_TOUCHSCREEN_BITSY is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_DRM is not set +# CONFIG_PCMCIA_SERIAL is not set +# CONFIG_AGP is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFSD is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_NLS is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_OSS is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_LL is not set diff --git a/arch/arm/def-configs/clps7500 b/arch/arm/def-configs/clps7500 new file mode 100644 index 000000000..fb1864561 --- /dev/null +++ b/arch/arm/def-configs/clps7500 @@ -0,0 +1,490 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_SBUS is not set +CONFIG_UID16=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_OBSOLETE=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_ARCA5K is not set +CONFIG_ARCH_CLPS7500=y +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FTVPCI is not set +# CONFIG_ARCH_TBOX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +CONFIG_CPU_32v3=y +CONFIG_CPU_ARM7=y +# CONFIG_DISCONTIGMEM is not set +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set + +# +# General setup +# +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_SYSCTL is not set +CONFIG_NWFPE=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="root=/dev/nfs rw" +# CONFIG_ALIGNMENT_TRAP is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_MTDRAM is not set + +# +# MTD drivers for mapped chips +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_JEDEC is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_PHYSMAP is not set + +# +# Drivers for chip mappings +# +# CONFIG_MTD_MIXMEM is not set +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_OCTAGON is not set +# CONFIG_MTD_PNC2000 is not set +# CONFIG_MTD_RPXLITE is not set +# CONFIG_MTD_VMAX is not set + +# +# User modules and translation layers for MTD devices +# +# CONFIG_MTD_CHAR is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_BLK_DEV_FLD7500=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI 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 +# CONFIG_PLIP is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +CONFIG_SLIP=y +CONFIG_SLIP_COMPRESSED=y +# CONFIG_SLIP_SMART is not set +# CONFIG_SLIP_MODE_SLIP6 is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_ASH is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +# CONFIG_SERIAL_CONSOLE is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 +CONFIG_PRINTER=y +CONFIG_LP_CONSOLE=y +# CONFIG_PPDEV is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_PHILIPSPAR is not set +# CONFIG_I2C_ELV is not set +# CONFIG_I2C_VELLEMAN is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_CHARDEV is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_CLPS7500_FLASH=y +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +CONFIG_MINIX_FS=y +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_NLS is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_FB=y + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FB_ACORN=y +# CONFIG_CHRONTEL_7003 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +CONFIG_FBCON_CFB8=y +# CONFIG_FBCON_CFB16 is not set +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_FRAME_POINTER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_LL is not set diff --git a/arch/arm/def-configs/lart b/arch/arm/def-configs/lart index 2e1cd07b5..4dd0b2eeb 100644 --- a/arch/arm/def-configs/lart +++ b/arch/arm/def-configs/lart @@ -2,53 +2,62 @@ # Automatically generated by make menuconfig: don't edit # CONFIG_ARM=y +# CONFIG_SBUS is not set CONFIG_UID16=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set # -# System and Processor Type +# Loadable module support # -# CONFIG_ARCH_ARC is not set -# CONFIG_ARCH_A5K is not set +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_FOOTBRIDGE is not set +# CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_RPC is not set CONFIG_ARCH_SA1100=y # CONFIG_SA1100_ASSABET is not set -# CONFIG_SA1100_BITSY is not set # CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_BITSY is not set CONFIG_SA1100_LART=y # CONFIG_SA1100_THINCLIENT is not set # CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_NANOENGINE is not set # CONFIG_SA1100_VICTOR is not set -CONFIG_DISCONTIGMEM=y +# CONFIG_ANGELBOOT is not set CONFIG_SA1100_FREQUENCY_SCALE=m CONFIG_SA1100_VOLTAGE_SCALE=y # CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set CONFIG_CPU_32=y # CONFIG_CPU_26 is not set CONFIG_CPU_32v4=y CONFIG_CPU_SA1100=y +CONFIG_DISCONTIGMEM=y # CONFIG_PCI is not set # CONFIG_ISA is not set # CONFIG_ISA_DMA is not set -# CONFIG_SBUS is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -# CONFIG_KMOD is not set # # General setup # +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set CONFIG_NET=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -59,26 +68,23 @@ CONFIG_KCORE_ELF=y CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +CONFIG_PM=y # CONFIG_ARTHUR is not set +CONFIG_CMDLINE="console=ttyS0,9600" +CONFIG_LEDS=y +# CONFIG_LEDS_TIMER is not set +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y # # Parallel port support # # CONFIG_PARPORT is not set -CONFIG_CMDLINE="console=ttyS0,9600" -CONFIG_LEDS=y -# CONFIG_LEDS_TIMER is not set -CONFIG_LEDS_CPU=y -# CONFIG_HOTPLUG is not set # -# I2O device support +# Memory Technology Devices (MTD) # -# CONFIG_I2O is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set +# CONFIG_MTD is not set # # Plug and Play configuration @@ -100,66 +106,18 @@ CONFIG_LEDS_CPU=y # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set -# CONFIG_RAID15_DANGEROUS is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y -# CONFIG_BLK_DEV_FLASH is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_SERIAL_SA1100=y -CONFIG_SERIAL_SA1100_CONSOLE=y -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_UNIX98_PTYS is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set - -# -# Joysticks -# -# CONFIG_JOYSTICK is not set -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set -# CONFIG_AGP is not set +CONFIG_BLK_DEV_FLASH=m # # Networking options # -# CONFIG_PACKET is not set +CONFIG_PACKET=m +# CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set @@ -172,17 +130,17 @@ CONFIG_INET=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set -# CONFIG_SKB_LARGE is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -195,16 +153,6 @@ CONFIG_INET=y # CONFIG_NET_SCHED is not set # -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# # Network device support # CONFIG_NETDEVICES=y @@ -221,7 +169,37 @@ CONFIG_NETDEVICES=y # # Ethernet (10 or 100Mbit) # -# CONFIG_NET_ETHERNET is not set +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +CONFIG_CS89x0=m +# CONFIG_DE4X5 is not set +# CONFIG_TULIP is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_LNE390 is not set +# CONFIG_NE3210 is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_RTL8129 is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_ES3210 is not set +# CONFIG_EPIC100 is not set +# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) @@ -262,11 +240,49 @@ CONFIG_SLIP_COMPRESSED=y # CONFIG_WAN is not set # +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# # ATA/IDE/MFM/RLL support # -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_IDE=m + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=m +# CONFIG_BLK_DEV_HD_IDE is not set # CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support @@ -274,54 +290,71 @@ CONFIG_SLIP_COMPRESSED=y # CONFIG_SCSI is not set # -# Sound +# I2O device support # -CONFIG_SOUND=m -# CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -CONFIG_SOUND_OSS=m -CONFIG_SOUND_TRACEINIT=y -# CONFIG_SOUND_DMAP is not set -# CONFIG_SOUND_AD1816 is not set -# CONFIG_SOUND_SGALAXY is not set -# CONFIG_SOUND_ADLIB is not set -# CONFIG_SOUND_ACI_MIXER is not set -# CONFIG_SOUND_CS4232 is not set -# CONFIG_SOUND_SSCAPE is not set -# CONFIG_SOUND_GUS is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_VMIDI is not set -# CONFIG_SOUND_TRIX is not set -# CONFIG_SOUND_MSS is not set -# CONFIG_SOUND_MPU401 is not set -# CONFIG_SOUND_NM256 is not set -# CONFIG_SOUND_MAD16 is not set -# CONFIG_SOUND_PAS is not set -# CONFIG_PAS_JOYSTICK is not set -# CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_SOFTOSS is not set -# CONFIG_SOUND_SB is not set -# CONFIG_SOUND_AWE32_SYNTH is not set -# CONFIG_SOUND_WAVEFRONT is not set -# CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_YM3812 is not set -# CONFIG_SOUND_OPL3SA1 is not set -# CONFIG_SOUND_OPL3SA2 is not set -# CONFIG_SOUND_YMPCI is not set -# CONFIG_SOUND_UART6850 is not set -# CONFIG_SOUND_AEDSP16 is not set -# CONFIG_SOUND_VIDC is not set -# CONFIG_SOUND_WAVEARTIST is not set -CONFIG_SOUND_SA1100_SSP=m +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_TOUCHSCREEN_UCB1200=m +# CONFIG_TOUCHSCREEN_BITSY is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set # # File systems @@ -339,6 +372,7 @@ CONFIG_SOUND_SA1100_SSP=m # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set @@ -367,13 +401,13 @@ CONFIG_EXT2_FS=y # Network File Systems # # CONFIG_CODA_FS is not set -# CONFIG_NFS_FS is not set +CONFIG_NFS_FS=m # CONFIG_NFS_V3 is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set -# CONFIG_SUNRPC is not set -# CONFIG_LOCKD is not set +CONFIG_SUNRPC=m +CONFIG_LOCKD=m # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -395,6 +429,57 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # +# Sound +# +CONFIG_SOUND=m +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +CONFIG_SOUND_OSS=m +CONFIG_SOUND_TRACEINIT=y +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SOFTOSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMPCI is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set +CONFIG_SOUND_SA1100_SSP=m +# CONFIG_SOUND_TVMIXER is not set + +# # USB support # # CONFIG_USB is not set @@ -406,5 +491,5 @@ CONFIG_FRAME_POINTER=y CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_USER=y # CONFIG_DEBUG_INFO is not set -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_LL=y diff --git a/arch/arm/def-configs/shark b/arch/arm/def-configs/shark new file mode 100644 index 000000000..5f62da754 --- /dev/null +++ b/arch/arm/def-configs/shark @@ -0,0 +1,655 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_SBUS is not set +CONFIG_UID16=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FTVPCI is not set +# CONFIG_ARCH_TBOX is not set +CONFIG_ARCH_SHARK=y +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +CONFIG_CPU_32v4=y +CONFIG_CPU_SA110=y +# CONFIG_DISCONTIGMEM is not set +CONFIG_PCI=y +CONFIG_ISA=y +CONFIG_ISA_DMA=y +CONFIG_PC_KEYB=y +CONFIG_PC_KEYMAP=y + +# +# General setup +# +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_NWFPE=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set +# CONFIG_ARTHUR is not set +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +# CONFIG_LEDS_CPU is not set +# CONFIG_ALIGNMENT_TRAP is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_IP_ROUTER is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +CONFIG_CS89x0=y +# CONFIG_DE4X5 is not set +# CONFIG_TULIP is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_LNE390 is not set +# CONFIG_NE3210 is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_RTL8129 is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_ES3210 is not set +# CONFIG_EPIC100 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 +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_ASH is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_BLK_DEV_SL82C105 is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set + +# +# SCSI support +# +CONFIG_SCSI=m + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=m +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_NCR53C8XX is not set +# CONFIG_SCSI_SYM53C8XX is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +CONFIG_JOYSTICK=y +CONFIG_INPUT_JOYDEV=y + +# +# Game port support +# +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set + +# +# Gameport joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set + +# +# Serial port support +# +# CONFIG_INPUT_SERPORT is not set + +# +# Serial port joysticks +# +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_IFORCE_232 is not set + +# +# Parallel port joysticks +# +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +CONFIG_JFFS_FS_VERBOSE=0 +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFSD is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_UTF8 is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_FB=y + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +CONFIG_FB_CYBER2000=y +# CONFIG_FB_MATROX is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_CFB24=y +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Sound +# +CONFIG_SOUND=m +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SOFTOSS is not set +CONFIG_SOUND_SB=m +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMPCI is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_FRAME_POINTER is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_DEBUG_LL=y diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 9fa2e8e86..ed5115c53 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -15,10 +15,18 @@ AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional O_OBJS_arc = dma-arc.o oldlatches.o O_OBJS_rpc = dma-rpc.o -O_OBJS_footbridge = dma-footbridge.o hw-footbridge.o isa.o -O_OBJS_sa1100 = hw-sa1100.o +O_OBJS_footbridge = dma-footbridge.o isa.o O_OBJS_l7200 = fiq.o +leds-ebsa110 = leds-ebsa110.o + +pci-nexuspci = plx90x0.o +pci-footbridge = dec21285.o +pci-shark = via82c505.o + +pci-$(CONFIG_ARCH_NEXUSPCI) += ftv-pci.o + + O_TARGET := kernel.o # Object file lists. @@ -30,21 +38,18 @@ obj-m := obj-n := obj- := -export-objs := armksyms.o dma.o ecard.o hw-footbridge.o \ - hw-sa1100.o leds-$(MACHINE).o oldlatches.o +export-objs := armksyms.o dma.o ecard.o \ + $(leds-$(MACHINE)) oldlatches.o \ + time.o obj-$(CONFIG_ARCH_ACORN) += ecard.o fiq.o time-acorn.o obj-$(CONFIG_DEBUG_LL) += debug-$(PROCESSOR).o obj-$(CONFIG_MODULES) += armksyms.o -obj-$(CONFIG_LEDS) += leds-$(MACHINE).o +obj-$(CONFIG_LEDS) += $(leds-$(MACHINE)) obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o -ifeq ($(MACHINE),nexuspci) - obj-$(CONFIG_PCI) += plx9080.o -else - obj-$(CONFIG_PCI) += bios32.o dec21285.o -endif +obj-$(CONFIG_PCI) += bios32.o $(pci-$(MACHINE)) $(pci-y) # Files that are both resident and modular; remove from modular. diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c index e25331e03..94a71c6e3 100644 --- a/arch/arm/kernel/arch.c +++ b/arch/arm/kernel/arch.c @@ -1,10 +1,10 @@ /* - * linux/arch/arm/kernel/arch.c + * linux/arch/arm/kernel/arch.c * - * 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. + * 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. */ #include <linux/config.h> #include <linux/tty.h> @@ -12,12 +12,12 @@ #include <linux/pm.h> #include <linux/init.h> -#include <asm/dec21285.h> #include <asm/elf.h> #include <asm/setup.h> #include <asm/mach-types.h> -#include "arch.h" +#include <asm/mach/arch.h> +#include <asm/hardware/dec21285.h> unsigned int vram_size; @@ -69,6 +69,8 @@ fixup_acorn(struct machine_desc *desc, struct param_struct *params, } #ifdef CONFIG_ARCH_RPC +extern void __init rpc_map_io(void); + MACHINE_START(RISCPC, "Acorn-RiscPC") MAINTAINER("Russell King") BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) @@ -76,6 +78,7 @@ MACHINE_START(RISCPC, "Acorn-RiscPC") DISABLE_PARPORT(0) DISABLE_PARPORT(1) FIXUP(fixup_acorn) + MAPIO(rpc_map_io) MACHINE_END #endif #ifdef CONFIG_ARCH_ARC @@ -94,379 +97,6 @@ MACHINE_END #endif #endif -#ifdef CONFIG_ARCH_EBSA285 - -static void __init -fixup_ebsa285(struct machine_desc *desc, struct param_struct *params, - char **cmdline, struct meminfo *mi) -{ - 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; -} - -MACHINE_START(EBSA285, "EBSA285") - MAINTAINER("Russell King") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - VIDEO(0x000a0000, 0x000bffff) - FIXUP(fixup_ebsa285) -MACHINE_END -#endif - -#ifdef CONFIG_ARCH_NETWINDER -/* - * 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, struct meminfo *mi) -{ -#ifdef CONFIG_ISAPNP - extern int isapnp_disable; - - /* - * We must not use the kernels ISAPnP code - * on the NetWinder - it will reset the settings - * for the WaveArtist chip and render it inoperable. - */ - isapnp_disable = 1; -#endif - - if (params->u1.s.nr_pages != 0x02000 && - params->u1.s.nr_pages != 0x04000 && - params->u1.s.nr_pages != 0x08000 && - params->u1.s.nr_pages != 0x10000) { - 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; - } -} - -MACHINE_START(NETWINDER, "Rebel-NetWinder") - MAINTAINER("Russell King/Rebel.com") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - VIDEO(0x000a0000, 0x000bffff) - DISABLE_PARPORT(0) - DISABLE_PARPORT(2) - FIXUP(fixup_netwinder) -MACHINE_END -#endif - -#ifdef CONFIG_ARCH_CATS -/* - * 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, struct meminfo *mi) -{ - ORIG_VIDEO_LINES = 25; - ORIG_VIDEO_POINTS = 16; - ORIG_Y = 24; -} - -MACHINE_START(CATS, "Chalice-CATS") - MAINTAINER("Philip Blundell") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - SOFT_REBOOT - FIXUP(fixup_cats) -MACHINE_END -#endif - -#ifdef CONFIG_ARCH_CO285 - -static void __init -fixup_coebsa285(struct machine_desc *desc, struct param_struct *params, - char **cmdline, struct meminfo *mi) -{ - extern unsigned long boot_memory_end; - extern char boot_command_line[]; - - mi->nr_banks = 1; - mi->bank[0].start = PHYS_OFFSET; - mi->bank[0].size = boot_memory_end; - mi->bank[0].node = 0; - - *cmdline = boot_command_line; -} - -MACHINE_START(CO285, "co-EBSA285") - MAINTAINER("Mark van Doesburg") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000) - FIXUP(fixup_coebsa285) -MACHINE_END -#endif - -#ifdef CONFIG_ARCH_SA1100 - -static void victor_power_off(void) -{ - /* switch off power supply */ - mdelay(2000); - GPCR = GPIO_GPIO23; - while (1); -} - - -static void xp860_power_off(void) -{ - GPDR |= GPIO_GPIO20; - GPSR = GPIO_GPIO20; - mdelay(1000); - GPCR = GPIO_GPIO20; - while(1); -} - - -extern void select_sa1100_io_desc(void); -#define SET_BANK(__nr,__start,__size) \ - mi->bank[__nr].start = (__start), \ - mi->bank[__nr].size = (__size), \ - mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27) -static void __init -fixup_sa1100(struct machine_desc *desc, struct param_struct *params, - char **cmdline, struct meminfo *mi) -{ - select_sa1100_io_desc(); - - if (machine_is_assabet()) { - /* - * On Assabet, we must probe for the Neponset board *before* - * paging_init() has occured to actually determine the amount - * of RAM available. - */ - extern void map_sa1100_gpio_regs(void); - extern void get_assabet_scr(void); - map_sa1100_gpio_regs(); - get_assabet_scr(); - - SET_BANK( 0, 0xc0000000, 32*1024*1024 ); - mi->nr_banks = 1; - - if (machine_has_neponset()) { - printk("Neponset expansion board detected\n"); - /* - * Note that Neponset RAM is slower... - * and still untested. - * This would be a candidate for - * _real_ NUMA support. - */ - //SET_BANK( 1, 0xd0000000, 32*1024*1024 ); - //mi->nr_banks = 2; - } - - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd( 0xc0800000, 3*1024*1024 ); - } - - else if (machine_is_brutus()) { - SET_BANK( 0, 0xc0000000, 4*1024*1024 ); - SET_BANK( 1, 0xc8000000, 4*1024*1024 ); - SET_BANK( 2, 0xd0000000, 4*1024*1024 ); - SET_BANK( 3, 0xd8000000, 4*1024*1024 ); - mi->nr_banks = 4; - - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd( __phys_to_virt(0xd8000000), 3*1024*1024 ); - } - - else if (machine_is_cerf()) { - // 16Meg Ram. - SET_BANK( 0, 0xc0000000, 8*1024*1024 ); - SET_BANK( 1, 0xc8000000, 8*1024*1024 ); // comment this out for 8MB Cerfs - mi->nr_banks = 2; - - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk(1, 0, 0, 8192); - // Save 2Meg for RAMDisk - setup_initrd(0xc0500000, 3*1024*1024); - } - - else if (machine_is_empeg()) { - SET_BANK( 0, 0xc0000000, 4*1024*1024 ); - SET_BANK( 1, 0xc8000000, 4*1024*1024 ); - mi->nr_banks = 2; - - ROOT_DEV = MKDEV( 3, 1 ); /* /dev/hda1 */ - setup_ramdisk( 1, 0, 0, 4096 ); - setup_initrd( 0xd0000000+((1024-320)*1024), (320*1024) ); - } - - else if (machine_is_lart()) { - /* - * Note that LART is a special case - it doesn't use physical - * address line A23 on the DRAM, so we effectively have 4 * 8MB - * in two SA1100 banks. - */ - SET_BANK( 0, 0xc0000000, 8*1024*1024 ); - SET_BANK( 1, 0xc1000000, 8*1024*1024 ); - SET_BANK( 2, 0xc8000000, 8*1024*1024 ); - SET_BANK( 3, 0xc9000000, 8*1024*1024 ); - mi->nr_banks = 4; - - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk(1, 0, 0, 8192); - setup_initrd(0xc0400000, 4*1024*1024); - } - - else if (machine_is_thinclient() || machine_is_graphicsclient()) { - SET_BANK( 0, 0xc0000000, 16*1024*1024 ); - mi->nr_banks = 1; - - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); - } - - else if (machine_is_nanoengine()) { - SET_BANK( 0, 0xc0000000, 32*1024*1024 ); - mi->nr_banks = 1; - - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); - - /* Get command line parameters passed from the loader (if any) */ - if( *((char*)0xc0000100) ) - *cmdline = ((char *)0xc0000100); - } - else if (machine_is_tifon()) { - SET_BANK( 0, 0xc0000000, 16*1024*1024 ); - SET_BANK( 1, 0xc8000000, 16*1024*1024 ); - mi->nr_banks = 2; - - ROOT_DEV = MKDEV(UNNAMED_MAJOR, 0); - setup_ramdisk(1, 0, 0, 4096); - setup_initrd( 0xd0000000 + 0x1100004, 0x140000 ); - } - - else if (machine_is_victor()) { - SET_BANK( 0, 0xc0000000, 4*1024*1024 ); - mi->nr_banks = 1; - - ROOT_DEV = MKDEV( 60, 2 ); - - /* Get command line parameters passed from the loader (if any) */ - if( *((char*)0xc0000000) ) - strcpy( *cmdline, ((char *)0xc0000000) ); - - /* power off if any problem */ - strcat( *cmdline, " panic=1" ); - - pm_power_off = victor_power_off; - } - - else if (machine_is_xp860()) { - SET_BANK( 0, 0xc0000000, 32*1024*1024 ); - mi->nr_banks = 1; - - pm_power_off = xp860_power_off; - } -} - -#ifdef CONFIG_SA1100_ASSABET -MACHINE_START(ASSABET, "Intel-Assabet") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_BITSY -MACHINE_START(BITSY, "Compaq Bitsy") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_BRUTUS -MACHINE_START(BRUTUS, "Intel Brutus (SA1100 eval board)") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_CERF -MACHINE_START(CERF, "Intrinsyc CerfBoard") - MAINTAINER("Pieter Truter") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_EMPEG -MACHINE_START(EMPEG, "empeg MP3 Car Audio Player") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_GRAPHICSCLIENT -MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_ITSY -MACHINE_START(ITSY, "Compaq Itsy") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100 - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_LART -MACHINE_START(LART, "LART") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_NANOENGINE -MACHINE_START(NANOENGINE, "BSE nanoEngine") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_PLEB -MACHINE_START(PLEB, "PLEB") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_THINCLIENT -MACHINE_START(THINCLIENT, "ADS ThinClient") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_TIFON -MACHINE_START(TIFON, "Tifon") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_VICTOR -MACHINE_START(VICTOR, "VisuAide Victor") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#ifdef CONFIG_SA1100_XP860 -MACHINE_START(XP860, "XP860") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - FIXUP(fixup_sa1100) -MACHINE_END -#endif -#endif - #ifdef CONFIG_ARCH_L7200 static void __init @@ -483,14 +113,20 @@ fixup_l7200(struct machine_desc *desc, struct param_struct *params, setup_initrd( __phys_to_virt(0xf1000000), 0x00162b0d); } +extern void __init l7200_map_io(void); + MACHINE_START(L7200, "LinkUp Systems L7200SDB") MAINTAINER("Steve Hill") BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000) FIXUP(fixup_l7200) + MAPIO(l7200_map_io) MACHINE_END #endif #ifdef CONFIG_ARCH_EBSA110 + +extern void __init ebsa110_map_io(void); + MACHINE_START(EBSA110, "EBSA110") MAINTAINER("Russell King") BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000) @@ -498,18 +134,27 @@ MACHINE_START(EBSA110, "EBSA110") DISABLE_PARPORT(0) DISABLE_PARPORT(2) SOFT_REBOOT + MAPIO(ebsa110_map_io) MACHINE_END #endif #ifdef CONFIG_ARCH_NEXUSPCI + +extern void __init nexuspci_map_io(void); + MACHINE_START(NEXUSPCI, "FTV/PCI") MAINTAINER("Philip Blundell") BOOT_MEM(0x40000000, 0x10000000, 0xe0000000) + MAPIO(nexuspci_map_io) MACHINE_END #endif #ifdef CONFIG_ARCH_TBOX + +extern void __init tbox_map_io(void); + MACHINE_START(TBOX, "unknown-TBOX") MAINTAINER("Philip Blundell") BOOT_MEM(0x80000000, 0x00400000, 0xe0000000) + MAPIO(tbox_map_io) MACHINE_END #endif #ifdef CONFIG_ARCH_CLPS7110 @@ -528,22 +173,12 @@ MACHINE_START(LACIE_NAS, "LaCie_NAS") MACHINE_END #endif #ifdef CONFIG_ARCH_CLPS7500 + +extern void __init clps7500_map_io(void); + MACHINE_START(CLPS7500, "CL-PS7500") MAINTAINER("Philip Blundell") BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) -MACHINE_END -#endif -#ifdef CONFIG_ARCH_SHARK -MACHINE_START(SHARK, "Shark") - MAINTAINER("Alexander Schulz") - BOOT_MEM(0x08000000, 0x40000000, 0xe0000000) - VIDEO(0x06000000, 0x061fffff) -MACHINE_END -#endif -#ifdef CONFIG_ARCH_PERSONAL_SERVER -MACHINE_START(PERSONAL_SERVER, "Compaq Personal Server") - MAINTAINER("Jamey Hicks / George France") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) + MAPIO(clps7500_map_io) MACHINE_END #endif diff --git a/arch/arm/kernel/arch.h b/arch/arm/kernel/arch.h deleted file mode 100644 index 87494efed..000000000 --- a/arch/arm/kernel/arch.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * The size of struct machine_desc - * (for assembler code) - */ -#define SIZEOF_MACHINE_DESC 40 - -#ifndef __ASSEMBLY__ - -struct machine_desc { - /* - * Note! The first four elements are used - * by assembler code in head-armv.S - */ - unsigned int nr; /* architecture number */ - unsigned int phys_ram; /* start of physical ram */ - unsigned int phys_io; /* start of physical io */ - unsigned int virt_io; /* start of virtual io */ - - const char *name; /* architecture name */ - unsigned int param_offset; /* parameter page */ - - unsigned int video_start; /* start of video RAM */ - unsigned int video_end; /* end of video RAM */ - - 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 */ - void (*fixup)(struct machine_desc *, - struct param_struct *, char **, - struct meminfo *); -}; - -/* - * Set of macros to define architecture features. This is built into - * a table by the linker. - */ -#define MACHINE_START(_type,_name) \ -const struct machine_desc __mach_desc_##_type \ - __attribute__((__section__(".arch.info"))) = { \ - nr: MACH_TYPE_##_type##, \ - name: _name, - -#define MAINTAINER(n) - -#define BOOT_MEM(_pram,_pio,_vio) \ - phys_ram: _pram, \ - phys_io: _pio, \ - virt_io: _vio, - -#define BOOT_PARAMS(_params) \ - param_offset: _params, - -#define VIDEO(_start,_end) \ - video_start: _start, \ - video_end: _end, - -#define DISABLE_PARPORT(_n) \ - reserve_lp##_n##: 1, - -#define BROKEN_HLT \ - broken_hlt: 1, - -#define SOFT_REBOOT \ - soft_reboot: 1, - -#define FIXUP(_func) \ - fixup: _func, - -#define MACHINE_END \ -}; - -#endif diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 8dafc4db9..a7c6d11ce 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -1,3 +1,12 @@ +/* + * linux/arch/arm/kernel/armksyms.c + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ #include <linux/config.h> #include <linux/module.h> #include <linux/user.h> @@ -110,23 +119,6 @@ EXPORT_SYMBOL(pm_idle); EXPORT_SYMBOL(pm_power_off); /* processor dependencies */ -#ifdef MULTI_CPU -EXPORT_SYMBOL(processor); -#else -EXPORT_SYMBOL(cpu_flush_cache_all); -EXPORT_SYMBOL(cpu_flush_cache_area); -EXPORT_SYMBOL(cpu_flush_cache_entry); -EXPORT_SYMBOL(cpu_clean_cache_area); -EXPORT_SYMBOL(cpu_flush_ram_page); -EXPORT_SYMBOL(cpu_flush_tlb_all); -EXPORT_SYMBOL(cpu_flush_tlb_area); -EXPORT_SYMBOL(cpu_set_pgd); -EXPORT_SYMBOL(cpu_set_pmd); -EXPORT_SYMBOL(cpu_set_pte); -EXPORT_SYMBOL(cpu_flush_icache_area); -EXPORT_SYMBOL(cpu_cache_wback_area); -EXPORT_SYMBOL(cpu_cache_purge_area); -#endif EXPORT_SYMBOL(__machine_arch_type); /* networking */ diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c index 0547302f8..236aa5f55 100644 --- a/arch/arm/kernel/arthur.c +++ b/arch/arm/kernel/arthur.c @@ -1,6 +1,14 @@ /* * Arthur personality - * Copyright (C) 1998-1999 Philip Blundell + * + * Copyright (C) 1998, 1999, 2000 Philip Blundell + */ + +/* + * 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 <linux/module.h> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 0b519e9c3..e79dd71e6 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -1,25 +1,23 @@ /* - * arch/arm/kernel/bios32.c + * linux/arch/arm/kernel/bios32.c * - * PCI bios-type initialisation for PCI machines + * PCI bios-type initialisation for PCI machines * - * Bits taken from various places. + * Bits taken from various places. */ #include <linux/config.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/init.h> +#include <asm/page.h> /* for BUG() */ #include <asm/irq.h> #include <asm/mach-types.h> - -#include "bios32.h" +#include <asm/mach/pci.h> static int debug_pci; int have_isa_bridge; -extern void hw_init(void); - void pcibios_report_status(u_int status_mask, int warn) { struct pci_dev *dev; @@ -157,6 +155,14 @@ static void __init pci_fixup_ide_bases(struct pci_dev *dev) } } +/* + * Put the DEC21142 to sleep + */ +static void __init pci_fixup_dec21142(struct pci_dev *dev) +{ + pci_write_config_dword(dev, 0x40, 0x80000000); +} + struct pci_fixup pcibios_fixups[] = { { PCI_FIXUP_HEADER, @@ -174,6 +180,10 @@ struct pci_fixup pcibios_fixups[] = { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases + }, { + PCI_FIXUP_HEADER, + PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, + pci_fixup_dec21142 }, { 0 } }; @@ -277,12 +287,11 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) * SERR and PERR reporting - this chip doesn't drive the * parity line correctly. */ -#if 1 /* !testing */ if (dev->vendor == PCI_VENDOR_ID_INTERG && dev->device == PCI_DEVICE_ID_INTERG_2000) busdata->features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY); -#endif + /* * Calculate the maximum devsel latency. */ @@ -319,18 +328,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) u8 min_gnt, latency; /* - * architecture specific hacks. I don't really want - * this here, but I don't see any other place for it - * to live. Shame the device doesn't support - * capabilities - */ - if (machine_is_netwinder() && - dev->vendor == PCI_VENDOR_ID_DEC && - dev->device == PCI_DEVICE_ID_DEC_21142) - /* Put the chip to sleep in case the driver isn't loaded */ - pci_write_config_dword(dev, 0x40, 0x80000000); - - /* * Calculate this masters latency timer value. * This is rather primitive - it does not take * account of the number of masters in a system @@ -372,184 +369,23 @@ pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *rang ranges->mem_end -= bus->resource[1]->start; } -static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin) +u8 __init no_swizzle(struct pci_dev *dev, u8 *pin) { return 0; } -/* ebsa285 host-specific stuff */ - -#ifdef CONFIG_ARCH_EBSA285 -static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI }; - -static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin) -{ - return PCI_SLOT(dev->devfn); -} - -static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - if (dev->vendor == PCI_VENDOR_ID_CONTAQ && - dev->device == PCI_DEVICE_ID_CONTAQ_82C693) - switch (PCI_FUNC(dev->devfn)) { - case 1: return 14; - case 2: return 15; - case 3: return 12; - } - - return irqmap_ebsa285[(slot + pin) & 3]; -} - -static struct hw_pci ebsa285_pci __initdata = { - dc21285_init, - 0x9000, - 0x00100000, - ebsa285_swizzle, - ebsa285_map_irq -}; -#endif - -#ifdef CONFIG_ARCH_CATS -/* cats host-specific stuff */ -static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; - -static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - if (dev->irq >= 128) - return dev->irq & 0x1f; - - if (dev->irq >= 1 && dev->irq <= 4) - return irqmap_cats[dev->irq - 1]; - - if (dev->irq != 0) - printk("PCI: device %02x:%02x has unknown irq line %x\n", - dev->bus->number, dev->devfn, dev->irq); - - return -1; -} - -static struct hw_pci cats_pci __initdata = { - dc21285_init, - 0x9000, - 0x00100000, - no_swizzle, - cats_map_irq -}; -#endif - -#ifdef CONFIG_ARCH_NETWINDER -/* netwinder host-specific stuff */ -static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ -#define DEV(v,d) ((v)<<16|(d)) - switch (DEV(dev->vendor, dev->device)) { - case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142): - case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C885): - case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_YELLOWFIN): - return IRQ_NETWINDER_ETHER100; - - case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a): - return IRQ_NETWINDER_ETHER10; - - case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553): - return 0; - - case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105): - return IRQ_ISA_HARDDISK1; - - case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000): - case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010): - case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000): - return IRQ_NETWINDER_VGA; - - case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285): - return 0; - - default: - printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n", - dev->bus->number, dev->devfn, - dev->vendor, dev->device); - return 0; - } -} - -static struct hw_pci netwinder_pci __initdata = { - dc21285_init, - 0x9000, - 0x00100000, - no_swizzle, - netwinder_map_irq -}; -#endif - -#ifdef CONFIG_ARCH_PERSONAL_SERVER -static int irqmap_personal_server[] __initdata = { - IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0, - IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI -}; - -static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - unsigned char line; - - pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line); - - if (line > 0x40 && line <= 0x5f) { - /* line corresponds to the bit controlling this interrupt - * in the footbridge. Ignore the first 8 interrupt bits, - * look up the rest in the map. IN0 is bit number 8 - */ - return irqmap_personal_server[(line & 0x1f) - 8]; - } else if (line == 0) { - /* no interrupt */ - return 0; - } else - return irqmap_personal_server[(line - 1) & 3]; -} - -static struct hw_pci personal_server_pci __initdata = { - dc21285_init, - 0x9000, - 0x00100000, - no_swizzle, - personal_server_map_irq -}; - -#endif - -#ifdef CONFIG_ARCH_NEXUSPCI -/* - * Owing to a PCB cockup, issue A backplanes are wired thus: - * - * Slot 1 2 3 4 5 Bridge - * IRQ D C B A A - * A D C B B - * B A D C C - * C B A D D - * - * ID A31 A30 A29 A28 A27 A26 - */ - -static int irqmap_ftv[] __initdata = { IRQ_PCI_A, IRQ_PCI_B, IRQ_PCI_C, IRQ_PCI_D }; - -static int __init ftv_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - return irqmap_ftv[(slot + pin) & 3]; -} - -/* ftv host-specific stuff */ -static struct hw_pci ftv_pci __initdata = { - plx90x0_init, - 0x9000, - 0x00100000, - no_swizzle, - ftv_map_irq -}; -#endif +extern struct hw_pci ebsa285_pci; +extern struct hw_pci cats_pci; +extern struct hw_pci netwinder_pci; +extern struct hw_pci personal_server_pci; +extern struct hw_pci ftv_pci; +extern struct hw_pci integrator_pci; void __init pcibios_init(void) { struct hw_pci *hw_pci = NULL; + struct arm_pci_sysdata sysdata; + int i; do { #ifdef CONFIG_ARCH_EBSA285 @@ -582,15 +418,28 @@ void __init pcibios_init(void) break; } #endif - } while (0); +#ifdef CONFIG_ARCH_INTEGRATOR + if (machine_is_integrator()) { + hw_pci = &integrator_pci; + break; + } +#endif + } while (0); if (hw_pci == NULL) return; + for (i = 0; i < MAX_NR_BUS; i++) { + sysdata.bus[i].features = PCI_COMMAND_FAST_BACK | + PCI_COMMAND_SERR | + PCI_COMMAND_PARITY; + sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST; + } + /* * Set up the host bridge, and scan the bus. */ - hw_pci->init(); + hw_pci->init(&sysdata); /* * Other architectures don't seem to do this... should we? @@ -598,8 +447,7 @@ void __init pcibios_init(void) pcibios_claim_resources(); /* - * Assign any unassigned resources. Note that we really ought to - * have min/max stuff here - max mem address is 0x0fffffff + * Assign any unassigned resources. */ pci_assign_unassigned_resources(); pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq); diff --git a/arch/arm/kernel/bios32.h b/arch/arm/kernel/bios32.h deleted file mode 100644 index 421ec6a79..000000000 --- a/arch/arm/kernel/bios32.h +++ /dev/null @@ -1,33 +0,0 @@ -#define MAX_NR_BUS 2 - -struct arm_bus_sysdata { - /* - * bitmask of features we can turn. - * See PCI command register for more info. - */ - u16 features; - /* - * Maximum devsel for this bus. - */ - u16 maxdevsel; - /* - * The maximum latency that devices on this - * bus can withstand. - */ - u8 max_lat; -}; - -struct arm_pci_sysdata { - struct arm_bus_sysdata bus[MAX_NR_BUS]; -}; - -struct hw_pci { - void (*init)(void); - unsigned long io_start; - unsigned long mem_start; - u8 (*swizzle)(struct pci_dev *dev, u8 *pin); - int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin); -}; - -void __init dc21285_init(void); -void __init plx90x0_init(void); diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index eee31eeae..9d672b4e9 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -1,9 +1,13 @@ /* - * linux/arch/arm/lib/calls.h + * linux/arch/arm/lib/calls.h * - * Copyright (C) 1995-1998 Russell King + * Copyright (C) 1995-1998 Russell King * - * This file is included twice in entry-common.S + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file is included twice in entry-common.S */ #ifndef NR_syscalls #define NR_syscalls 256 diff --git a/arch/arm/kernel/debug-armo.S b/arch/arm/kernel/debug-armo.S index 1c6aaccc3..cc10311ff 100644 --- a/arch/arm/kernel/debug-armo.S +++ b/arch/arm/kernel/debug-armo.S @@ -1,9 +1,13 @@ /* - * linux/arch/arm/kernel/debug-armo.S + * linux/arch/arm/kernel/debug-armo.S * - * Copyright (C) 1999 Russell King + * Copyright (C) 1999 Russell King * - * 26-bit debugging code + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 26-bit debugging code */ #include <linux/linkage.h> diff --git a/arch/arm/kernel/debug-armv.S b/arch/arm/kernel/debug-armv.S index e0b916438..8f9501754 100644 --- a/arch/arm/kernel/debug-armv.S +++ b/arch/arm/kernel/debug-armv.S @@ -1,14 +1,18 @@ /* - * linux/arch/arm/kernel/debug-armv.S + * linux/arch/arm/kernel/debug-armv.S * - * Copyright (C) 1994-1999 Russell King + * Copyright (C) 1994-1999 Russell King * - * 32-bit debugging code + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 32-bit debugging code */ #include <linux/config.h> #include <linux/linkage.h> #include <asm/hardware.h> -#include <asm/dec21285.h> +#include <asm/hardware/dec21285.h> .text @@ -29,10 +33,10 @@ .endm .macro busyuart,rd,rx -1002: ldrb \rd, [\rx, #0x14] +1001: ldrb \rd, [\rx, #0x14] and \rd, \rd, #0x60 teq \rd, #0x60 - bne 1002b + bne 1001b .endm .macro waituart,rd,rx @@ -189,6 +193,38 @@ tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy bne 1001b .endm + +#elif defined(CONFIG_ARCH_INTEGRATOR) + +#include <asm/hardware/serial_amba.h> + + .equ io_virt, 0xf0000000 + (0x16000000 >> 4) + .equ io_phys, 0x16000000 + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, #0x16000000 @ physical base address + movne \rx, #0xf0000000 @ virtual base + addne \rx, \rx, #0x16000000 >> 4 + .endm + + .macro senduart,rd,rx + strb \rd, [\rx, #AMBA_UARTDR] + .endm + + .macro waituart,rd,rx +1001: ldr \rd, [\rx, #0x18] @ UARTFLG + tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full + bne 1001b + .endm + + .macro busyuart,rd,rx +1001: ldr \rd, [\rx, #0x18] @ UARTFLG + tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy + bne 1001b + .endm + #else #error Unknown architecture #endif diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c index 3238b3a3c..8c427b379 100644 --- a/arch/arm/kernel/dec21285.c +++ b/arch/arm/kernel/dec21285.c @@ -1,7 +1,11 @@ /* - * arch/arm/kernel/dec21285.c: PCI functions for DC21285 + * linux/arch/arm/kernel/dec21285.c: PCI functions for DC21285 * - * Copyright (C) 1998-2000 Russell King, Phil Blundell + * Copyright (C) 1998-2000 Russell King, Phil Blundell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/sched.h> #include <linux/kernel.h> @@ -12,12 +16,11 @@ #include <linux/init.h> #include <linux/ioport.h> -#include <asm/dec21285.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/system.h> - -#include "bios32.h" +#include <asm/mach/pci.h> +#include <asm/hardware/dec21285.h> #define MAX_SLOTS 21 @@ -252,7 +255,7 @@ static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs) add_timer(timer); } -void __init dc21285_init(void) +void __init dc21285_init(struct arm_pci_sysdata *sysdata) { unsigned long cntl; unsigned int mem_size; @@ -279,19 +282,26 @@ void __init dc21285_init(void) "central function" : "addin"); if (cfn_mode) { - static struct resource csrmem, csrio; - struct arm_pci_sysdata sysdata; - int i; + static struct resource csrmem, csrio, busmem, busmempf; + struct pci_bus *bus; csrio.flags = IORESOURCE_IO; - csrio.name = "DC21285"; + csrio.name = "Footbridge"; csrmem.flags = IORESOURCE_MEM; - csrmem.name = "DC21285"; + csrmem.name = "Footbridge"; + busmem.flags = IORESOURCE_MEM; + busmem.name = "Footbridge non-prefetch"; + busmempf.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; + busmempf.name = "Footbridge prefetch"; allocate_resource(&ioport_resource, &csrio, 128, 0xff00, 0xffff, 128, NULL, NULL); allocate_resource(&iomem_resource, &csrmem, 128, 0xf4000000, 0xf8000000, 128, NULL, NULL); + allocate_resource(&iomem_resource, &busmempf, 0x20000000, + 0x00000000, 0x80000000, 0x20000000, NULL, NULL); + allocate_resource(&iomem_resource, &busmem, 0x40000000, + 0x00000000, 0x80000000, 0x40000000, NULL, NULL); /* * Map our SDRAM at a known address in PCI space, just in case @@ -302,24 +312,24 @@ void __init dc21285_init(void) *CSR_PCICACHELINESIZE = 0x00002008; *CSR_PCICSRBASE = csrmem.start; *CSR_PCICSRIOBASE = csrio.start; - *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET); + *CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET); *CSR_PCIROMBASE = 0; *CSR_PCICMD = pci_cmd | (1 << 31) | (1 << 29) | (1 << 28) | (1 << 24); - for (i = 0; i < MAX_NR_BUS; i++) { - sysdata.bus[i].features = PCI_COMMAND_FAST_BACK | - PCI_COMMAND_SERR | - PCI_COMMAND_PARITY; - sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST; - } - - pci_scan_bus(0, &dc21285_ops, &sysdata); + bus = pci_scan_bus(0, &dc21285_ops, sysdata); + /* + * bus->resource[0] is the IO resource for this bus + * bus->resource[1] is the mem resource for this bus + * bus->resource[2] is the prefetch mem resource for this bus + */ + bus->resource[1] = &busmem; + bus->resource[2] = &busmempf; - pci_cmd |= sysdata.bus[0].features; + pci_cmd |= sysdata->bus[0].features; printk("PCI: Fast back to back transfers %sabled\n", - (sysdata.bus[0].features & PCI_COMMAND_FAST_BACK) ? + (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); /* diff --git a/arch/arm/kernel/dma-arc.c b/arch/arm/kernel/dma-arc.c index 25fbcccd8..2ad2edf3b 100644 --- a/arch/arm/kernel/dma-arc.c +++ b/arch/arm/kernel/dma-arc.c @@ -1,9 +1,13 @@ /* - * arch/arm/kernel/dma-arc.c + * linux/arch/arm/kernel/dma-arc.c * - * Copyright (C) 1998-1999 Dave Gilbert / Russell King + * Copyright (C) 1998-1999 Dave Gilbert / Russell King * - * DMA functions specific to Archimedes and A5000 architecture + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * DMA functions specific to Archimedes and A5000 architecture */ #include <linux/config.h> #include <linux/sched.h> @@ -11,11 +15,12 @@ #include <asm/dma.h> #include <asm/fiq.h> +#include <asm/irq.h> #include <asm/io.h> #include <asm/hardware.h> #include <asm/mach-types.h> -#include "dma.h" +#include <asm/mach/dma.h> #define DPRINTK(x...) printk(KERN_DEBUG x) @@ -30,11 +35,11 @@ static void arc_floppy_data_enable_dma(dmach_t channel, dma_t *dma) unsigned long flags; DPRINTK("enable_dma fdc1772 data read\n"); save_flags(flags); - cliIF(); + clf(); memcpy ((void *)0x1c, (void *)&fdc1772_dma_read, &fdc1772_dma_read_end - &fdc1772_dma_read); - fdc1772_setupdma(dma->buf.length, __bus_to_virt(dma->buf.address)); /* Sets data pointer up */ + fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */ enable_irq (64); restore_flags(flags); } @@ -46,10 +51,10 @@ static void arc_floppy_data_enable_dma(dmach_t channel, dma_t *dma) unsigned long flags; DPRINTK("enable_dma fdc1772 data write\n"); save_flags(flags); - cliIF(); + clf(); memcpy ((void *)0x1c, (void *)&fdc1772_dma_write, &fdc1772_dma_write_end - &fdc1772_dma_write); - fdc1772_setupdma(dma->buf.length, __bus_to_virt(dma->buf.address)); /* Sets data pointer up */ + fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */ enable_irq (64); restore_flags(flags); @@ -77,7 +82,7 @@ static void arc_floppy_cmdend_enable_dma(dmach_t channel, dma_t *dma) DPRINTK("arc_floppy_cmdend_enable_dma\n"); /*printk("enable_dma fdc1772 command end FIQ\n");*/ save_flags(flags); - cliIF(); + clf(); /* B fdc1772_comendhandler */ *((unsigned int *)0x1c)=0xea000000 | @@ -150,7 +155,7 @@ static void a5k_floppy_enable_dma(dmach_t channel, dma_t *dma) } memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length); regs.ARM_r9 = dma->buf.length; - regs.ARM_r10 = __bus_to_virt(dma->buf.address); + regs.ARM_r10 = dma->buf.address; regs.ARM_fp = (int)PCIO_FLOPPYDMABASE; set_fiq_regs(®s); enable_irq(dma->dma_irq); @@ -173,7 +178,7 @@ static struct dma_ops a5k_floppy_dma_ops = { /* * This is virtual DMA - we don't need anything here */ -static int sound_enable_disable_dma(dmach_t channel, dma_t *dma) +static void sound_enable_disable_dma(dmach_t channel, dma_t *dma) { } @@ -195,8 +200,8 @@ void __init arch_dma_init(dma_t *dma) #endif #ifdef CONFIG_ARCH_A5K if (machine_is_a5k()) { - dma[DMA_VIRTUAL_FLOPPY].dma_irq = 64; - dma[DMA_VIRTUAL_FLOPPY].d_ops = &a5k_floppy_dma_ops; + dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64; + dma[DMA_VIRTUAL_FLOPPY0].d_ops = &a5k_floppy_dma_ops; } #endif dma[DMA_VIRTUAL_SOUND].d_ops = &sound_dma_ops; diff --git a/arch/arm/kernel/dma-footbridge.c b/arch/arm/kernel/dma-footbridge.c index b9d4b62fa..1674a007a 100644 --- a/arch/arm/kernel/dma-footbridge.c +++ b/arch/arm/kernel/dma-footbridge.c @@ -1,27 +1,24 @@ /* - * arch/arm/kernel/dma-ebsa285.c + * linux/arch/arm/kernel/dma-ebsa285.c * - * Copyright (C) 1998 Phil Blundell + * Copyright (C) 1998 Phil Blundell * * DMA functions specific to EBSA-285/CATS architectures * - * Changelog: - * 09-Nov-1998 RMK Split out ISA DMA functions to dma-isa.c - * 17-Mar-1999 RMK Allow any EBSA285-like architecture to have + * Changelog: + * 09-Nov-1998 RMK Split out ISA DMA functions to dma-isa.c + * 17-Mar-1999 RMK Allow any EBSA285-like architecture to have * ISA DMA controllers. */ - #include <linux/config.h> #include <linux/sched.h> #include <linux/init.h> -#include <asm/dec21285.h> #include <asm/dma.h> #include <asm/io.h> -#include "dma.h" - -extern void isa_init_dma(dma_t *dma); +#include <asm/mach/dma.h> +#include <asm/hardware/dec21285.h> #if 0 static int fb_dma_request(dmach_t channel, dma_t *dma) diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c index f144d0436..b3a1ea06d 100644 --- a/arch/arm/kernel/dma-isa.c +++ b/arch/arm/kernel/dma-isa.c @@ -1,24 +1,30 @@ /* - * arch/arm/kernel/dma-isa.c: ISA DMA primitives + * linux/arch/arm/kernel/dma-isa.c * - * Copyright (C) 1999-2000 Russell King + * Copyright (C) 1999-2000 Russell King * - * Taken from various sources, including: - * linux/include/asm/dma.h: Defines for using and allocating dma channels. - * Written by Hennus Bergman, 1992. - * High DMA channel support & info by Hannu Savolainen and John Boyd, - * Nov. 1992. - * arch/arm/kernel/dma-ebsa285.c - * Copyright (C) 1998 Phil Blundell + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ISA DMA primitives + * Taken from various sources, including: + * linux/include/asm/dma.h: Defines for using and allocating dma channels. + * Written by Hennus Bergman, 1992. + * High DMA channel support & info by Hannu Savolainen and John Boyd, + * Nov. 1992. + * arch/arm/kernel/dma-ebsa285.c + * Copyright (C) 1998 Phil Blundell */ #include <linux/sched.h> #include <linux/ioport.h> #include <linux/init.h> +#include <linux/pci.h> #include <asm/dma.h> #include <asm/io.h> -#include "dma.h" +#include <asm/mach/dma.h> #define ISA_DMA_MODE_READ 0x44 #define ISA_DMA_MODE_WRITE 0x48 @@ -60,48 +66,58 @@ static void isa_enable_dma(dmach_t channel, dma_t *dma) { if (dma->invalid) { unsigned long address, length; - unsigned int mode; - - address = dma->buf.address; - length = dma->buf.length - 1; - - outb(address >> 16, isa_dma_port[channel][ISA_DMA_PGLO]); - outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]); - - if (channel >= 4) { - address >>= 1; - length >>= 1; - } - - outb(0, isa_dma_port[channel][ISA_DMA_CLRFF]); - - outb(address, isa_dma_port[channel][ISA_DMA_ADDR]); - outb(address >> 8, isa_dma_port[channel][ISA_DMA_ADDR]); - - outb(length, isa_dma_port[channel][ISA_DMA_COUNT]); - outb(length >> 8, isa_dma_port[channel][ISA_DMA_COUNT]); + unsigned int mode, direction; mode = channel & 3; - switch (dma->dma_mode & DMA_MODE_MASK) { case DMA_MODE_READ: mode |= ISA_DMA_MODE_READ; - dma_cache_inv(__bus_to_virt(dma->buf.address), dma->buf.length); + direction = PCI_DMA_FROMDEVICE; break; case DMA_MODE_WRITE: mode |= ISA_DMA_MODE_WRITE; - dma_cache_wback(__bus_to_virt(dma->buf.address), dma->buf.length); + direction = PCI_DMA_TODEVICE; break; case DMA_MODE_CASCADE: mode |= ISA_DMA_MODE_CASCADE; + direction = PCI_DMA_BIDIRECTIONAL; break; default: break; } + if (!dma->using_sg) { + /* + * Cope with ISA-style drivers which expect cache + * coherence. + */ + dma->buf.dma_address = pci_map_single(NULL, + dma->buf.address, dma->buf.length, + direction); + } + + address = dma->buf.dma_address; + length = dma->buf.length - 1; + + outb(address >> 16, isa_dma_port[channel][ISA_DMA_PGLO]); + outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]); + + if (channel >= 4) { + address >>= 1; + length >>= 1; + } + + outb(0, isa_dma_port[channel][ISA_DMA_CLRFF]); + + outb(address, isa_dma_port[channel][ISA_DMA_ADDR]); + outb(address >> 8, isa_dma_port[channel][ISA_DMA_ADDR]); + + outb(length, isa_dma_port[channel][ISA_DMA_COUNT]); + outb(length >> 8, isa_dma_port[channel][ISA_DMA_COUNT]); + if (dma->dma_mode & DMA_AUTOINIT) mode |= ISA_DMA_AUTOINIT; diff --git a/arch/arm/kernel/dma-rpc.c b/arch/arm/kernel/dma-rpc.c index c7eecfe42..b46ca7753 100644 --- a/arch/arm/kernel/dma-rpc.c +++ b/arch/arm/kernel/dma-rpc.c @@ -1,25 +1,30 @@ /* - * arch/arm/kernel/dma-rpc.c + * linux/arch/arm/kernel/dma-rpc.c * - * Copyright (C) 1998 Russell King + * Copyright (C) 1998 Russell King * - * DMA functions specific to RiscPC architecture + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * DMA functions specific to RiscPC architecture */ #include <linux/sched.h> #include <linux/malloc.h> #include <linux/mman.h> #include <linux/init.h> +#include <linux/pci.h> #include <asm/page.h> #include <asm/dma.h> #include <asm/fiq.h> #include <asm/io.h> -#include <asm/iomd.h> #include <asm/irq.h> #include <asm/hardware.h> #include <asm/uaccess.h> -#include "dma.h" +#include <asm/mach/dma.h> +#include <asm/hardware/iomd.h> #if 0 typedef enum { @@ -47,13 +52,13 @@ typedef struct { #define state_wait_a 1 #define state_wait_b 2 -static void iomd_get_next_sg(dmasg_t *sg, dma_t *dma) +static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma) { unsigned long end, offset, flags = 0; if (dma->sg) { - sg->address = dma->sg->address; - offset = sg->address & ~PAGE_MASK; + sg->dma_address = dma->sg->dma_address; + offset = sg->dma_address & ~PAGE_MASK; end = offset + dma->sg->length; @@ -66,7 +71,7 @@ static void iomd_get_next_sg(dmasg_t *sg, dma_t *dma) sg->length = end - TRANSFER_SIZE; dma->sg->length -= end - offset; - dma->sg->address += end - offset; + dma->sg->dma_address += end - offset; if (dma->sg->length == 0) { if (dma->sgcount > 1) { @@ -79,22 +84,22 @@ static void iomd_get_next_sg(dmasg_t *sg, dma_t *dma) } } else { flags = DMA_END_S | DMA_END_L; - sg->address = 0; + sg->dma_address = 0; sg->length = 0; } sg->length |= flags; } -static inline void iomd_setup_dma_a(dmasg_t *sg, dma_t *dma) +static inline void iomd_setup_dma_a(struct scatterlist *sg, dma_t *dma) { - outl_t(sg->address, dma->dma_base + CURA); + outl_t(sg->dma_address, dma->dma_base + CURA); outl_t(sg->length, dma->dma_base + ENDA); } -static inline void iomd_setup_dma_b(dmasg_t *sg, dma_t *dma) +static inline void iomd_setup_dma_b(struct scatterlist *sg, dma_t *dma) { - outl_t(sg->address, dma->dma_base + CURB); + outl_t(sg->dma_address, dma->dma_base + CURB); outl_t(sg->length, dma->dma_base + ENDB); } @@ -160,17 +165,8 @@ static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs) static int iomd_request_dma(dmach_t channel, dma_t *dma) { - unsigned long flags; - int ret; - - save_flags_cli(flags); - ret = request_irq(dma->dma_irq, iomd_dma_handle, - SA_INTERRUPT, dma->device_id, dma); - if (!ret) - disable_irq(dma->dma_irq); - restore_flags(flags); - - return ret; + return request_irq(dma->dma_irq, iomd_dma_handle, + SA_INTERRUPT, dma->device_id, dma); } static void iomd_free_dma(dmach_t channel, dma_t *dma) @@ -186,6 +182,17 @@ static void iomd_enable_dma(dmach_t channel, dma_t *dma) if (dma->invalid) { dma->invalid = 0; + /* + * Cope with ISA-style drivers which expect cache + * coherence. + */ + if (!dma->using_sg) { + dma->buf.dma_address = pci_map_single(NULL, + dma->buf.address, dma->buf.length, + dma->dma_mode == DMA_MODE_READ ? + PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); + } + outb_t(DMA_CR_C, dma_base + CR); dma->state = state_prog_a; } @@ -279,8 +286,8 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma) } regs.ARM_r9 = dma->buf.length; - regs.ARM_r10 = __bus_to_virt(dma->buf.address); - regs.ARM_fp = (int)PCIO_FLOPPYDMABASE; + regs.ARM_r10 = (unsigned long)dma->buf.address; + regs.ARM_fp = (unsigned long)PCIO_FLOPPYDMABASE; if (claim_fiq(&fh)) { printk("floppydma: couldn't claim FIQ.\n"); diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c index 6fe844db4..ad311020f 100644 --- a/arch/arm/kernel/dma.c +++ b/arch/arm/kernel/dma.c @@ -1,11 +1,15 @@ /* - * linux/arch/arm/kernel/dma.c + * linux/arch/arm/kernel/dma.c * - * Copyright (C) 1995-2000 Russell King + * Copyright (C) 1995-2000 Russell King * - * Front-end to the DMA handling. This handles the allocation/freeing - * of DMA channels, and provides a unified interface to the machines - * DMA facilities. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Front-end to the DMA handling. This handles the allocation/freeing + * of DMA channels, and provides a unified interface to the machines + * DMA facilities. */ #include <linux/module.h> #include <linux/malloc.h> @@ -16,7 +20,7 @@ #include <asm/dma.h> -#include "dma.h" +#include <asm/mach/dma.h> spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED; @@ -111,12 +115,13 @@ bad_dma: /* Set DMA Scatter-Gather list */ -void set_dma_sg (dmach_t channel, dmasg_t *sg, int nr_sg) +void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg) { dma_t *dma = dma_chan + channel; dma->sg = sg; dma->sgcount = nr_sg; + dma->using_sg = 1; dma->invalid = 1; } @@ -134,7 +139,8 @@ void set_dma_addr (dmach_t channel, unsigned long physaddr) dma->sg = &dma->buf; dma->sgcount = 1; - dma->buf.address = physaddr; + dma->buf.address = bus_to_virt(physaddr); + dma->using_sg = 0; dma->invalid = 1; } @@ -153,6 +159,7 @@ void set_dma_count (dmach_t channel, unsigned long count) dma->sg = &dma->buf; dma->sgcount = 1; dma->buf.length = count; + dma->using_sg = 0; dma->invalid = 1; } diff --git a/arch/arm/kernel/dma.h b/arch/arm/kernel/dma.h deleted file mode 100644 index 6cd96ed97..000000000 --- a/arch/arm/kernel/dma.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * linux/arch/arm/kernel/dma.h - * - * Copyright (C) 1998-2000 Russell King - * - * This header file describes the interface between the generic DMA handler - * (dma.c) and the architecture-specific DMA backends (dma-*.c) - */ - -struct dma_struct; -typedef struct dma_struct dma_t; - -struct dma_ops { - int (*request)(dmach_t, dma_t *); /* optional */ - void (*free)(dmach_t, dma_t *); /* optional */ - void (*enable)(dmach_t, dma_t *); /* mandatory */ - void (*disable)(dmach_t, dma_t *); /* mandatory */ - int (*residue)(dmach_t, dma_t *); /* optional */ - int (*setspeed)(dmach_t, dma_t *, int); /* optional */ - char *type; -}; - -struct dma_struct { - dmasg_t buf; /* single DMA */ - int sgcount; /* number of DMA SG */ - dmasg_t *sg; /* DMA Scatter-Gather List */ - - unsigned int active:1; /* Transfer active */ - unsigned int invalid:1; /* Address/Count changed */ - dmamode_t dma_mode; /* DMA mode */ - int speed; /* DMA speed */ - - unsigned int lock; /* Device is allocated */ - const char *device_id; /* Device name */ - - unsigned int dma_base; /* Controller base address */ - int dma_irq; /* Controller IRQ */ - int state; /* Controller state */ - dmasg_t cur_sg; /* Current controller buffer */ - - struct dma_ops *d_ops; -}; - -/* Prototype: void arch_dma_init(dma) - * Purpose : Initialise architecture specific DMA - * Params : dma - pointer to array of DMA structures - */ -void arch_dma_init(dma_t *dma); diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 6d9b425ea..3584c3227 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -1,27 +1,30 @@ /* - * linux/arch/arm/kernel/ecard.c + * linux/arch/arm/kernel/ecard.c * - * Find all installed expansion cards, and handle interrupts from them. + * Copyright 1995-1998 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * - * Copyright 1995-1998 Russell King + * Find all installed expansion cards, and handle interrupts from them. * - * Created from information from Acorns RiscOS3 PRMs + * Created from information from Acorns RiscOS3 PRMs * - * 08-Dec-1996 RMK Added code for the 9'th expansion card - the ether + * 08-Dec-1996 RMK Added code for the 9'th expansion card - the ether * podule slot. - * 06-May-1997 RMK Added blacklist for cards whose loader doesn't work. - * 12-Sep-1997 RMK Created new handling of interrupt enables/disables + * 06-May-1997 RMK Added blacklist for cards whose loader doesn't work. + * 12-Sep-1997 RMK Created new handling of interrupt enables/disables * - cards can now register their own routine to control * interrupts (recommended). - * 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled + * 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled * on reset from Linux. (Caused cards not to respond * under RiscOS without hard reset). - * 15-Feb-1998 RMK Added DMA support - * 12-Sep-1998 RMK Added EASI support - * 10-Jan-1999 RMK Run loaders in a simulated RISC OS environment. - * 17-Apr-1999 RMK Support for EASI Type C cycles. + * 15-Feb-1998 RMK Added DMA support + * 12-Sep-1998 RMK Added EASI support + * 10-Jan-1999 RMK Run loaders in a simulated RISC OS environment. + * 17-Apr-1999 RMK Support for EASI Type C cycles. */ - #define ECARD_C #define __KERNEL_SYSCALLS__ @@ -137,15 +140,10 @@ ecard_task_reset(struct ecard_request *req) if (req->ec == NULL) { ecard_t *ec; - for (ec = cards; ec; ec = ec->next) { - printk(KERN_DEBUG "Resetting card %d\n", - ec->slot_no); - + for (ec = cards; ec; ec = ec->next) if (ec->loader) ecard_loader_reset(POD_INT_ADDR(ec->podaddr), ec->loader); - } - printk(KERN_DEBUG "All cards reset\n"); } else if (req->ec->loader) ecard_loader_reset(POD_INT_ADDR(req->ec->podaddr), req->ec->loader); @@ -318,7 +316,7 @@ ecard_task(void * unused) * We don't want /any/ signals, not even SIGKILL */ sigfillset(&tsk->blocked); - sigemptyset(&tsk->signal); + sigemptyset(&tsk->pending.signal); recalc_sigpending(tsk); strcpy(tsk->comm, "kecardd"); @@ -335,7 +333,7 @@ ecard_task(void * unused) req = xchg(&ecard_req, NULL); if (req == NULL) { - sigemptyset(&tsk->signal); + sigemptyset(&tsk->pending.signal); interruptible_sleep_on(&ecard_wait); } } while (req == NULL); diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S index ab0f4e69e..e4df9fe1a 100644 --- a/arch/arm/kernel/entry-armo.S +++ b/arch/arm/kernel/entry-armo.S @@ -1,25 +1,29 @@ /* - * linux/arch/arm/kernel/entry-armo.S + * linux/arch/arm/kernel/entry-armo.S * - * Copyright (C) 1995,1996,1997,1998 Russell King. + * Copyright (C) 1995,1996,1997,1998 Russell King. * - * Low-level vector interface routines + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * - * Design issues: - * - We have several modes that each vector can be called from, - * each with its own set of registers. On entry to any vector, - * we *must* save the registers used in *that* mode. + * Low-level vector interface routines * - * - This code must be as fast as possible. + * Design issues: + * - We have several modes that each vector can be called from, + * each with its own set of registers. On entry to any vector, + * we *must* save the registers used in *that* mode. * - * There are a few restrictions on the vectors: - * - the SWI vector cannot be called from *any* non-user mode + * - This code must be as fast as possible. * - * - the FP emulator is *never* called from *any* non-user mode undefined - * instruction. + * There are a few restrictions on the vectors: + * - the SWI vector cannot be called from *any* non-user mode * - * Ok, so this file may be a mess, but its as efficient as possible while - * adhering to the above criteria. + * - the FP emulator is *never* called from *any* non-user mode undefined + * instruction. + * + * Ok, so this file may be a mess, but its as efficient as possible while + * adhering to the above criteria. */ #include <linux/linkage.h> #include <linux/config.h> diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 002c39933..c8c737404 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -1,13 +1,17 @@ /* - * linux/arch/arm/kernel/entry-armv.S + * linux/arch/arm/kernel/entry-armv.S * - * Copyright (C) 1996,1997,1998 Russell King. - * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk) + * Copyright (C) 1996,1997,1998 Russell King. + * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk) * - * Low-level vector interface routines + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * - * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes - * it to save wrong values... Be aware! + * Low-level vector interface routines + * + * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes + * it to save wrong values... Be aware! */ #include <linux/config.h> /* for CONFIG_ARCH_xxxx */ #include <linux/linkage.h> @@ -68,7 +72,7 @@ #ifdef IOC_BASE /* IOC / IOMD based hardware */ -#include <asm/iomd.h> +#include <asm/hardware/iomd.h> .equ ioc_base_high, IOC_BASE & 0xff000000 .equ ioc_base_low, IOC_BASE & 0x00ff0000 @@ -226,7 +230,7 @@ irq_prio_ebsa110: .endm #elif defined(CONFIG_FOOTBRIDGE) -#include <asm/dec21285.h> +#include <asm/hardware/dec21285.h> .macro disable_fiq .endm @@ -425,9 +429,9 @@ ENTRY(soft_irq_mask) .endm .macro get_irqnr_and_base, irqnr, irqstat, base - mov r4, #irq_base_addr @ Virt addr IRQ regs - add r4, r4, #0x00001000 @ Status reg - ldr \irqstat, [r4] @ get interrupts + mov \irqstat, #irq_base_addr @ Virt addr IRQ regs + add \irqstat, \irqstat, #0x00001000 @ Status reg + ldr \irqstat, [\irqstat, #0] @ get interrupts mov \irqnr, #0 1001: tst \irqstat, #1 addeq \irqnr, \irqnr, #1 @@ -440,6 +444,32 @@ ENTRY(soft_irq_mask) .macro irq_prio_table .endm +#elif defined(CONFIG_ARCH_INTEGRATOR) + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base +/* FIXME: should not be using soo many LDRs here */ + ldr \irqnr, =IO_ADDRESS(INTEGRATOR_IC_BASE) + ldr \irqstat, [\irqnr, #IRQ_STATUS] @ get masked status + ldr \irqnr, =IO_ADDRESS(INTEGRATOR_HDR_BASE) + ldr \irqnr, [\irqnr, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)] + orr \irqstat, \irqstat, \irqnr, lsl #INTEGRATOR_CM_INT0 + + mov \irqnr, #0 +1001: tst \irqstat, #1 + bne 1002f + add \irqnr, \irqnr, #1 + mov \irqstat, \irqstat, lsr #1 + cmp \irqnr, #22 + bcc 1001b +1002: /* EQ will be set if we reach 22 */ + .endm + + .macro irq_prio_table + .endm + #else #error Unknown architecture #endif diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index b22720cd5..8fe41f38c 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -1,3 +1,12 @@ +/* + * linux/arch/arm/kernel/entry-common.S + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ #include <linux/config.h> #define PT_TRACESYS 0x00000002 diff --git a/arch/arm/kernel/ftv-pci.c b/arch/arm/kernel/ftv-pci.c new file mode 100644 index 000000000..11369bc58 --- /dev/null +++ b/arch/arm/kernel/ftv-pci.c @@ -0,0 +1,51 @@ +/* + * linux/arch/arm/kernel/ftv-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> + +/* + * Owing to a PCB cockup, issue A backplanes are wired thus: + * + * Slot 1 2 3 4 5 Bridge S1 S2 S3 S4 + * IRQ D C B A A C B A D + * A D C B B D C B A + * B A D C C A D C B + * C B A D D B A D C + * + * ID A31 A30 A29 A28 A27 A26 DEV4 DEV5 DEV6 DEV7 + * + * Actually, this isn't too bad, because with the processor card + * in slot 5 on the primary bus, the IRQs rotate on both sides + * as you'd expect. + */ + +static int irqmap_ftv[] __initdata = { IRQ_PCI_D, IRQ_PCI_C, IRQ_PCI_B, IRQ_PCI_A }; + +static int __init ftv_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (slot > 0x10) + slot--; + return irqmap_ftv[(slot - pin) & 3]; +} + +static u8 __init ftv_swizzle(struct pci_dev *dev, u8 *pin) +{ + return PCI_SLOT(dev->devfn); +} + +/* ftv host-specific stuff */ +struct hw_pci ftv_pci __initdata = { + init: plx90x0_init, + swizzle: ftv_swizzle, + map_irq: ftv_map_irq, +}; + diff --git a/arch/arm/kernel/head-armo.S b/arch/arm/kernel/head-armo.S index f0360a3d9..f42f3337d 100644 --- a/arch/arm/kernel/head-armo.S +++ b/arch/arm/kernel/head-armo.S @@ -1,9 +1,13 @@ /* - * linux/arch/arm/kernel/head-armo.S + * linux/arch/arm/kernel/head-armo.S * - * Copyright (C) 1994-2000 Russell King + * Copyright (C) 1994-2000 Russell King * - * 26-bit kernel startup code + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 26-bit kernel startup code */ #include <linux/config.h> #include <linux/linkage.h> @@ -72,6 +76,7 @@ detect_arch_type: mov pc, lr detect_proc_type: + mov ip, lr mov r2, #0xea000000 @ Point undef instr to continuation adr r0, continue - 12 orr r0, r2, r0, lsr #2 @@ -80,8 +85,9 @@ detect_proc_type: ldr r0, arm2_id swp r2, r2, [r1] @ check for swp (ARM2 can't) ldr r0, arm250_id - mrc 15, 0, r0, c0, c0 @ check for CP#15 (ARM250 can't) + mrc 15, 0, r3, c0, c0 @ check for CP#15 (ARM250 can't) + mov r0, r3 continue: mov r2, #0xeb000000 @ Make undef vector loop sub r2, r2, #2 str r2, [r1, #4] - mov pc, lr + mov pc, ip diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S index e253c7efa..5e141bf51 100644 --- a/arch/arm/kernel/head-armv.S +++ b/arch/arm/kernel/head-armv.S @@ -1,26 +1,36 @@ /* - * linux/arch/arm/kernel/head-armv.S + * linux/arch/arm/kernel/head-armv.S * - * Copyright (C) 1994-1999 Russell King + * Copyright (C) 1994-1999 Russell King * - * 32-bit kernel startup code for all architectures + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 32-bit kernel startup code for all architectures */ #include <linux/config.h> #include <linux/linkage.h> #include <asm/assembler.h> -#include <asm/hardware.h> -#include <asm/dec21285.h> - -#include "arch.h" +#include <asm/mach-types.h> +#include <asm/mach/arch.h> #if (TEXTADDR & 0xffff) != 0x8000 #error TEXTADDR must start at 0xXXXX8000 #endif -#define SWAPPER_PGDIR_OFFSET 0x4000 #define K(a,b,c) ((a) << 24 | (b) << 12 | (c)) +/* + * swapper_pg_dir is the virtual address of the "init_task" page tables. + * SWAPPER_PGDIR_OFFSET is the offset from the start of memory of the + * page tables. + * + * Note that at the moment, we assume TEXTADDR is the virtual equivalent + * of start of memory + 0x8000 + */ +#define SWAPPER_PGDIR_OFFSET 0x4000 .globl SYMBOL_NAME(swapper_pg_dir) .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x8000 + SWAPPER_PGDIR_OFFSET @@ -50,7 +60,7 @@ ENTRY(_stext) * ideal, but in this case, it should ONLY set r0 and r1 to the * appropriate value. */ -#ifdef CONFIG_ARCH_NETWINDER +#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_INTEGRATOR) /* * Compatability cruft for old NetWinder NeTTroms. This * code is currently scheduled for destruction in 2.5.xx @@ -85,18 +95,23 @@ ENTRY(_stext) mov r5, #0 movne pc, r0 - mov r1, #5 @ (will go in 2.5) - mov r12, #2 << 24 @ scheduled for removal in 2.5.xx + mov r1, #MACH_TYPE_NETWINDER @ (will go in 2.5) + mov r12, #2 << 24 @ scheduled for removal in 2.5.xx orr r12, r12, #5 << 12 +__entry: #endif -#ifdef CONFIG_ARCH_L7200 +#if defined(CONFIG_ARCH_L7200) /* * FIXME - No bootloader, so manually set 'r1' with our architecture number. */ - mov r1, #19 + mov r1, #MACH_TYPE_L7200 +#elif defined(CONFIG_ARCH_INTEGRATOR) + mov r1, #MACH_TYPE_INTEGRATOR #endif -__entry: bl __lookup_processor_type + mov r0, #F_BIT | I_BIT | MODE_SVC @ make sure svc mode + msr cpsr_c, r0 @ and all irqs diabled + bl __lookup_processor_type teq r10, #0 @ invalid processor? moveq r0, #'p' @ yes, error 'p' beq __error @@ -140,7 +155,7 @@ __mmap_switched: @ sp = stack pointer str r12, [r2] - mov fp, #0 @ Clear BSS + mov fp, #0 @ Clear BSS (and zero fp) 1: cmp r4, r5 strcc fp, [r4],#4 bcc 1b @@ -182,17 +197,19 @@ __create_page_tables: bne 1b /* * Create identity mapping for first MB of kernel. - * map in four sections (4MB) for kernel. - * these are marked cacheable and bufferable. + * This is marked cacheable and bufferable. * * The identity mapping will be removed by paging_init() */ - mov r3, #0x0c @ cacheable, bufferable - orr r3, r3, r8 @ | pagetable flags - add r3, r3, r5 @ + start of RAM + add r3, r8, r5 @ mmuflags + start of RAM add r0, r4, r5, lsr #18 str r3, [r0] @ identity mapping - add r0, r4, #(TEXTADDR - 0x8000) >> 18 @ start of kernel + /* + * Now setup the pagetables for our kernel direct + * mapped region. We round TEXTADDR down to the + * nearest megabyte boundary. + */ + add r0, r4, #(TEXTADDR & 0xfff00000) >> 18 @ start of kernel str r3, [r0], #4 @ PAGE_OFFSET + 0MB add r3, r3, #1 << 20 str r3, [r0], #4 @ PAGE_OFFSET + 1MB @@ -200,6 +217,9 @@ __create_page_tables: str r3, [r0], #4 @ PAGE_OFFSET + 2MB add r3, r3, #1 << 20 str r3, [r0], #4 @ PAGE_OFFSET + 3MB + + bic r8, r8, #0x0c @ turn off cacheable + @ and bufferable bits #ifdef CONFIG_DEBUG_LL /* * Map in IO space for serial debugging. diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c index 1a379ee10..480c025fb 100644 --- a/arch/arm/kernel/init_task.c +++ b/arch/arm/kernel/init_task.c @@ -1,6 +1,10 @@ +/* + * linux/arch/arm/kernel/init_task.c + */ #include <linux/mm.h> #include <linux/fs.h> #include <linux/sched.h> +#include <linux/init.h> #include <asm/uaccess.h> #include <asm/pgtable.h> diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 69b72624d..3c6899264 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -4,16 +4,18 @@ * Copyright (C) 1992 Linus Torvalds * Modifications for ARM processor Copyright (C) 1995-1998 Russell King. * - * This file contains the code used by various IRQ handling routines: - * asking for different IRQ's should be done through these routines - * instead of just grabbing them. Thus setups with different IRQ numbers - * shouldn't result in any weird surprises, and installing new handlers - * should be easier. - */ - -/* - * IRQ's are in fact implemented a bit like signal handlers for the kernel. - * Naturally it's not a 1:1 relation, but there are similarities. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file contains the code used by various IRQ handling routines: + * asking for different IRQ's should be done through these routines + * instead of just grabbing them. Thus setups with different IRQ numbers + * shouldn't result in any weird surprises, and installing new handlers + * should be easier. + * + * IRQ's are in fact implemented a bit like signal handlers for the kernel. + * Naturally it's not a 1:1 relation, but there are similarities. */ #include <linux/config.h> #include <linux/ptrace.h> diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c index 17696acb0..c9b9526d2 100644 --- a/arch/arm/kernel/isa.c +++ b/arch/arm/kernel/isa.c @@ -1,9 +1,16 @@ /* - * arch/arm/kernel/isa.c + * linux/arch/arm/kernel/isa.c * - * ISA shared memory and I/O port support + * Copyright (C) 1999 Phil Blundell * - * Copyright (C) 1999 Phil Blundell + * ISA shared memory and I/O port support + */ + +/* + * 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. */ /* diff --git a/arch/arm/kernel/leds-ebsa110.c b/arch/arm/kernel/leds-ebsa110.c index 7b2c886ef..17cb356e4 100644 --- a/arch/arm/kernel/leds-ebsa110.c +++ b/arch/arm/kernel/leds-ebsa110.c @@ -1,23 +1,32 @@ /* - * arch/arm/kernel/leds-ebsa110.c + * linux/arch/arm/kernel/leds-ebsa110.c * - * Copyright (C) 1998 Russell King + * Copyright (C) 1998 Russell King * - * EBSA-110 LED control routines. We use the led as follows: + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * - * - Red - toggles state every 50 timer interrupts + * EBSA-110 LED control routines. We use the led as follows: + * + * - Red - toggles state every 50 timer interrupts */ #include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/init.h> #include <asm/hardware.h> #include <asm/leds.h> #include <asm/system.h> +#include <asm/mach-types.h> + +static spinlock_t leds_lock; static void ebsa110_leds_event(led_event_t ledevt) { unsigned long flags; - save_flags_cli(flags); + spin_lock_irqsave(&leds_lock, flags); switch(ledevt) { case led_timer: @@ -28,9 +37,15 @@ static void ebsa110_leds_event(led_event_t ledevt) break; } - restore_flags(flags); + spin_unlock_irqrestore(&leds_lock, flags); } -void (*leds_event)(led_event_t) = ebsa110_leds_event; +static int __init leds_init(void) +{ + if (machine_is_ebsa110()) + leds_event = ebsa110_leds_event; + + return 0; +} -EXPORT_SYMBOL(leds_event); +__initcall(leds_init); diff --git a/arch/arm/kernel/leds-ftvpci.c b/arch/arm/kernel/leds-ftvpci.c new file mode 100644 index 000000000..a1cf22dd8 --- /dev/null +++ b/arch/arm/kernel/leds-ftvpci.c @@ -0,0 +1,31 @@ +/* + * linux/arch/arm/kernel/leds-ftvpci.c + * + * Copyright (C) 1999 FutureTV Labs Ltd + */ + +#include <linux/module.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> +#include <asm/io.h> + +static void ftvpci_leds_event(led_event_t ledevt) +{ + static int led_state = 0; + + switch(ledevt) { + case led_timer: + led_state ^= 1; + raw_writeb(0x1a | led_state, INTCONT_BASE); + break; + + default: + break; + } +} + +void (*leds_event)(led_event_t) = ftvpci_leds_event; + +EXPORT_SYMBOL(leds_event); diff --git a/arch/arm/kernel/oldlatches.c b/arch/arm/kernel/oldlatches.c index 91b9e5d62..fe40c58b5 100644 --- a/arch/arm/kernel/oldlatches.c +++ b/arch/arm/kernel/oldlatches.c @@ -1,7 +1,14 @@ -/* Support for the latches on the old Archimedes which control the floppy, - * hard disc and printer +/* + * linux/arch/arm/kernel/oldlatches.c * - * (c) David Alan Gilbert 1995/1996,2000 + * Copyright (C) David Alan Gilbert 1995/1996,2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Support for the latches on the old Archimedes which control the floppy, + * hard disc and printer */ #include <linux/module.h> #include <linux/kernel.h> diff --git a/arch/arm/kernel/plx90x0.c b/arch/arm/kernel/plx90x0.c new file mode 100644 index 000000000..47ec9a8d2 --- /dev/null +++ b/arch/arm/kernel/plx90x0.c @@ -0,0 +1,198 @@ +/* + * Driver for PLX Technology PCI9000-series host bridge. + * + * Copyright (C) 1997, 1998, 1999, 2000 FutureTV Labs Ltd + */ + +/* + * 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 <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/sched.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/ptrace.h> +#include <asm/irq.h> +#include <asm/mach/pci.h> + +/* + * Since the following functions are all very similar, the common parts + * are pulled out into these macros. + */ + +#define PLX_CLEAR_CONFIG \ + __raw_writel(0, PLX_BASE + 0xac); \ + local_irq_restore(flags); } + +#define PLX_SET_CONFIG \ + { unsigned long flags; \ + local_irq_save(flags); \ + __raw_writel((1<<31 | (dev->bus->number << 16) \ + | (dev->devfn << 8) | (where & ~3) \ + | ((dev->bus->number == 0)?0:1)), PLX_BASE + 0xac); \ + +#define PLX_CONFIG_WRITE(size) \ + PLX_SET_CONFIG \ + __raw_write##size(value, PCIO_BASE + (where & 3)); \ + if (__raw_readw(PLX_BASE + 0x6) & 0x2000) \ + __raw_writew(0x2000, PLX_BASE + 0x6); \ + PLX_CLEAR_CONFIG \ + return PCIBIOS_SUCCESSFUL; + +#define PLX_CONFIG_READ(size) \ + PLX_SET_CONFIG \ + *value = __raw_read##size(PCIO_BASE + (where & 3)); \ + if (__raw_readw(PLX_BASE + 0x6) & 0x2000) { \ + __raw_writew(0x2000, PLX_BASE + 0x6); \ + *value = 0xffffffffUL; \ + } \ + PLX_CLEAR_CONFIG \ + return PCIBIOS_SUCCESSFUL; + +/* Configuration space access routines */ + +static int +plx90x0_read_config_byte (struct pci_dev *dev, + int where, u8 *value) +{ + PLX_CONFIG_READ(b) +} + +static int +plx90x0_read_config_word (struct pci_dev *dev, + int where, u16 *value) +{ + PLX_CONFIG_READ(w) +} + +static int +plx90x0_read_config_dword (struct pci_dev *dev, + int where, u32 *value) +{ + PLX_CONFIG_READ(l) +} + +static int +plx90x0_write_config_byte (struct pci_dev *dev, + int where, u8 value) +{ + PLX_CONFIG_WRITE(b) +} + +static int +plx90x0_write_config_word (struct pci_dev *dev, + int where, u16 value) +{ + PLX_CONFIG_WRITE(w) +} + +static int +plx90x0_write_config_dword (struct pci_dev *dev, + int where, u32 value) +{ + PLX_CONFIG_WRITE(l) +} + +static void +plx_syserr_handler(int irq, void *handle, struct pt_regs *regs) +{ + printk("PLX90x0: machine check %04x (pc=%08lx)\n", + readw(PLX_BASE + 6), regs->ARM_pc); + __raw_writew(0xf000, PLX_BASE + 6); +} + +static struct pci_ops +plx90x0_ops = +{ + plx90x0_read_config_byte, + plx90x0_read_config_word, + plx90x0_read_config_dword, + plx90x0_write_config_byte, + plx90x0_write_config_word, + plx90x0_write_config_dword, +}; + +/* + * Initialise the PCI system. + */ + +void __init +plx90x0_init(struct arm_sysdata *sysdata) +{ + static const unsigned long int base = PLX_BASE; + char *what; + unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET); + unsigned int pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; + + /* Have a sniff around and see which PLX device is present. */ + unsigned long id = __raw_readl(base + 0xf0); + +#if 0 + /* This check was a good idea, but can fail. The PLX9060 puts no + default value in these registers unless NB# is asserted (which it + isn't on these cards). */ + if ((id & 0xffff) != PCI_VENDOR_ID_PLX) + return; /* Nothing found */ +#endif + + /* Found one - now work out what it is. */ + switch (id >> 16) { + case 0: /* PCI_DEVICE_ID_PLX_9060 */ + what = "PCI9060"; + break; + case PCI_DEVICE_ID_PLX_9060ES: + what = "PCI9060ES"; + break; + case PCI_DEVICE_ID_PLX_9060SD: + what = "PCI9060SD"; /* uhuhh.. */ + break; + case PCI_DEVICE_ID_PLX_9080: + what = "PCI9080"; + break; + default: + printk("PCI: Unknown PLX device %04lx found -- ignored.\n", + id >> 16); + return; + } + + printk("PCI: PLX Technology %s host bridge found.\n", what); + + /* Now set it up for both master and slave accesses. */ + __raw_writel(0xffff0147, base + 0x4); + __raw_writeb(32, base + 0xd); + __raw_writel(0x8 | bar, base + 0x18); + __raw_writel(0xf8000008, base + 0x80); + __raw_writel(0x40000001, base + 0x84); + __raw_writel(0, base + 0x88); + __raw_writel(0, base + 0x8c); + __raw_writel(0x11, base + 0x94); + __raw_writel(0xC3 + (4 << 28) + + (8 << 11) + (1 << 10) + + (1 << 24), base + 0x98); + __raw_writel(0xC0000000, base + 0x9c); + __raw_writel(PLX_MEM_START, base + 0xa0); + __raw_writel(PLX_IO_START, base + 0xa4); + __raw_writel(0x3, base + 0xa8); + __raw_writel(0, base + 0xac); + __raw_writel(0x10001, base + 0xe8); + __raw_writel(0x8000767e, base + 0xec); + + request_irq(IRQ_SYSERR, plx_syserr_handler, 0, + "system error", NULL); + + pci_scan_bus(0, &plx90x0_ops, sysdata); + + pci_cmd |= sysdata->bus[0].features; + + printk("PCI: Fast back to back transfers %sabled\n", + (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ? + "en" : "dis"); +} diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 478810936..9f50ab6fd 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -3,8 +3,11 @@ * * Copyright (C) 1996-2000 Russell King - Converted to ARM. * Origional Copyright (C) 1995 Linus Torvalds + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <stdarg.h> #include <linux/config.h> @@ -173,10 +176,11 @@ void show_regs(struct pt_regs * regs) flags & CC_Z_BIT ? 'Z' : 'z', flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v'); - printk(" IRQs %s FIQs %s Mode %s Segment %s\n", + printk(" IRQs %s FIQs %s Mode %s%s Segment %s\n", interrupts_enabled(regs) ? "on" : "off", fast_interrupts_enabled(regs) ? "on" : "off", processor_modes[processor_mode(regs)], + thumb_mode(regs) ? " (T)" : "", get_fs() == get_ds() ? "kernel" : "user"); #if defined(CONFIG_CPU_32) { @@ -280,8 +284,8 @@ void exit_thread(void) void flush_thread(void) { - memset(¤t->thread.debug, 0, sizeof(current->thread.debug)); - memset(¤t->thread.fpstate, 0, sizeof(current->thread.fpstate)); + memset(¤t->thread.debug, 0, sizeof(struct debug_info)); + memset(¤t->thread.fpstate, 0, sizeof(union fp_state)); current->used_math = 0; current->flags &= ~PF_USEDFPU; } @@ -291,6 +295,7 @@ void release_thread(struct task_struct *dead_task) } int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, + unsigned long unused, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; @@ -326,19 +331,21 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp) */ void dump_thread(struct pt_regs * regs, struct user * dump) { + struct task_struct *tsk = current; + dump->magic = CMAGIC; - dump->start_code = current->mm->start_code; + dump->start_code = tsk->mm->start_code; dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1); - dump->u_tsize = (current->mm->end_code - current->mm->start_code) >> PAGE_SHIFT; - dump->u_dsize = (current->mm->brk - current->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; + dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT; + dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; dump->u_ssize = 0; - dump->u_debugreg[0] = current->thread.debug.bp[0].address; - dump->u_debugreg[1] = current->thread.debug.bp[1].address; - dump->u_debugreg[2] = current->thread.debug.bp[0].insn; - dump->u_debugreg[3] = current->thread.debug.bp[1].insn; - dump->u_debugreg[4] = current->thread.debug.nsaved; + dump->u_debugreg[0] = tsk->thread.debug.bp[0].address; + dump->u_debugreg[1] = tsk->thread.debug.bp[1].address; + dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn; + dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn; + dump->u_debugreg[4] = tsk->thread.debug.nsaved; if (dump->start_stack < 0x04000000) dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT; diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index e45e03fcb..2d20c9271 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -1,8 +1,14 @@ -/* ptrace.c */ -/* By Ross Biro 1/23/92 */ -/* edited by Linus Torvalds */ -/* edited for ARM by Russell King */ - +/* + * linux/arch/arm/kernel/ptrace.c + * + * By Ross Biro 1/23/92 + * edited by Linus Torvalds + * ARM modifications Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> @@ -61,9 +67,18 @@ static inline long get_stack_long(struct task_struct *task, int offset) static inline int put_stack_long(struct task_struct *task, int offset, long data) { - get_user_regs(task)->uregs[offset] = data; + struct pt_regs newregs, *regs = get_user_regs(task); + int ret = -EINVAL; + + newregs = *regs; + newregs.uregs[offset] = data; + + if (valid_user_regs(&newregs)) { + regs->uregs[offset] = data; + ret = 0; + } - return 0; + return ret; } static inline int @@ -406,7 +421,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) break; - if (addr < sizeof (struct pt_regs)) + if (addr < sizeof(struct pt_regs)) ret = put_stack_long(child, (int)addr >> 2, data); break; @@ -499,12 +514,19 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat * Set all gp regs in the child. */ case PTRACE_SETREGS: { - struct pt_regs *regs = get_user_regs(child); - - ret = 0; - if (copy_from_user(regs, (void *)data, - sizeof(struct pt_regs))) - ret = -EFAULT; + struct pt_regs newregs; + + ret = -EFAULT; + if (copy_from_user(&newregs, (void *)data, + sizeof(struct pt_regs)) == 0) { + struct pt_regs *regs = get_user_regs(child); + + ret = -EINVAL; + if (valid_user_regs(&newregs)) { + *regs = newregs; + ret = 0; + } + } break; } diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h index feae0acd8..ec1789aa4 100644 --- a/arch/arm/kernel/ptrace.h +++ b/arch/arm/kernel/ptrace.h @@ -1,3 +1,12 @@ +/* + * linux/arch/arm/kernel/ptrace.h + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ extern void __ptrace_cancel_bpt(struct task_struct *); extern int ptrace_set_bpt(struct task_struct *); diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c index d29f8cf1f..e01a6417e 100644 --- a/arch/arm/kernel/semaphore.c +++ b/arch/arm/kernel/semaphore.c @@ -1,11 +1,15 @@ /* - * ARM semaphore implementation, taken from + * ARM semaphore implementation, taken from * - * i386 semaphore implementation. + * i386 semaphore implementation. * - * (C) Copyright 1999 Linus Torvalds + * (C) Copyright 1999 Linus Torvalds * - * Modified for ARM by Russell King + * Modified for ARM by Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> #include <linux/sched.h> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index c20ffab21..9a917b171 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -2,6 +2,10 @@ * linux/arch/arm/kernel/setup.c * * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> #include <linux/kernel.h> @@ -21,7 +25,7 @@ #include <asm/setup.h> #include <asm/mach-types.h> -#include "arch.h" +#include <asm/mach/arch.h> #ifndef MEM_SIZE #define MEM_SIZE (16*1024*1024) @@ -31,7 +35,7 @@ #define CONFIG_CMDLINE "" #endif -extern void paging_init(struct meminfo *); +extern void paging_init(struct meminfo *, struct machine_desc *desc); extern void bootmem_init(struct meminfo *); extern void reboot_setup(char *str); extern void disable_hlt(void); @@ -163,7 +167,7 @@ static struct machine_desc * __init setup_architecture(unsigned int nr) printk("Architecture: %s\n", list->name); if (compat) - printk(KERN_WARNING "Using compatability code " + printk(KERN_WARNING "Using compatibility code " "scheduled for removal in v%d.%d.%d\n", compat >> 24, (compat >> 12) & 0x3ff, compat & 0x3ff); @@ -378,7 +382,7 @@ void __init setup_arch(char **cmdline_p) saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; parse_cmdline(&meminfo, cmdline_p, from); bootmem_init(&meminfo); - paging_init(&meminfo); + paging_init(&meminfo, mdesc); request_standard_resources(&meminfo, mdesc); #ifdef CONFIG_VT diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 5c2e240b7..1af2abd84 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -2,8 +2,11 @@ * linux/arch/arm/kernel/signal.c * * Copyright (C) 1995, 1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/config.h> #include <linux/sched.h> #include <linux/mm.h> @@ -587,7 +590,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 6d49e1427..36bbf3ac8 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -1,14 +1,17 @@ /* - * linux/arch/arm/kernel/sys_arm.c + * linux/arch/arm/kernel/sys_arm.c * - * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c - * Copyright (C) 1995, 1996 Russell King. - * - * This file contains various random system calls that - * have a non-standard calling sequence on the Linux/arm - * platform. + * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c + * Copyright (C) 1995, 1996 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file contains various random system calls that + * have a non-standard calling sequence on the Linux/arm + * platform. */ - #include <linux/errno.h> #include <linux/sched.h> #include <linux/malloc.h> @@ -203,7 +206,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, */ asmlinkage int sys_fork(struct pt_regs *regs) { - return do_fork(SIGCHLD, regs->ARM_sp, regs); + return do_fork(SIGCHLD, regs->ARM_sp, regs, 0); } /* Clone a task - this clones the calling program thread. @@ -213,12 +216,12 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct { if (!newsp) newsp = regs->ARM_sp; - return do_fork(clone_flags, newsp, regs); + return do_fork(clone_flags, newsp, regs, 0); } asmlinkage int sys_vfork(struct pt_regs *regs) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs); + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0); } /* sys_execve() executes a new program. diff --git a/arch/arm/kernel/time-acorn.c b/arch/arm/kernel/time-acorn.c index 8a7d964fc..05de01e85 100644 --- a/arch/arm/kernel/time-acorn.c +++ b/arch/arm/kernel/time-acorn.c @@ -1,12 +1,16 @@ /* - * linux/arch/arm/kernel/time-acorn.c + * linux/arch/arm/kernel/time-acorn.c * - * Copyright (c) 1996-2000 Russell King. + * Copyright (c) 1996-2000 Russell King. * - * Changelog: - * 24-Sep-1996 RMK Created - * 10-Oct-1996 RMK Brought up to date with arch-sa110eval - * 04-Dec-1997 RMK Updated for new arch/arm/time.c + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * 24-Sep-1996 RMK Created + * 10-Oct-1996 RMK Brought up to date with arch-sa110eval + * 04-Dec-1997 RMK Updated for new arch/arm/time.c */ #include <linux/sched.h> #include <linux/interrupt.h> @@ -14,8 +18,8 @@ #include <asm/hardware.h> #include <asm/io.h> -#include <asm/ioc.h> #include <asm/irq.h> +#include <asm/hardware/ioc.h> extern unsigned long (*gettimeoffset)(void); diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index da437639f..926cdff2f 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -4,15 +4,20 @@ * Copyright (C) 1991, 1992, 1995 Linus Torvalds * Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King * - * This file contains the ARM-specific time handling details: - * reading the RTC at bootup, etc... + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * - * 1994-07-02 Alan Modra - * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime - * 1998-12-20 Updated NTP code according to technical memorandum Jan '96 - * "A Kernel Model for Precision Timekeeping" by Dave Mills + * This file contains the ARM-specific time handling details: + * reading the RTC at bootup, etc... + * + * 1994-07-02 Alan Modra + * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime + * 1998-12-20 Updated NTP code according to technical memorandum Jan '96 + * "A Kernel Model for Precision Timekeeping" by Dave Mills */ #include <linux/config.h> +#include <linux/module.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/interrupt.h> @@ -64,37 +69,6 @@ static unsigned long dummy_gettimeoffset(void) */ unsigned long (*gettimeoffset)(void) = dummy_gettimeoffset; -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -unsigned long -mktime(unsigned int year, unsigned int mon, unsigned int day, - unsigned int hour, unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - /* * Handle kernel profile stuff... */ @@ -151,6 +125,16 @@ static inline void do_set_rtc(void) #include <asm/leds.h> +static void dummy_leds_event(led_event_t evt) +{ +} + +void (*leds_event)(led_event_t) = dummy_leds_event; + +#ifdef CONFIG_MODULES +EXPORT_SYMBOL(leds_event); +#endif + static void do_leds(void) { #ifdef CONFIG_LEDS_CPU @@ -234,7 +218,7 @@ void do_settimeofday(struct timeval *tv) } static struct irqaction timer_irq = { - NULL, 0, 0, "timer", NULL, NULL + name: "timer", }; /* diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 197107138..8e8e3675f 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -3,12 +3,14 @@ * * Copyright (C) 1995, 1996 Russell King * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds - */ - -/* - * 'traps.c' handles hardware exceptions after we have saved some state in - * 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably - * kill the offending process. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 'traps.c' handles hardware exceptions after we have saved some state in + * 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably + * kill the offending process. */ #include <linux/config.h> #include <linux/types.h> @@ -314,7 +316,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) case 2: /* sys_cacheflush */ #ifdef CONFIG_CPU_32 /* r0 = start, r1 = end, r2 = flags */ - cpu_flush_cache_area(regs->ARM_r0, regs->ARM_r1, 1); + cpu_cache_clean_invalidate_range(regs->ARM_r0, regs->ARM_r1, 1); #endif break; diff --git a/arch/arm/kernel/via82c505.c b/arch/arm/kernel/via82c505.c new file mode 100644 index 000000000..42a2bb448 --- /dev/null +++ b/arch/arm/kernel/via82c505.c @@ -0,0 +1,186 @@ +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/ptrace.h> +#include <linux/interrupt.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/ioport.h> + +#include <asm/io.h> +#include <asm/system.h> + +#include <asm/mach/pci.h> + +#define MAX_SLOTS 7 + +#define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3)) + +static int +via82c505_read_config_byte(struct pci_dev *dev, int where, u8 *value) +{ + outl(CONFIG_CMD(dev,where),0xCF8); + *value=inb(0xCFC + (where&3)); + return PCIBIOS_SUCCESSFUL; +} + +static int +via82c505_read_config_word(struct pci_dev *dev, int where, u16 *value) +{ + outl(CONFIG_CMD(dev,where),0xCF8); + *value=inw(0xCFC + (where&2)); + return PCIBIOS_SUCCESSFUL; +} + +static int +via82c505_read_config_dword(struct pci_dev *dev, int where, u32 *value) +{ + outl(CONFIG_CMD(dev,where),0xCF8); + *value=inl(0xCFC); + return PCIBIOS_SUCCESSFUL; +} + +static int +via82c505_write_config_byte(struct pci_dev *dev, int where, u8 value) +{ + outl(CONFIG_CMD(dev,where),0xCF8); + outb(value, 0xCFC + (where&3)); + return PCIBIOS_SUCCESSFUL; +} + +static int +via82c505_write_config_word(struct pci_dev *dev, int where, u16 value) +{ + outl(CONFIG_CMD(dev,where),0xCF8); + outw(value, 0xCFC + (where&2)); + return PCIBIOS_SUCCESSFUL; +} + +static int +via82c505_write_config_dword(struct pci_dev *dev, int where, u32 value) +{ + outl(CONFIG_CMD(dev,where),0xCF8); + outl(value, 0xCFC); + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops via82c505_ops = { + via82c505_read_config_byte, + via82c505_read_config_word, + via82c505_read_config_dword, + via82c505_write_config_byte, + via82c505_write_config_word, + via82c505_write_config_dword, +}; + +#ifdef CONFIG_ARCH_SHARK + +static char size_wanted = 0; + +static int +dummy_read_config_byte(struct pci_dev *dev, int where, u8 *value) +{ + *value=0; + return PCIBIOS_SUCCESSFUL; +} + +static int +dummy_read_config_word(struct pci_dev *dev, int where, u16 *value) +{ + *value=0; + return PCIBIOS_SUCCESSFUL; +} + +static int +dummy_read_config_dword(struct pci_dev *dev, int where, u32 *value) +{ + if (dev->devfn != 0) *value = 0; + else + switch(where) { + case PCI_VENDOR_ID: + *value = PCI_VENDOR_ID_INTERG | PCI_DEVICE_ID_INTERG_2010 << 16; + break; + case PCI_CLASS_REVISION: + *value = PCI_CLASS_DISPLAY_VGA << 16; + break; + case PCI_BASE_ADDRESS_0: + if (size_wanted) { + /* 0x00900000 bytes long */ + *value = 0xff700000; + size_wanted = 0; + } else { + *value = FB_START; + } + break; + case PCI_INTERRUPT_LINE: + *value = 6; + break; + default: + *value=0; + } + return PCIBIOS_SUCCESSFUL; +} + +static int +dummy_write_config_byte(struct pci_dev *dev, int where, u8 value) +{ + return PCIBIOS_SUCCESSFUL; +} + +static int +dummy_write_config_word(struct pci_dev *dev, int where, u16 value) +{ + return PCIBIOS_SUCCESSFUL; +} + +static int +dummy_write_config_dword(struct pci_dev *dev, int where, u32 value) +{ + if ((dev->devfn == 0) && (where == PCI_BASE_ADDRESS_0) && (value == 0xffffffff)) + size_wanted = 1; + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops dummy_ops = { + dummy_read_config_byte, + dummy_read_config_word, + dummy_read_config_dword, + dummy_write_config_byte, + dummy_write_config_word, + dummy_write_config_dword, +}; +#endif + +void __init via82c505_init(struct arm_pci_sysdata *sysdata) +{ + unsigned int pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; + struct pci_dev *dev; + struct pci_bus *bus; + + printk(KERN_DEBUG "PCI: VIA 82c505\n"); + request_region(0xA8,2,"via config"); + request_region(0xCF8,8,"pci config"); + + /* Enable compatible Mode */ + outb(0x96,0xA8); + outb(0x18,0xA9); + outb(0x93,0xA8); + outb(0xd0,0xA9); + + pci_scan_bus(0, &via82c505_ops, sysdata); + + pci_cmd |= sysdata->bus[0].features; + + printk("PCI: Fast back to back transfers %sabled\n", + (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); + +#ifdef CONFIG_ARCH_SHARK + /* + * Initialize a fake pci-bus number 1 for the CyberPro + * on the vlbus + */ + bus = pci_scan_bus(1, &dummy_ops, sysdata); +#endif +} diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index cfa371d5e..b7e29ca55 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -9,9 +9,9 @@ USE_STANDARD_AS_RULE := true L_TARGET := lib.a L_OBJS := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \ csumpartialcopyuser.o clearbit.o copy_page.o findbit.o \ - memchr.o memcpy.o memset.o memzero.o setbit.o strchr.o \ - strrchr.o testchangebit.o testclearbit.o testsetbit.o \ - uaccess.o + memchr.o memcpy.o memset.o memzero.o setbit.o \ + strncpy_from_user.o strnlen_user.o strchr.o strrchr.o \ + testchangebit.o testclearbit.o testsetbit.o uaccess.o O_TARGET := lib.o O_OBJS := backtrace.o delay.o @@ -25,6 +25,7 @@ L_OBJS_l7200 := io-acorn.o L_OBJS_nexuspci := io-footbridge.o L_OBJS_sa1100 := io-footbridge.o L_OBJS_shark := io-shark.o +L_OBJS_integrator := io-shark.o ifeq ($(PROCESSOR),armo) L_OBJS += uaccess-armo.o diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S index e871f2615..5fe3c066e 100644 --- a/arch/arm/lib/backtrace.S +++ b/arch/arm/lib/backtrace.S @@ -1,7 +1,11 @@ /* - * linux/arch/arm/lib/backtrace.S + * linux/arch/arm/lib/backtrace.S * - * Copyright (C) 1995, 1996 Russell King + * Copyright (C) 1995, 1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> #include <linux/linkage.h> diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S index adb847670..6feb62783 100644 --- a/arch/arm/lib/changebit.S +++ b/arch/arm/lib/changebit.S @@ -1,9 +1,12 @@ /* - * linux/arch/arm/lib/changebit.S + * linux/arch/arm/lib/changebit.S * - * Copyright (C) 1995-1996 Russell King + * Copyright (C) 1995-1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/linkage.h> #include <asm/assembler.h> .text diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S index d63947520..225aa6fb9 100644 --- a/arch/arm/lib/clearbit.S +++ b/arch/arm/lib/clearbit.S @@ -1,9 +1,12 @@ /* - * linux/arch/arm/lib/clearbit.S + * linux/arch/arm/lib/clearbit.S * - * Copyright (C) 1995-1996 Russell King + * Copyright (C) 1995-1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/linkage.h> #include <asm/assembler.h> .text diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S index 16c43268a..d7cf6fe45 100644 --- a/arch/arm/lib/copy_page.S +++ b/arch/arm/lib/copy_page.S @@ -1,35 +1,38 @@ /* - * linux/arch/arm/lib/copypage.S + * linux/arch/arm/lib/copypage.S * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-1999 Russell King * - * ASM optimised string functions + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * + * ASM optimised string functions */ #include <linux/linkage.h> #include <asm/assembler.h> #include "constants.h" - .text + .text + .align 5 /* * StrongARM optimised copy_page routine - * now 1.72bytes/cycle, was 1.60 bytes/cycle - * (50MHz bus -> 86MB/s) + * now 1.78bytes/cycle, was 1.60 bytes/cycle (50MHz bus -> 89MB/s) + * Note that we probably achieve closer to the 100MB/s target with + * the core clock switching. */ - ENTRY(copy_page) stmfd sp!, {r4, lr} @ 2 mov r2, #PAGE_SZ/64 @ 1 -1: ldmia r1!, {r3, r4, ip, lr} @ 4 - subs r2, r2, #1 @ 1 - stmia r0!, {r3, r4, ip, lr} @ 4 ldmia r1!, {r3, r4, ip, lr} @ 4+1 - stmia r0!, {r3, r4, ip, lr} @ 4 +1: stmia r0!, {r3, r4, ip, lr} @ 4 ldmia r1!, {r3, r4, ip, lr} @ 4+1 stmia r0!, {r3, r4, ip, lr} @ 4 ldmia r1!, {r3, r4, ip, lr} @ 4+1 stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4 + subs r2, r2, #1 @ 1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmneia r1!, {r3, r4, ip, lr} @ 4 bne 1b @ 1 LOADREGS(fd, sp!, {r4, pc}) @ 3 - - diff --git a/arch/arm/lib/csumipv6.S b/arch/arm/lib/csumipv6.S index 76e7d26d8..7065a20ee 100644 --- a/arch/arm/lib/csumipv6.S +++ b/arch/arm/lib/csumipv6.S @@ -1,7 +1,11 @@ /* - * linux/arch/arm/lib/csumipv6.S + * linux/arch/arm/lib/csumipv6.S * - * Copyright (C) 1995-1998 Russell King + * Copyright (C) 1995-1998 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/linkage.h> #include <asm/assembler.h> diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S index 2406dfb38..dea2c389c 100644 --- a/arch/arm/lib/csumpartial.S +++ b/arch/arm/lib/csumpartial.S @@ -1,7 +1,11 @@ /* - * linux/arch/arm/lib/csumpartial.S + * linux/arch/arm/lib/csumpartial.S * - * Copyright (C) 1995-1998 Russell King + * Copyright (C) 1995-1998 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/linkage.h> #include <asm/assembler.h> diff --git a/arch/arm/lib/csumpartialcopy.S b/arch/arm/lib/csumpartialcopy.S index fc52662a8..005bc9332 100644 --- a/arch/arm/lib/csumpartialcopy.S +++ b/arch/arm/lib/csumpartialcopy.S @@ -1,7 +1,11 @@ /* - * linux/arch/arm/lib/csumpartialcopy.S + * linux/arch/arm/lib/csumpartialcopy.S * - * Copyright (C) 1995-1998 Russell King + * Copyright (C) 1995-1998 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/linkage.h> #include <asm/assembler.h> diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S index cde500440..3799ccaec 100644 --- a/arch/arm/lib/csumpartialcopyuser.S +++ b/arch/arm/lib/csumpartialcopyuser.S @@ -1,7 +1,11 @@ /* - * linux/arch/arm/lib/csumpartialcopyuser.S + * linux/arch/arm/lib/csumpartialcopyuser.S * - * Copyright (C) 1995-1998 Russell King + * Copyright (C) 1995-1998 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> #include <linux/linkage.h> @@ -396,6 +400,12 @@ ENTRY(csum_partial_copy_from_user) mov r4, r4, lsr #8 b .exit +/* + * FIXME: minor buglet here + * We don't return the checksum for the data present in the buffer. To do + * so properly, we would have to add in whatever registers were loaded before + * the fault, which, with the current asm above is not predictable. + */ #if defined(CONFIG_CPU_32) .section .fixup,"ax" #endif diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S index 72dab5a95..caf8ec1dc 100644 --- a/arch/arm/lib/delay.S +++ b/arch/arm/lib/delay.S @@ -1,7 +1,11 @@ /* - * linux/arch/arm/lib/delay.S + * linux/arch/arm/lib/delay.S * - * Copyright (C) 1995, 1996 Russell King + * Copyright (C) 1995, 1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/linkage.h> #include <asm/assembler.h> @@ -40,4 +44,3 @@ ENTRY(__delay) subs r0, r0, #1 bcs SYMBOL_NAME(__delay) RETINSTR(mov,pc,lr) - diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S index 5b570f199..279230292 100644 --- a/arch/arm/lib/findbit.S +++ b/arch/arm/lib/findbit.S @@ -1,9 +1,12 @@ /* - * linux/arch/arm/lib/findbit.S + * linux/arch/arm/lib/findbit.S * - * Copyright (C) 1995-2000 Russell King + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/linkage.h> #include <asm/assembler.h> .text diff --git a/arch/arm/lib/floppydma.S b/arch/arm/lib/floppydma.S index 778d3e574..9073e54ef 100644 --- a/arch/arm/lib/floppydma.S +++ b/arch/arm/lib/floppydma.S @@ -1,7 +1,11 @@ /* - * linux/arch/arm/lib/floppydma.S + * linux/arch/arm/lib/floppydma.S * - * Copyright (C) 1995, 1996 Russell King + * Copyright (C) 1995, 1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/linkage.h> #include <asm/assembler.h> diff --git a/arch/arm/lib/getconsdata.c b/arch/arm/lib/getconsdata.c index aa5efa1cd..ee8040be7 100644 --- a/arch/arm/lib/getconsdata.c +++ b/arch/arm/lib/getconsdata.c @@ -1,7 +1,11 @@ /* - * linux/arch/arm/lib/getconsdata.c + * linux/arch/arm/lib/getconsdata.c * - * Copyright (C) 1995-2000 Russell King + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> #include <linux/sched.h> diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/lib/io-acorn.S index bf2dd6333..bc40496ac 100644 --- a/arch/arm/lib/io-acorn.S +++ b/arch/arm/lib/io-acorn.S @@ -1,7 +1,11 @@ /* - * linux/arch/arm/lib/io.S + * linux/arch/arm/lib/io-acorn.S * - * Copyright (C) 1995, 1996 Russell King + * Copyright (C) 1995, 1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> /* for CONFIG_CPU_nn */ #include <linux/linkage.h> diff --git a/arch/arm/lib/io-ebsa110.S b/arch/arm/lib/io-ebsa110.S index b29276ff7..b1c507886 100644 --- a/arch/arm/lib/io-ebsa110.S +++ b/arch/arm/lib/io-ebsa110.S @@ -1,7 +1,11 @@ /* - * linux/arch/arm/lib/io-ebsa.S + * linux/arch/arm/lib/io-ebsa.S * - * Copyright (C) 1995, 1996 Russell King + * Copyright (C) 1995, 1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/linkage.h> #include <asm/assembler.h> diff --git a/arch/arm/lib/io-shark.c b/arch/arm/lib/io-shark.c index 41595bc6f..b68faa700 100644 --- a/arch/arm/lib/io-shark.c +++ b/arch/arm/lib/io-shark.c @@ -1,11 +1,15 @@ /* - * linux/arch/arm/lib/io-shark.c + * linux/arch/arm/lib/io-shark.c * - * by Alexander.Schulz@stud.uni-karlsruhe.de + * by Alexander.Schulz@stud.uni-karlsruhe.de * * derived from: * linux/arch/arm/lib/io-ebsa.S * Copyright (C) 1995, 1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/kernel.h> diff --git a/arch/arm/lib/memchr.S b/arch/arm/lib/memchr.S index d52abe57f..4eed74a7e 100644 --- a/arch/arm/lib/memchr.S +++ b/arch/arm/lib/memchr.S @@ -1,24 +1,25 @@ /* - * linux/arch/arm/lib/memchr.S + * linux/arch/arm/lib/memchr.S * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-2000 Russell King * - * ASM optimised string functions + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * + * ASM optimised string functions */ #include <linux/linkage.h> #include <asm/assembler.h> -#include "constants.h" - .text + .text + .align 5 ENTRY(memchr) - str lr, [sp, #-4]! -1: ldrb r3, [r0], #1 - teq r3, r1 - beq 2f - subs r2, r2, #1 - bpl 1b -2: movne r0, #0 - subeq r0, r0, #1 - LOADREGS(fd, sp!, {pc}) - +1: ldrb r3, [r0], #1 + teq r3, r1 + beq 2f + subs r2, r2, #1 + bpl 1b +2: movne r0, #0 + subeq r0, r0, #1 + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index ae5307d4b..e652b5276 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S @@ -1,10 +1,13 @@ /* - * linux/arch/arm/lib/memcpy.S + * linux/arch/arm/lib/memcpy.S * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-1999 Russell King * - * ASM optimised string functions + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * + * ASM optimised string functions */ #include <linux/linkage.h> #include <asm/assembler.h> @@ -314,5 +317,3 @@ ENTRY(memmove) b 24b .align - - diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S index b7202e867..a1795f599 100644 --- a/arch/arm/lib/memset.S +++ b/arch/arm/lib/memset.S @@ -1,88 +1,80 @@ /* - * linux/arch/arm/lib/memset.S + * linux/arch/arm/lib/memset.S * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-2000 Russell King * - * ASM optimised string functions + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * + * ASM optimised string functions */ #include <linux/linkage.h> #include <asm/assembler.h> -#include "constants.h" - .text - .align 5 -ENTRY(memset) - mov r3, r0 - cmp r2, #16 - blt 6f - ands ip, r3, #3 - beq 1f - cmp ip, #2 - strltb r1, [r3], #1 @ Align destination - strleb r1, [r3], #1 - strb r1, [r3], #1 - rsb ip, ip, #4 - sub r2, r2, ip -1: orr r1, r1, r1, lsl #8 - orr r1, r1, r1, lsl #16 - cmp r2, #256 - blt 4f - stmfd sp!, {r4, r5, lr} - mov r4, r1 - mov r5, r1 - mov lr, r1 - mov ip, r2, lsr #6 - sub r2, r2, ip, lsl #6 -2: stmia r3!, {r1, r4, r5, lr} @ 64 bytes at a time. - stmia r3!, {r1, r4, r5, lr} - stmia r3!, {r1, r4, r5, lr} - stmia r3!, {r1, r4, r5, lr} - subs ip, ip, #1 - bne 2b - teq r2, #0 - LOADREGS(eqfd, sp!, {r4, r5, pc}) @ Now <64 bytes to go. - tst r2, #32 - stmneia r3!, {r1, r4, r5, lr} - stmneia r3!, {r1, r4, r5, lr} - tst r2, #16 - stmneia r3!, {r1, r4, r5, lr} - ldmia sp!, {r4, r5} -3: tst r2, #8 - stmneia r3!, {r1, lr} - tst r2, #4 - strne r1, [r3], #4 - tst r2, #2 - strneb r1, [r3], #1 - strneb r1, [r3], #1 - tst r2, #1 - strneb r1, [r3], #1 - LOADREGS(fd, sp!, {pc}) + .text + .align 5 + .word 0 -4: movs ip, r2, lsr #3 - beq 3b - sub r2, r2, ip, lsl #3 - str lr, [sp, #-4]! - mov lr, r1 - subs ip, ip, #4 -5: stmgeia r3!, {r1, lr} - stmgeia r3!, {r1, lr} - stmgeia r3!, {r1, lr} - stmgeia r3!, {r1, lr} - subges ip, ip, #4 - bge 5b - tst ip, #2 - stmneia r3!, {r1, lr} - stmneia r3!, {r1, lr} - tst ip, #1 - stmneia r3!, {r1, lr} - teq r2, #0 - LOADREGS(eqfd, sp!, {pc}) - b 3b +1: subs r2, r2, #4 @ 1 do we have enough + blt 5f @ 1 bytes to align with? + cmp r3, #2 @ 1 + strltb r1, [r0], #1 @ 1 + strleb r1, [r0], #1 @ 1 + strb r1, [r0], #1 @ 1 + add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) +/* + * The pointer is now aligned and the length is adjusted. Try doing the + * memzero again. + */ -6: subs r2, r2, #1 - strgeb r1, [r3], #1 - bgt 6b - RETINSTR(mov, pc, lr) +ENTRY(memset) + ands r3, r0, #3 @ 1 unaligned? + bne 1b @ 1 +/* + * we know that the pointer in r0 is aligned to a word boundary. + */ + orr r1, r1, r1, lsl #8 + orr r1, r1, r1, lsl #16 + mov r3, r1 + cmp r2, #16 + blt 4f +/* + * We need an extra register for this loop - save the return address and + * use the LR + */ + str lr, [sp, #-4]! + mov ip, r1 + mov lr, r1 +2: subs r2, r2, #64 + stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time. + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} + bgt 2b + LOADREGS(eqfd, sp!, {pc}) @ Now <64 bytes to go. +/* + * No need to correct the count; we're only testing bits from now on + */ + tst r2, #32 + stmneia r0!, {r1, r3, ip, lr} + stmneia r0!, {r1, r3, ip, lr} + tst r2, #16 + stmneia r0!, {r1, r3, ip, lr} + ldr lr, [sp], #4 +4: tst r2, #8 + stmneia r0!, {r1, r3} + tst r2, #4 + strne r1, [r0], #4 +/* + * When we get here, we've got less than 4 bytes to zero. We + * may have an unaligned pointer as well. + */ +5: tst r2, #2 + strneb r1, [r0], #1 + strneb r1, [r0], #1 + tst r2, #1 + strneb r1, [r0], #1 + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/memzero.S b/arch/arm/lib/memzero.S index 59ec36574..51ccc6016 100644 --- a/arch/arm/lib/memzero.S +++ b/arch/arm/lib/memzero.S @@ -1,80 +1,80 @@ /* - * linux/arch/arm/lib/memzero.S + * linux/arch/arm/lib/memzero.S * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/linkage.h> #include <asm/assembler.h> -#include "constants.h" - - .text + .text + .align 5 + .word 0 /* - * Prototype: void memzero(void *d, size_t n) + * Align the pointer in r0. r3 contains the number of bytes that we are + * mis-aligned by, and r1 is the number of bytes. If r1 < 4, then we + * don't bother; we use byte stores instead. + */ +1: subs r1, r1, #4 @ 1 do we have enough + blt 5f @ 1 bytes to align with? + cmp r3, #2 @ 1 + strltb r2, [r0], #1 @ 1 + strleb r2, [r0], #1 @ 1 + strb r2, [r0], #1 @ 1 + add r1, r1, r3 @ 1 (r1 = r1 - (4 - r3)) +/* + * The pointer is now aligned and the length is adjusted. Try doing the + * memzero again. */ -1: @ 4 <= r1 - cmp ip, #2 @ 1 - strltb r2, [r0], #1 @ 1 - strleb r2, [r0], #1 @ 1 - strb r2, [r0], #1 @ 1 - rsb ip, ip, #4 @ 1 - sub r1, r1, ip @ 1 - cmp r1, #3 @ 1 - bgt 2f @ 1 @ +8 - b 4f @ 1 @ +9 - - .align 5 ENTRY(__memzero) - mov r2, #0 @ 1 - cmp r1, #4 @ 1 - blt 4f @ 1 @ = 3 - - @ r1 >= 4 - - ands ip, r0, #3 @ 1 - bne 1b @ 1 @ = 5 - -2: @ r1 >= 4 && (r0 & 3) = 0 @ = 5 or 11 - - str lr, [sp, #-4]! @ 1 - mov r3, #0 @ 1 - mov ip, #0 @ 1 - mov lr, #0 @ 1 - - @ 4 <= r1 <= 32 @ = 9 or 15 - -3: subs r1, r1, #32 @ 1 - stmgeia r0!, {r2, r3, ip, lr} @ 4 - stmgeia r0!, {r2, r3, ip, lr} @ 4 - bgt 3b @ 1 - LOADREGS(eqfd, sp!, {pc}) @ 1/2 - - @ -28 <= r1 <= -1 - - cmp r1, #-16 @ 1 - stmgeia r0!, {r2, r3, ip, lr} @ 4 - ldr lr, [sp], #4 @ 1 - addlts r1, r1, #16 @ 1 - RETINSTR(moveq,pc,lr) @ 1 - - @ -12 <= r1 <= -1 - - cmp r1, #-8 @ 1 - stmgeia r0!, {r2, r3} @ 2 - addlts r1, r1, #8 @ 1 - RETINSTR(moveq,pc,lr) @ 1 - - @ -4 <= r1 <= -1 - - cmp r1, #-4 @ 1 - strge r2, [r0], #4 @ 1 - adds r1, r1, #4 @ 1 - RETINSTR(moveq,pc,lr) @ 1 - -4: @ 1 <= r1 <= 3 - cmp r1, #2 @ 1 - strgtb r2, [r0], #1 @ 1 - strgeb r2, [r0], #1 @ 1 - strb r2, [r0], #1 @ 1 - RETINSTR(mov,pc,lr) @ 1 + mov r2, #0 @ 1 + ands r3, r0, #3 @ 1 unaligned? + bne 1b @ 1 +/* + * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary. + */ + cmp r1, #16 @ 1 we can skip this chunk if we + blt 4f @ 1 have < 16 bytes +/* + * We need an extra register for this loop - save the return address and + * use the LR + */ + str lr, [sp, #-4]! @ 1 + mov ip, r2 @ 1 + mov lr, r2 @ 1 + +3: subs r1, r1, #64 @ 1 write 32 bytes out per loop + stmgeia r0!, {r2, r3, ip, lr} @ 4 + stmgeia r0!, {r2, r3, ip, lr} @ 4 + stmgeia r0!, {r2, r3, ip, lr} @ 4 + stmgeia r0!, {r2, r3, ip, lr} @ 4 + bgt 3b @ 1 + LOADREGS(eqfd, sp!, {pc}) @ 1/2 quick exit +/* + * No need to correct the count; we're only testing bits from now on + */ + tst r1, #32 @ 1 + stmneia r0!, {r2, r3, ip, lr} @ 4 + stmneia r0!, {r2, r3, ip, lr} @ 4 + tst r1, #16 @ 1 16 bytes or more? + stmneia r0!, {r2, r3, ip, lr} @ 4 + ldr lr, [sp], #4 @ 1 + +4: tst r1, #8 @ 1 8 bytes or more? + stmneia r0!, {r2, r3} @ 2 + tst r1, #4 @ 1 4 bytes or more? + strne r2, [r0], #4 @ 1 +/* + * When we get here, we've got less than 4 bytes to zero. We + * may have an unaligned pointer as well. + */ +5: tst r1, #2 @ 1 2 bytes or more? + strneb r2, [r0], #1 @ 1 + strneb r2, [r0], #1 @ 1 + tst r1, #1 @ 1 a byte left over + strneb r2, [r0], #1 @ 1 + RETINSTR(mov,pc,lr) @ 1 diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S index 745bdce4e..5e51b27a8 100644 --- a/arch/arm/lib/setbit.S +++ b/arch/arm/lib/setbit.S @@ -1,9 +1,12 @@ /* - * linux/arch/arm/lib/setbit.S + * linux/arch/arm/lib/setbit.S * - * Copyright (C) 1995-1996 Russell King + * Copyright (C) 1995-1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/linkage.h> #include <asm/assembler.h> .text diff --git a/arch/arm/lib/strchr.S b/arch/arm/lib/strchr.S index fbde2483f..49b96bc02 100644 --- a/arch/arm/lib/strchr.S +++ b/arch/arm/lib/strchr.S @@ -1,19 +1,20 @@ /* - * linux/arch/arm/lib/strchr.S + * linux/arch/arm/lib/strchr.S * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-2000 Russell King * - * ASM optimised string functions + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * + * ASM optimised string functions */ #include <linux/linkage.h> #include <asm/assembler.h> -#include "constants.h" .text + .align 5 ENTRY(strchr) - str lr, [sp, #-4]! - mov r3, #0 1: ldrb r2, [r0], #1 teq r2, r1 teqne r2, #0 @@ -21,6 +22,4 @@ ENTRY(strchr) teq r2, #0 moveq r0, #0 subne r0, r0, #1 - LOADREGS(fd, sp!, {pc}) - - + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S new file mode 100644 index 000000000..629cc8775 --- /dev/null +++ b/arch/arm/lib/strncpy_from_user.S @@ -0,0 +1,43 @@ +/* + * linux/arch/arm/lib/strncpy_from_user.S + * + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/errno.h> + + .text + .align 5 + +/* + * Copy a string from user space to kernel space. + * r0 = dst, r1 = src, r2 = byte length + * returns the number of characters copied (strlen of copied string), + * -EFAULT on exception, or "len" if we fill the whole buffer + */ +ENTRY(__arch_strncpy_from_user) + save_lr + mov ip, r1 +1: subs r2, r2, #1 +USER( ldrplbt r3, [r1], #1) + bmi 2f + strb r3, [r0], #1 + teq r3, #0 + bne 1b + sub r1, r1, #1 @ take NUL character out of count +2: sub r0, r1, ip + restore_pc + + .section .fixup,"ax" + .align 0 +9001: mov r3, #0 + strb r3, [r0, #0] @ null terminate + mov r0, #-EFAULT + restore_pc + .previous + diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S new file mode 100644 index 000000000..67bcd8268 --- /dev/null +++ b/arch/arm/lib/strnlen_user.S @@ -0,0 +1,40 @@ +/* + * linux/arch/arm/lib/strnlen_user.S + * + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/errno.h> + + .text + .align 5 + +/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n) + * Purpose : get length of a string in user memory + * Params : str - address of string in user memory + * Returns : length of string *including terminator* + * or zero on exception, or n + 1 if too long + */ +ENTRY(__arch_strnlen_user) + save_lr + mov r2, r0 +1: +USER( ldrbt r3, [r0], #1) + teq r3, #0 + beq 2f + subs r1, r1, #1 + bne 1b + add r0, r0, #1 +2: sub r0, r0, r2 + restore_pc + + .section .fixup,"ax" + .align 0 +9001: mov r0, #0 + restore_pc + .previous diff --git a/arch/arm/lib/strrchr.S b/arch/arm/lib/strrchr.S index c9145d7af..7ef7fa439 100644 --- a/arch/arm/lib/strrchr.S +++ b/arch/arm/lib/strrchr.S @@ -1,18 +1,20 @@ /* - * linux/arch/arm/lib/strrchr.S + * linux/arch/arm/lib/strrchr.S * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-2000 Russell King * - * ASM optimised string functions + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * + * ASM optimised string functions */ #include <linux/linkage.h> #include <asm/assembler.h> -#include "constants.h" .text + .align 5 ENTRY(strrchr) - str lr, [sp, #-4]! mov r3, #0 1: ldrb r2, [r0], #1 teq r2, r1 @@ -20,6 +22,4 @@ ENTRY(strrchr) teq r2, #0 bne 1b mov r0, r3 - LOADREGS(fd, sp!, {pc}) - - + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S index c627cf99d..3131538d8 100644 --- a/arch/arm/lib/testchangebit.S +++ b/arch/arm/lib/testchangebit.S @@ -1,9 +1,12 @@ /* - * linux/arch/arm/lib/testchangebit.S + * linux/arch/arm/lib/testchangebit.S * - * Copyright (C) 1995-1996 Russell King + * Copyright (C) 1995-1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/linkage.h> #include <asm/assembler.h> .text diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S index 3a678e7ff..d6c612fe1 100644 --- a/arch/arm/lib/testclearbit.S +++ b/arch/arm/lib/testclearbit.S @@ -1,9 +1,12 @@ /* - * linux/arch/arm/lib/testclearbit.S + * linux/arch/arm/lib/testclearbit.S * - * Copyright (C) 1995-1996 Russell King + * Copyright (C) 1995-1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/linkage.h> #include <asm/assembler.h> .text diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S index 2b59febea..b022c324f 100644 --- a/arch/arm/lib/testsetbit.S +++ b/arch/arm/lib/testsetbit.S @@ -1,9 +1,12 @@ /* - * linux/arch/arm/lib/testsetbit.S + * linux/arch/arm/lib/testsetbit.S * - * Copyright (C) 1995-1996 Russell King + * Copyright (C) 1995-1996 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/linkage.h> #include <asm/assembler.h> .text diff --git a/arch/arm/lib/uaccess-armo.S b/arch/arm/lib/uaccess-armo.S index 695fdf0c1..2ffdf4dbb 100644 --- a/arch/arm/lib/uaccess-armo.S +++ b/arch/arm/lib/uaccess-armo.S @@ -1,23 +1,20 @@ /* - * arch/arm/lib/uaccess-armo.S + * linux/arch/arm/lib/uaccess-armo.S * - * Copyright (C) 1998 Russell King + * Copyright (C) 1998 Russell King * - * Note! Some code fragments found in here have a special calling - * convention - they are not APCS compliant! + * Note! Some code fragments found in here have a special calling + * convention - they are not APCS compliant! + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/linkage.h> #include <asm/assembler.h> .text -#define USER(x...) \ -9999: x; \ - .section __ex_table,"a"; \ - .align 3; \ - .long 9999b,9001f; \ - .previous - .globl SYMBOL_NAME(uaccess_user) SYMBOL_NAME(uaccess_user): .word uaccess_user_put_byte diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S index f2ea3231d..13af269c6 100644 --- a/arch/arm/lib/uaccess.S +++ b/arch/arm/lib/uaccess.S @@ -1,11 +1,15 @@ /* - * linux/arch/arm/lib/uaccess.S + * linux/arch/arm/lib/uaccess.S * - * Copyright (C) 1995, 1996,1997,1998 Russell King + * Copyright (C) 1995, 1996,1997,1998 Russell King * - * Routines to block copy data to/from user memory - * These are highly optimised both for the 4k page size - * and for various alignments. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Routines to block copy data to/from user memory + * These are highly optimised both for the 4k page size + * and for various alignments. */ #include <linux/linkage.h> #include <asm/assembler.h> @@ -13,13 +17,6 @@ .text -#define USER(x...) \ -9999: x; \ - .section __ex_table,"a"; \ - .align 3; \ - .long 9999b,9001f; \ - .previous - #define PAGE_SHIFT 12 /* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) @@ -590,62 +587,3 @@ USER( strnebt r2, [r0], #1) 9001: LOADREGS(fd,sp!, {r0, pc}) .previous -/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n) - * Purpose : get length of a string in user memory - * Params : str - address of string in user memory - * Returns : length of string *including terminator* - * or zero on exception, or n + 1 if too long - */ -ENTRY(__arch_strnlen_user) - str lr, [sp, #-4]! - mov r2, r0 -1: -USER( ldrbt r3, [r0], #1) - teq r3, #0 - beq 2f - subs r1, r1, #1 - bne 1b - add r0, r0, #1 -2: sub r0, r0, r2 - LOADREGS(fd,sp!, {pc}) - - .section .fixup,"ax" - .align 0 -9001: mov r0, #0 - LOADREGS(fd,sp!,{pc}) - .previous - -/* Prototype: size_t __arch_strncpy_from_user(char *dst, char *src, size_t len) - * Purpose : copy a string from user memory to kernel memory - * Params : dst - kernel memory destination - * : src - user memory source - * : len - maximum length of string - * Returns : number of characters copied - */ -ENTRY(__arch_strncpy_from_user) - str lr, [sp, #-4]! - add ip, r1, #1 -1: subs r2, r2, #1 - bmi 2f -USER( ldrbt r3, [r1], #1) - strb r3, [r0], #1 - teq r3, #0 - bne 1b - sub r0, r1, ip - LOADREGS(fd, sp!, {pc}) -2: sub ip, ip, #1 - sub r0, r1, ip - LOADREGS(fd, sp!, {pc}) - - .section .fixup,"ax" - .align 0 -9001: mov ip, #0 -1: strb ip, [r0], #1 - subs r2, r2, #1 - bpl 1b - mov r0, #-EFAULT - LOADREGS(fd, sp!, {pc}) - .previous - - .align - diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile new file mode 100644 index 000000000..c21caa6f6 --- /dev/null +++ b/arch/arm/mach-footbridge/Makefile @@ -0,0 +1,46 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). + +O_TARGET := footbridge.o + +# Object file lists. + +obj-y := arch.o #dma.o mm.o +obj-m := +obj-n := +obj- := + +export-objs := netwinder-hw.o + +ifeq ($(CONFIG_PCI),y) +obj-$(CONFIG_ARCH_CATS) += cats-pci.o +obj-$(CONFIG_ARCH_EBSA285) += ebsa285-pci.o +obj-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o +obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o +endif + +ifeq ($(CONFIG_LEDS),y) +obj-$(CONFIG_ARCH_CO285) += ebsa285-leds.o +obj-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o +obj-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o +endif + +obj-$(CONFIG_ARCH_CATS) += cats-hw.o +obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o + +# Files that are both resident and modular; remove from modular. + +obj-m := $(filter-out $(obj-y), $(obj-m)) + +# Translate to Rules.make lists. + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) + +include $(TOPDIR)/Rules.make diff --git a/arch/arm/mach-footbridge/arch.c b/arch/arm/mach-footbridge/arch.c new file mode 100644 index 000000000..d91c9b14b --- /dev/null +++ b/arch/arm/mach-footbridge/arch.c @@ -0,0 +1,152 @@ +/* + * linux/arch/arm/mach-footbridge/arch.c + * + * 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. + */ +#include <linux/config.h> +#include <linux/tty.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/init.h> + +#include <asm/hardware/dec21285.h> +#include <asm/elf.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> + +extern void setup_initrd(unsigned int start, unsigned int size); +extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz); +extern void __init footbridge_map_io(void); + +#ifdef CONFIG_ARCH_EBSA285 + +static void __init +fixup_ebsa285(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ + 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; +} + +MACHINE_START(EBSA285, "EBSA285") + MAINTAINER("Russell King") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + VIDEO(0x000a0000, 0x000bffff) + FIXUP(fixup_ebsa285) + MAPIO(footbridge_map_io) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_NETWINDER +/* + * 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, struct meminfo *mi) +{ +#ifdef CONFIG_ISAPNP + extern int isapnp_disable; + + /* + * We must not use the kernels ISAPnP code + * on the NetWinder - it will reset the settings + * for the WaveArtist chip and render it inoperable. + */ + isapnp_disable = 1; +#endif + + if (params->u1.s.nr_pages != 0x02000 && + params->u1.s.nr_pages != 0x04000 && + params->u1.s.nr_pages != 0x08000 && + params->u1.s.nr_pages != 0x10000) { + 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; + } +} + +MACHINE_START(NETWINDER, "Rebel-NetWinder") + MAINTAINER("Russell King/Rebel.com") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + VIDEO(0x000a0000, 0x000bffff) + DISABLE_PARPORT(0) + DISABLE_PARPORT(2) + FIXUP(fixup_netwinder) + MAPIO(footbridge_map_io) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_CATS +/* + * 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, struct meminfo *mi) +{ + ORIG_VIDEO_LINES = 25; + ORIG_VIDEO_POINTS = 16; + ORIG_Y = 24; +} + +MACHINE_START(CATS, "Chalice-CATS") + MAINTAINER("Philip Blundell") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + SOFT_REBOOT + FIXUP(fixup_cats) + MAPIO(footbridge_map_io) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_CO285 + +static void __init +fixup_coebsa285(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ + extern unsigned long boot_memory_end; + extern char boot_command_line[]; + + mi->nr_banks = 1; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].size = boot_memory_end; + mi->bank[0].node = 0; + + *cmdline = boot_command_line; +} + +MACHINE_START(CO285, "co-EBSA285") + MAINTAINER("Mark van Doesburg") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000) + FIXUP(fixup_coebsa285) + MAPIO(footbridge_map_io) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_PERSONAL_SERVER +MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer") + MAINTAINER("Jamey Hicks / George France") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + MAPIO(footbridge_map_io) +MACHINE_END +#endif diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c new file mode 100644 index 000000000..160b0307f --- /dev/null +++ b/arch/arm/mach-footbridge/cats-hw.c @@ -0,0 +1,65 @@ +/* + * linux/arch/arm/mach-footbridge/cats-hw.c + * + * CATS machine fixup + * + * Copyright (C) 1998, 1999 Russell King, Phil Blundell + */ +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/io.h> +#include <asm/mach-types.h> + +#define CFG_PORT 0x370 +#define INDEX_PORT (CFG_PORT) +#define DATA_PORT (CFG_PORT + 1) + +static int __init cats_hw_init(void) +{ + if (machine_is_cats()) { + /* Set Aladdin to CONFIGURE mode */ + outb(0x51, CFG_PORT); + outb(0x23, CFG_PORT); + + /* Select logical device 3 */ + outb(0x07, INDEX_PORT); + outb(0x03, DATA_PORT); + + /* Set parallel port to DMA channel 3, ECP+EPP1.9, + enable EPP timeout */ + outb(0x74, INDEX_PORT); + outb(0x03, DATA_PORT); + + outb(0xf0, INDEX_PORT); + outb(0x0f, DATA_PORT); + + outb(0xf1, INDEX_PORT); + outb(0x07, DATA_PORT); + + /* Select logical device 4 */ + outb(0x07, INDEX_PORT); + outb(0x04, DATA_PORT); + + /* UART1 high speed mode */ + outb(0xf0, INDEX_PORT); + outb(0x02, DATA_PORT); + + /* Select logical device 5 */ + outb(0x07, INDEX_PORT); + outb(0x05, DATA_PORT); + + /* UART2 high speed mode */ + outb(0xf0, INDEX_PORT); + outb(0x02, DATA_PORT); + + /* Set Aladdin to RUN mode */ + outb(0xbb, CFG_PORT); + } + + return 0; +} + +__initcall(cats_hw_init); diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c new file mode 100644 index 000000000..1f9e198ba --- /dev/null +++ b/arch/arm/mach-footbridge/cats-pci.c @@ -0,0 +1,37 @@ +/* + * linux/arch/arm/mach-footbridge/cats-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> + +/* cats host-specific stuff */ +static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; + +static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (dev->irq >= 128) + return dev->irq & 0x1f; + + if (dev->irq >= 1 && dev->irq <= 4) + return irqmap_cats[dev->irq - 1]; + + if (dev->irq != 0) + printk("PCI: device %02x:%02x has unknown irq line %x\n", + dev->bus->number, dev->devfn, dev->irq); + + return -1; +} + +struct hw_pci cats_pci __initdata = { + init: dc21285_init, + swizzle: no_swizzle, + map_irq: cats_map_irq, +}; diff --git a/arch/arm/kernel/leds-footbridge.c b/arch/arm/mach-footbridge/ebsa285-leds.c index 3de4c96f9..46ce71423 100644 --- a/arch/arm/kernel/leds-footbridge.c +++ b/arch/arm/mach-footbridge/ebsa285-leds.c @@ -1,19 +1,18 @@ /* - * arch/arm/kernel/leds-footbridge.c + * linux/arch/arm/mach-footbridge/ebsa285-leds.c * - * Copyright (C) 1998-1999 Russell King + * Copyright (C) 1998-1999 Russell King * - * EBSA-285 and NetWinder LED control routines. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * EBSA-285 control routines. * * The EBSA-285 uses the leds as follows: * - Green - toggles state every 50 timer interrupts * - Amber - On if system is not idle * - Red - currently unused * - * The Netwinder uses the leds as follows: - * - Green - toggles state every 50 timer interrupts - * - Red - On if the system is not idle - * * Changelog: * 02-05-1999 RMK Various cleanups */ @@ -34,9 +33,6 @@ static char led_state; static char hw_led_state; static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED; -extern spinlock_t gpio_lock; - -#if defined(CONFIG_ARCH_EBSA285) || defined(CONFIG_ARCH_CO285) static void ebsa285_leds_event(led_event_t evt) { @@ -131,123 +127,10 @@ static void ebsa285_leds_event(led_event_t evt) spin_unlock_irqrestore(&leds_lock, flags); } -#endif - -#ifdef CONFIG_ARCH_NETWINDER - -static void netwinder_leds_event(led_event_t evt) -{ - unsigned long flags; - - spin_lock_irqsave(&leds_lock, flags); - - switch (evt) { - case led_start: - led_state |= LED_STATE_ENABLED; - hw_led_state = GPIO_GREEN_LED; - break; - - case led_stop: - led_state &= ~LED_STATE_ENABLED; - break; - - case led_claim: - led_state |= LED_STATE_CLAIMED; - hw_led_state = 0; - break; - - case led_release: - led_state &= ~LED_STATE_CLAIMED; - hw_led_state = 0; - break; - -#ifdef CONFIG_LEDS_TIMER - case led_timer: - if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state ^= GPIO_GREEN_LED; - break; -#endif - -#ifdef CONFIG_LEDS_CPU - case led_idle_start: - if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state &= ~GPIO_RED_LED; - break; - - case led_idle_end: - if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state |= GPIO_RED_LED; - break; -#endif - - case led_halted: - if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state |= GPIO_RED_LED; - break; - - case led_green_on: - if (led_state & LED_STATE_CLAIMED) - hw_led_state |= GPIO_GREEN_LED; - break; - - case led_green_off: - if (led_state & LED_STATE_CLAIMED) - hw_led_state &= ~GPIO_GREEN_LED; - break; - - case led_amber_on: - if (led_state & LED_STATE_CLAIMED) - hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED; - break; - - case led_amber_off: - if (led_state & LED_STATE_CLAIMED) - hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED); - break; - - case led_red_on: - if (led_state & LED_STATE_CLAIMED) - hw_led_state |= GPIO_RED_LED; - break; - - case led_red_off: - if (led_state & LED_STATE_CLAIMED) - hw_led_state &= ~GPIO_RED_LED; - break; - - default: - break; - } - - spin_unlock_irqrestore(&leds_lock, flags); - - if (led_state & LED_STATE_ENABLED) { - spin_lock_irqsave(&gpio_lock, flags); - gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state); - spin_unlock_irqrestore(&gpio_lock, flags); - } -} - -#endif - -static void dummy_leds_event(led_event_t evt) -{ -} - -void (*leds_event)(led_event_t) = dummy_leds_event; - -EXPORT_SYMBOL(leds_event); - static int __init leds_init(void) { -#if defined(CONFIG_ARCH_EBSA285) || defined(CONFIG_ARCH_CO285) if (machine_is_ebsa285() || machine_is_co285()) leds_event = ebsa285_leds_event; -#endif -#ifdef CONFIG_ARCH_NETWINDER - if (machine_is_netwinder()) - leds_event = netwinder_leds_event; -#endif leds_event(led_start); diff --git a/arch/arm/mach-footbridge/ebsa285-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c new file mode 100644 index 000000000..304079040 --- /dev/null +++ b/arch/arm/mach-footbridge/ebsa285-pci.c @@ -0,0 +1,39 @@ +/* + * linux/arch/arm/mach-footbridge/ebsa285-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> + +static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI }; + +static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin) +{ + return PCI_SLOT(dev->devfn); +} + +static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (dev->vendor == PCI_VENDOR_ID_CONTAQ && + dev->device == PCI_DEVICE_ID_CONTAQ_82C693) + switch (PCI_FUNC(dev->devfn)) { + case 1: return 14; + case 2: return 15; + case 3: return 12; + } + + return irqmap_ebsa285[(slot + pin) & 3]; +} + +struct hw_pci ebsa285_pci __initdata = { + init: dc21285_init, + swizzle: ebsa285_swizzle, + map_irq: ebsa285_map_irq, +}; diff --git a/arch/arm/kernel/hw-footbridge.c b/arch/arm/mach-footbridge/netwinder-hw.c index 41ff450a5..4b47b6e47 100644 --- a/arch/arm/kernel/hw-footbridge.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -1,7 +1,7 @@ /* - * arch/arm/kernel/hw-footbridge.c + * linux/arch/arm/mach-footbridge/netwinder-hw.c * - * Footbridge-dependent machine fixup + * Netwinder machine fixup * * Copyright (C) 1998, 1999 Russell King, Phil Blundell */ @@ -29,11 +29,6 @@ #endif /* - * Netwinder stuff - */ -#ifdef CONFIG_ARCH_NETWINDER - -/* * Winbond WB83977F accessibility stuff */ static inline void wb977_open(void) @@ -609,13 +604,6 @@ EXPORT_SYMBOL(cpld_modify); */ static int __init nw_hw_init(void) { - /* - * this ought to have a better home... - * Since this calls the above routines, which are - * compiled only if CONFIG_ARCH_NETWINDER is set, - * these should only be parsed by the compiler - * in the same circumstance. - */ if (machine_is_netwinder()) { unsigned long flags; @@ -631,62 +619,3 @@ static int __init nw_hw_init(void) } __initcall(nw_hw_init); -#endif - -/* - * CATS stuff - */ -#ifdef CONFIG_ARCH_CATS - -#define CONFIG_PORT 0x370 -#define INDEX_PORT (CONFIG_PORT) -#define DATA_PORT (CONFIG_PORT + 1) - -static int __init cats_hw_init(void) -{ - if (machine_is_cats()) { - /* Set Aladdin to CONFIGURE mode */ - outb(0x51, CONFIG_PORT); - outb(0x23, CONFIG_PORT); - - /* Select logical device 3 */ - outb(0x07, INDEX_PORT); - outb(0x03, DATA_PORT); - - /* Set parallel port to DMA channel 3, ECP+EPP1.9, - enable EPP timeout */ - outb(0x74, INDEX_PORT); - outb(0x03, DATA_PORT); - - outb(0xf0, INDEX_PORT); - outb(0x0f, DATA_PORT); - - outb(0xf1, INDEX_PORT); - outb(0x07, DATA_PORT); - - /* Select logical device 4 */ - outb(0x07, INDEX_PORT); - outb(0x04, DATA_PORT); - - /* UART1 high speed mode */ - outb(0xf0, INDEX_PORT); - outb(0x02, DATA_PORT); - - /* Select logical device 5 */ - outb(0x07, INDEX_PORT); - outb(0x05, DATA_PORT); - - /* UART2 high speed mode */ - outb(0xf0, INDEX_PORT); - outb(0x02, DATA_PORT); - - /* Set Aladdin to RUN mode */ - outb(0xbb, CONFIG_PORT); - } - - return 0; -} - -__initcall(cats_hw_init); -#endif - diff --git a/arch/arm/mach-footbridge/netwinder-leds.c b/arch/arm/mach-footbridge/netwinder-leds.c new file mode 100644 index 000000000..bcf6e6a7c --- /dev/null +++ b/arch/arm/mach-footbridge/netwinder-leds.c @@ -0,0 +1,141 @@ +/* + * linux/arch/arm/mach-footbridge/netwinder-leds.c + * + * Copyright (C) 1998-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * NetWinder LED control routines. + * + * The Netwinder uses the leds as follows: + * - Green - toggles state every 50 timer interrupts + * - Red - On if the system is not idle + * + * Changelog: + * 02-05-1999 RMK Various cleanups + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/spinlock.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/mach-types.h> +#include <asm/system.h> + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 +static char led_state; +static char hw_led_state; + +static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED; +extern spinlock_t gpio_lock; + +static void netwinder_leds_event(led_event_t evt) +{ + unsigned long flags; + + spin_lock_irqsave(&leds_lock, flags); + + switch (evt) { + case led_start: + led_state |= LED_STATE_ENABLED; + hw_led_state = GPIO_GREEN_LED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= GPIO_GREEN_LED; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~GPIO_RED_LED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= GPIO_RED_LED; + break; +#endif + + case led_halted: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= GPIO_RED_LED; + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GPIO_GREEN_LED; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~GPIO_GREEN_LED; + break; + + case led_amber_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED; + break; + + case led_amber_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED); + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GPIO_RED_LED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~GPIO_RED_LED; + break; + + default: + break; + } + + spin_unlock_irqrestore(&leds_lock, flags); + + if (led_state & LED_STATE_ENABLED) { + spin_lock_irqsave(&gpio_lock, flags); + gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state); + spin_unlock_irqrestore(&gpio_lock, flags); + } +} + +static int __init leds_init(void) +{ + if (machine_is_netwinder()) + leds_event = netwinder_leds_event; + + leds_event(led_start); + + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c new file mode 100644 index 000000000..6bad74680 --- /dev/null +++ b/arch/arm/mach-footbridge/netwinder-pci.c @@ -0,0 +1,54 @@ +/* + * linux/arch/arm/mach-footbridge/netwinder-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> + +/* netwinder host-specific stuff */ +static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ +#define DEV(v,d) ((v)<<16|(d)) + switch (DEV(dev->vendor, dev->device)) { + case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142): + case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C885): + case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_YELLOWFIN): + return IRQ_NETWINDER_ETHER100; + + case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a): + return IRQ_NETWINDER_ETHER10; + + case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553): + return 0; + + case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105): + return IRQ_ISA_HARDDISK1; + + case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000): + case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010): + case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000): + return IRQ_NETWINDER_VGA; + + case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285): + return 0; + + default: + printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n", + dev->bus->number, dev->devfn, + dev->vendor, dev->device); + return 0; + } +} + +struct hw_pci netwinder_pci __initdata = { + init: dc21285_init, + swizzle: no_swizzle, + map_irq: netwinder_map_irq, +}; diff --git a/arch/arm/mach-footbridge/personal-pci.c b/arch/arm/mach-footbridge/personal-pci.c new file mode 100644 index 000000000..8d810a22f --- /dev/null +++ b/arch/arm/mach-footbridge/personal-pci.c @@ -0,0 +1,43 @@ +/* + * linux/arch/arm/mach-footbridge/personal-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> + +static int irqmap_personal_server[] __initdata = { + IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0, + IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI +}; + +static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + unsigned char line; + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line); + + if (line > 0x40 && line <= 0x5f) { + /* line corresponds to the bit controlling this interrupt + * in the footbridge. Ignore the first 8 interrupt bits, + * look up the rest in the map. IN0 is bit number 8 + */ + return irqmap_personal_server[(line & 0x1f) - 8]; + } else if (line == 0) { + /* no interrupt */ + return 0; + } else + return irqmap_personal_server[(line - 1) & 3]; +} + +struct hw_pci personal_server_pci __initdata = { + init: dc21285_init, + swizzle: no_swizzle, + map_irq: personal_server_map_irq, +}; diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile new file mode 100644 index 000000000..441608295 --- /dev/null +++ b/arch/arm/mach-sa1100/Makefile @@ -0,0 +1,34 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). + +USE_STANDARD_AS_RULE := true + +O_TARGET := sa1100.o + +# Object file lists. + +obj-y := arch.o hw.o #dma.o mm.o +obj-m := +obj-n := +obj- := + +export-objs := hw.o leds.o + +obj-$(CONFIG_LEDS) += leds.o + +# Files that are both resident and modular; remove from modular. + +obj-m := $(filter-out $(obj-y), $(obj-m)) + +# Translate to Rules.make lists. + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) + +include $(TOPDIR)/Rules.make diff --git a/arch/arm/mach-sa1100/arch.c b/arch/arm/mach-sa1100/arch.c new file mode 100644 index 000000000..32ac72379 --- /dev/null +++ b/arch/arm/mach-sa1100/arch.c @@ -0,0 +1,291 @@ +/* + * linux/arch/arm/mach-sa1100/arch.c + * + * 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. + */ +#include <linux/config.h> +#include <linux/tty.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/init.h> + +#include <asm/elf.h> +#include <asm/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> + +extern void setup_initrd(unsigned int start, unsigned int size); +extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz); + +static void victor_power_off(void) +{ + /* switch off power supply */ + mdelay(2000); + GPCR = GPIO_GPIO23; + while (1); +} + + +static void xp860_power_off(void) +{ + GPDR |= GPIO_GPIO20; + GPSR = GPIO_GPIO20; + mdelay(1000); + GPCR = GPIO_GPIO20; + while(1); +} + + +extern void __init sa1100_map_io(void); + +#define SET_BANK(__nr,__start,__size) \ + mi->bank[__nr].start = (__start), \ + mi->bank[__nr].size = (__size), \ + mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27) +static void __init +fixup_sa1100(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ + if (machine_is_assabet()) { + /* + * On Assabet, we must probe for the Neponset board *before* + * paging_init() has occured to actually determine the amount + * of RAM available. + */ + extern void map_sa1100_gpio_regs(void); + extern void get_assabet_scr(void); + map_sa1100_gpio_regs(); + get_assabet_scr(); + + SET_BANK( 0, 0xc0000000, 32*1024*1024 ); + mi->nr_banks = 1; + + if (machine_has_neponset()) { + printk("Neponset expansion board detected\n"); + /* + * Note that Neponset RAM is slower... + * and still untested. + * This would be a candidate for + * _real_ NUMA support. + */ + //SET_BANK( 1, 0xd0000000, 32*1024*1024 ); + //mi->nr_banks = 2; + } + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( 0xc0800000, 3*1024*1024 ); + } + + else if (machine_is_brutus()) { + SET_BANK( 0, 0xc0000000, 4*1024*1024 ); + SET_BANK( 1, 0xc8000000, 4*1024*1024 ); + SET_BANK( 2, 0xd0000000, 4*1024*1024 ); + SET_BANK( 3, 0xd8000000, 4*1024*1024 ); + mi->nr_banks = 4; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( __phys_to_virt(0xd8000000), 3*1024*1024 ); + } + + else if (machine_is_cerf()) { + // 16Meg Ram. + SET_BANK( 0, 0xc0000000, 8*1024*1024 ); + SET_BANK( 1, 0xc8000000, 8*1024*1024 ); // comment this out for 8MB Cerfs + mi->nr_banks = 2; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk(1, 0, 0, 8192); + // Save 2Meg for RAMDisk + setup_initrd(0xc0500000, 3*1024*1024); + } + + else if (machine_is_empeg()) { + SET_BANK( 0, 0xc0000000, 4*1024*1024 ); + SET_BANK( 1, 0xc8000000, 4*1024*1024 ); + mi->nr_banks = 2; + + ROOT_DEV = MKDEV( 3, 1 ); /* /dev/hda1 */ + setup_ramdisk( 1, 0, 0, 4096 ); + setup_initrd( 0xd0000000+((1024-320)*1024), (320*1024) ); + } + + else if (machine_is_lart()) { + /* + * Note that LART is a special case - it doesn't use physical + * address line A23 on the DRAM, so we effectively have 4 * 8MB + * in two SA1100 banks. + */ + SET_BANK( 0, 0xc0000000, 8*1024*1024 ); + SET_BANK( 1, 0xc1000000, 8*1024*1024 ); + SET_BANK( 2, 0xc8000000, 8*1024*1024 ); + SET_BANK( 3, 0xc9000000, 8*1024*1024 ); + mi->nr_banks = 4; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk(1, 0, 0, 8192); + setup_initrd(0xc0400000, 4*1024*1024); + } + + else if (machine_is_thinclient() || machine_is_graphicsclient()) { + SET_BANK( 0, 0xc0000000, 16*1024*1024 ); + mi->nr_banks = 1; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); + } + + else if (machine_is_nanoengine()) { + SET_BANK( 0, 0xc0000000, 32*1024*1024 ); + mi->nr_banks = 1; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); + + /* Get command line parameters passed from the loader (if any) */ + if( *((char*)0xc0000100) ) + *cmdline = ((char *)0xc0000100); + } + else if (machine_is_tifon()) { + SET_BANK( 0, 0xc0000000, 16*1024*1024 ); + SET_BANK( 1, 0xc8000000, 16*1024*1024 ); + mi->nr_banks = 2; + + ROOT_DEV = MKDEV(UNNAMED_MAJOR, 0); + setup_ramdisk(1, 0, 0, 4096); + setup_initrd( 0xd0000000 + 0x1100004, 0x140000 ); + } + + else if (machine_is_victor()) { + SET_BANK( 0, 0xc0000000, 4*1024*1024 ); + mi->nr_banks = 1; + + ROOT_DEV = MKDEV( 60, 2 ); + + /* Get command line parameters passed from the loader (if any) */ + if( *((char*)0xc0000000) ) + strcpy( *cmdline, ((char *)0xc0000000) ); + + /* power off if any problem */ + strcat( *cmdline, " panic=1" ); + + pm_power_off = victor_power_off; + } + + else if (machine_is_xp860()) { + SET_BANK( 0, 0xc0000000, 32*1024*1024 ); + mi->nr_banks = 1; + + pm_power_off = xp860_power_off; + } +} + +#ifdef CONFIG_SA1100_ASSABET +MACHINE_START(ASSABET, "Intel-Assabet") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_BITSY +MACHINE_START(BITSY, "Compaq Bitsy") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_BRUTUS +MACHINE_START(BRUTUS, "Intel Brutus (SA1100 eval board)") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_CERF +MACHINE_START(CERF, "Intrinsyc CerfBoard") + MAINTAINER("Pieter Truter") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_EMPEG +MACHINE_START(EMPEG, "empeg MP3 Car Audio Player") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_GRAPHICSCLIENT +MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_ITSY +MACHINE_START(ITSY, "Compaq Itsy") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100 + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_LART +MACHINE_START(LART, "LART") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_NANOENGINE +MACHINE_START(NANOENGINE, "BSE nanoEngine") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_PLEB +MACHINE_START(PLEB, "PLEB") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_THINCLIENT +MACHINE_START(THINCLIENT, "ADS ThinClient") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_TIFON +MACHINE_START(TIFON, "Tifon") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_VICTOR +MACHINE_START(VICTOR, "VisuAide Victor") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif +#ifdef CONFIG_SA1100_XP860 +MACHINE_START(XP860, "XP860") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) + MAPIO(sa1100_map_io) +MACHINE_END +#endif diff --git a/arch/arm/kernel/hw-sa1100.c b/arch/arm/mach-sa1100/hw.c index 5acfab1e2..1ccc61fe3 100644 --- a/arch/arm/kernel/hw-sa1100.c +++ b/arch/arm/mach-sa1100/hw.c @@ -67,13 +67,13 @@ void __init get_assabet_scr(void) { unsigned long flags, scr, i; - save_flags_cli(flags); + local_irq_save(flags); GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */ GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */ GPDR &= ~(0x3fc); /* Configure GPIO 9:2 as inputs */ for(i = 100; i--; scr = GPLR); /* Read GPIO 9:2 */ GPDR |= 0x3fc; /* restore correct pin direction */ - restore_flags(flags); + local_irq_restore(flags); scr &= 0x3fc; /* save as system configuration byte. */ SCR_value = scr; @@ -81,10 +81,11 @@ void __init get_assabet_scr(void) #endif /* CONFIG_SA1100_ASSABET */ + +#if defined(CONFIG_SA1100_BITSY) /* * Bitsy has extended, write-only memory-mapped GPIO's */ -#if defined(CONFIG_SA1100_BITSY) static int bitsy_egpio = EGPIO_BITSY_RS232_ON; void clr_bitsy_egpio(unsigned long x) { @@ -100,9 +101,10 @@ EXPORT_SYMBOL(clr_bitsy_egpio); EXPORT_SYMBOL(set_bitsy_egpio); #endif + #ifdef CONFIG_SA1111 -void __init sa1111_init(void){ +static void __init sa1111_init(void){ unsigned long id=SKID; if((id & SKID_ID_MASK) == SKID_SA1111_ID) @@ -160,6 +162,8 @@ void __init sa1111_init(void){ } } +#else +#define sa1111_init() printk( "Warning: missing SA1111 support\n" ) #endif diff --git a/arch/arm/kernel/leds-sa1100.c b/arch/arm/mach-sa1100/leds.c index fc4662c2a..be36e94a3 100644 --- a/arch/arm/kernel/leds-sa1100.c +++ b/arch/arm/mach-sa1100/leds.c @@ -55,7 +55,7 @@ static void assabet_leds_event(led_event_t evt) { unsigned long flags; - save_flags_cli(flags); + local_irq_save(flags); switch (evt) { case led_start: @@ -132,7 +132,7 @@ static void assabet_leds_event(led_event_t evt) if (led_state & LED_STATE_ENABLED) BCR = BCR_value = (BCR_value & ~BCR_LED_MASK) | hw_led_state; - restore_flags(flags); + local_irq_restore(flags); } #endif /* CONFIG_SA1100_ASSABET */ @@ -148,7 +148,7 @@ static void brutus_leds_event(led_event_t evt) { unsigned long flags; - save_flags_cli(flags); + local_irq_save(flags); switch (evt) { case led_start: @@ -222,7 +222,7 @@ static void brutus_leds_event(led_event_t evt) GPCR = hw_led_state ^ LED_MASK; } - restore_flags(flags); + local_irq_restore(flags); } #endif /* CONFIG_SA1100_BRUTUS */ @@ -237,7 +237,7 @@ static void lart_leds_event(led_event_t evt) { unsigned long flags; - save_flags_cli(flags); + local_irq_save(flags); switch(evt) { case led_start: @@ -301,7 +301,7 @@ static void lart_leds_event(led_event_t evt) GPCR = hw_led_state ^ LED_MASK; } - restore_flags(flags); + local_irq_restore(flags); } #endif /* CONFIG_SA1100_LART */ @@ -317,7 +317,7 @@ static void cerf_leds_event(led_event_t evt) { unsigned long flags; - save_flags_cli(flags); + local_irq_save(flags); switch (evt) { case led_start: @@ -395,19 +395,11 @@ static void cerf_leds_event(led_event_t evt) GPCR = hw_led_state ^ LED_MASK; } - restore_flags(flags); + local_irq_restore(flags); } #endif /* CONFIG_SA1100_CERF */ -static void dummy_leds_event(led_event_t evt) -{ -} - -void (*leds_event)(led_event_t) = dummy_leds_event; - -EXPORT_SYMBOL(leds_event); - static int __init sa1100_leds_init(void) { diff --git a/arch/arm/mach-shark/Makefile b/arch/arm/mach-shark/Makefile new file mode 100644 index 000000000..414d0c2e1 --- /dev/null +++ b/arch/arm/mach-shark/Makefile @@ -0,0 +1,32 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). + +O_TARGET := shark.o + +# Object file lists. + +obj-y := arch.o dma.o mm.o pci.o +obj-m := +obj-n := +obj- := + +export-objs := + +#obj-$(CONFIG_LEDS) += leds.o + +# Files that are both resident and modular; remove from modular. + +obj-m := $(filter-out $(obj-y), $(obj-m)) + +# Translate to Rules.make lists. + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) + +include $(TOPDIR)/Rules.make diff --git a/arch/arm/mach-shark/arch.c b/arch/arm/mach-shark/arch.c new file mode 100644 index 000000000..87ebe0270 --- /dev/null +++ b/arch/arm/mach-shark/arch.c @@ -0,0 +1,31 @@ +/* + * linux/arch/arm/mach-shark/arch.c + * + * 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. + */ +#include <linux/tty.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/init.h> + +#include <asm/hardware/dec21285.h> +#include <asm/elf.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> + +extern void setup_initrd(unsigned int start, unsigned int size); +extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz); +extern void __init footbridge_map_io(void); +extern void __init shark_map_io(void); + +MACHINE_START(SHARK, "Shark") + MAINTAINER("Alexander Schulz") + BOOT_MEM(0x08000000, 0x40000000, 0xe0000000) + VIDEO(0x06000000, 0x061fffff) + MAPIO(shark_map_io) +MACHINE_END diff --git a/arch/arm/mach-shark/dma.c b/arch/arm/mach-shark/dma.c new file mode 100644 index 000000000..9e80dfb7b --- /dev/null +++ b/arch/arm/mach-shark/dma.c @@ -0,0 +1,25 @@ +/* + * linux/arch/arm/mach-shark/dma.c + * + * by Alexander.Schulz@stud.uni-karlsruhe.de + * + * derived from: + * arch/arm/kernel/dma-ebsa285.c + * Copyright (C) 1998 Phil Blundell + */ + +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/init.h> + +#include <asm/dma.h> +#include <asm/io.h> + +#include <asm/mach/dma.h> + +void __init arch_dma_init(dma_t *dma) +{ +#ifdef CONFIG_ISA_DMA + isa_init_dma(dma); +#endif +} diff --git a/arch/arm/mach-shark/mm.c b/arch/arm/mach-shark/mm.c new file mode 100644 index 000000000..f3092fb8a --- /dev/null +++ b/arch/arm/mach-shark/mm.c @@ -0,0 +1,30 @@ +/* + * linux/arch/arm/mach-shark/mm.c + * + * by Alexander.Schulz@stud.uni-karlsruhe.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/init.h> + +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/io.h> + +#include <asm/mach/map.h> + +static struct map_desc shark_io_desc[] __initdata = { + { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, + { FB_BASE , FB_START , FB_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, + { FBREG_BASE , FBREG_START , FBREG_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, + LAST_DESC +}; + +void __init shark_map_io(void) +{ + iotable_init(shark_io_desc); +} diff --git a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c new file mode 100644 index 000000000..601922ce8 --- /dev/null +++ b/arch/arm/mach-shark/pci.c @@ -0,0 +1,27 @@ +/* + * linux/arch/arm/mach-shark/pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> + +static int __init shark_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (dev->bus->number == 0) + if (dev->devfn == 0) return 255; + else return 11; + else return 6; +} + +struct hw_pci shark_pci __initdata = { + init: via82c505_init, + swizzle: no_swizzle, + map_irq: shark_map_irq +}; diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 075193467..fe3cf5eac 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -9,40 +9,61 @@ USE_STANDARD_AS_RULE := true +EXTRA_AFLAGS := -traditional O_TARGET := mm.o -O_OBJS := extable.o fault-$(PROCESSOR).o init.o \ + +# Object file lists. + +obj-y := extable.o fault-$(PROCESSOR).o init.o \ mm-$(PROCESSOR).o small_page.o +obj-m := +obj-n := +obj- := +export-objs := proc-syms.o -ifeq ($(CONFIG_CPU_26),y) - O_OBJS += proc-arm2,3.o -endif +p-$(CONFIG_CPU_26) += proc-arm2,3.o +p-$(CONFIG_CPU_ARM6) += proc-arm6,7.o +p-$(CONFIG_CPU_ARM7) += proc-arm6,7.o +p-$(CONFIG_CPU_ARM720) += proc-arm720.o +p-$(CONFIG_CPU_ARM920) += proc-arm920.o +p-$(CONFIG_CPU_ARM10) += proc-arm10.o +p-$(CONFIG_CPU_SA110) += proc-sa110.o +p-$(CONFIG_CPU_SA1100) += proc-sa110.o +obj-$(CONFIG_CPU_32) += consistent.o ioremap.o ifeq ($(CONFIG_CPU_32),y) - ifeq ($(CONFIG_CPU_ARM6),y) - P_OBJS += proc-arm6,7.o - endif - ifeq ($(CONFIG_CPU_ARM7),y) - P_OBJS += proc-arm6,7.o - endif - ifeq ($(CONFIG_CPU_ARM720),y) - P_OBJS += proc-arm720.o - endif - ifeq ($(CONFIG_CPU_SA110),y) - P_OBJS += proc-sa110.o - endif - ifeq ($(CONFIG_CPU_SA1100),y) - P_OBJS += proc-sa110.o - endif - O_OBJS += mm-$(MACHINE).o consistent.o ioremap.o $(sort $(P_OBJS)) +obj-$(CONFIG_MODULES) += proc-syms.o +endif + +# Integrator follows "new style" +# Soon, others will do too, and we can get rid of this +MMMACH := mm-$(MACHINE).o +ifeq ($(MMMACH),$(wildcard $(MMMACH))) +obj-$(CONFIG_CPU_32) += $(MMMACH) endif +obj-y += $(sort $(p-y)) + +# Files that are both resident and modular; remove from modular. + +obj-m := $(filter-out $(obj-y), $(obj-m)) + +# Translate to Rules.make lists. + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) + include $(TOPDIR)/Rules.make # Special dependencies -fault-armv.o: fault-common.c -fault-armo.o: fault-common.c +fault-armv.o: fault-common.c +fault-armo.o: fault-common.c proc-arm2,3.o: ../lib/constants.h proc-arm6,7.o: ../lib/constants.h proc-arm720.o: ../lib/constants.h +proc-arm920.o: ../lib/constants.h +proc-arm10.o: ../lib/constants.h proc-sa110.o: ../lib/constants.h diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index b21bc1d8a..4b06c4cad 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -1,5 +1,13 @@ /* - * Dynamic DMA mapping support. + * linux/arch/arm/mm/consistent.c + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Dynamic DMA mapping support. */ #include <linux/config.h> #include <linux/types.h> @@ -43,18 +51,19 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) ret = __ioremap(virt_to_phys((void *)page), size, 0); if (ret) { /* free wasted pages */ - unsigned long end = page + (PAGE_SIZE << order); + unsigned long end; /* * we need to ensure that there are no * cachelines in use, or worse dirty in * this area. */ - dma_cache_inv(page, size); - dma_cache_inv(ret, size); + invalidate_dcache_range(page, page + size); + invalidate_dcache_range((unsigned long)ret, (unsigned long)ret + size); - *dma_handle = virt_to_bus((void *)page); + *dma_handle = __virt_to_bus(page); + end = page + (PAGE_SIZE << order); page += size; while (page < end) { free_page(page); @@ -102,17 +111,20 @@ void consistent_free(void *vaddr) */ void consistent_sync(void *vaddr, size_t size, int direction) { + unsigned long start = (unsigned long)vaddr; + unsigned long end = start + size; + switch (direction) { case PCI_DMA_NONE: BUG(); case PCI_DMA_FROMDEVICE: /* invalidate only */ - dma_cache_inv(vaddr, size); + invalidate_dcache_range(start, end); break; case PCI_DMA_TODEVICE: /* writeback only */ - dma_cache_wback(vaddr, size); + clean_dcache_range(start, end); break; case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */ - dma_cache_wback_inv(vaddr, size); + flush_dcache_range(start, end); break; } } diff --git a/arch/arm/mm/extable.c b/arch/arm/mm/extable.c index e603b6362..e32d40c8e 100644 --- a/arch/arm/mm/extable.c +++ b/arch/arm/mm/extable.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mm/extable.c + * linux/arch/arm/mm/extable.c */ #include <linux/config.h> diff --git a/arch/arm/mm/fault-armo.c b/arch/arm/mm/fault-armo.c index 19a1fff7c..85b2dc2f4 100644 --- a/arch/arm/mm/fault-armo.c +++ b/arch/arm/mm/fault-armo.c @@ -3,8 +3,11 @@ * * Copyright (C) 1995 Linus Torvalds * Modifications for ARM processor (c) 1995-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index c3d03f251..f184b4e68 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -3,8 +3,11 @@ * * Copyright (C) 1995 Linus Torvalds * Modifications for ARM processor (c) 1995-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> @@ -399,7 +402,11 @@ do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr) return; bad: force_sig(inf->sig, current); - die_if_kernel(inf->name, regs, fsr); + + printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n", + inf->name, fsr, addr); + show_pte(current->mm, addr); + die_if_kernel("Oops", regs, 0); return; weirdness: diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c index 519f1965a..0e198ab8a 100644 --- a/arch/arm/mm/fault-common.c +++ b/arch/arm/mm/fault-common.c @@ -3,6 +3,10 @@ * * Copyright (C) 1995 Linus Torvalds * Modifications for ARM processor (c) 1995-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> @@ -12,7 +16,7 @@ extern void die(const char *msg, struct pt_regs *regs, int err); * This is useful to dump out the page tables associated with * 'addr' in mm 'mm'. */ -static void show_pte(struct mm_struct *mm, unsigned long addr) +void show_pte(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; @@ -31,7 +35,7 @@ static void show_pte(struct mm_struct *mm, unsigned long addr) break; if (pgd_bad(*pgd)) { - printk("(bad)\n"); + printk("(bad)"); break; } @@ -42,7 +46,7 @@ static void show_pte(struct mm_struct *mm, unsigned long addr) break; if (pmd_bad(*pmd)) { - printk("(bad)\n"); + printk("(bad)"); break; } diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index ba58e8bad..a235232d9 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -2,6 +2,10 @@ * linux/arch/arm/mm/init.c * * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> #include <linux/signal.h> @@ -27,7 +31,8 @@ #include <asm/hardware.h> #include <asm/setup.h> -#include "map.h" +#include <asm/mach/arch.h> +#include <asm/mach/map.h> #ifndef CONFIG_DISCONTIGMEM #define NR_NODES 1 @@ -387,6 +392,12 @@ static inline void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot */ reserve_bootmem_node(0, __pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(void *)); +#else + /* + * Stop this memory from being grabbed - its special DMA + * memory that is required for the screen. + */ + reserve_bootmem_node(0, 0x02000000, 0x00080000); #endif /* * And don't forget to reserve the allocator bitmap, @@ -466,7 +477,7 @@ void __init bootmem_init(struct meminfo *mi) * paging_init() sets up the page tables, initialises the zone memory * maps, and sets up the zero page, bad page and bad page tables. */ -void __init paging_init(struct meminfo *mi) +void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) { void *zero_page, *bad_page, *bad_table; int node; @@ -474,16 +485,19 @@ void __init paging_init(struct meminfo *mi) memcpy(&meminfo, mi, sizeof(meminfo)); /* - * allocate what we need for the bad pages + * allocate what we need for the bad pages. + * note that we count on this going ok. */ zero_page = alloc_bootmem_low_pages(PAGE_SIZE); bad_page = alloc_bootmem_low_pages(PAGE_SIZE); bad_table = alloc_bootmem_low_pages(TABLE_SIZE); /* - * initialise the page tables + * initialise the page tables. */ - pagetable_init(mi); + memtable_init(mi); + if (mdesc->map_io) + mdesc->map_io(); flush_tlb_all(); /* @@ -528,7 +542,7 @@ void __init paging_init(struct meminfo *mi) zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT; } - free_area_init_node(node, pgdat, zone_size, + free_area_init_node(node, pgdat, 0, zone_size, bdata->node_boot_start, zhole_size); } diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index d59b4e16c..e90c25018 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -1,5 +1,5 @@ /* - * arch/arm/mm/ioremap.c + * linux/arch/arm/mm/ioremap.c * * Re-map IO memory to kernel address space so that we can access it. * diff --git a/arch/arm/mm/map.h b/arch/arm/mm/map.h deleted file mode 100644 index 1d071748d..000000000 --- a/arch/arm/mm/map.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * linux/arch/arm/mm/map.h - * - * Copyright (C) 1999 Russell King - * - * Page table mapping constructs and function prototypes - */ -struct map_desc { - unsigned long virtual; - unsigned long physical; - unsigned long length; - int domain:4, - prot_read:1, - prot_write:1, - cacheable:1, - bufferable:1; -}; - -extern struct map_desc io_desc[]; -extern unsigned int io_desc_size; - -struct meminfo; - -extern void create_memmap_holes(struct meminfo *); -extern void pagetable_init(struct meminfo *); diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c index dc1647a2d..9a426fc18 100644 --- a/arch/arm/mm/mm-armo.c +++ b/arch/arm/mm/mm-armo.c @@ -1,9 +1,13 @@ /* - * arch/arm/mm/mm-armo.c + * linux/arch/arm/mm/mm-armo.c * - * Page table sludge for older ARM processor architectures. + * Copyright (C) 1998-2000 Russell King * - * Copyright (C) 1998-2000 Russell King + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Page table sludge for older ARM processor architectures. */ #include <linux/sched.h> #include <linux/mm.h> @@ -15,7 +19,7 @@ #include <asm/page.h> #include <asm/arch/memory.h> -#include "map.h" +#include <asm/mach/map.h> #define MEMC_TABLE_SIZE (256*sizeof(unsigned long)) #define PGD_TABLE_SIZE (PTRS_PER_PGD * BYTES_PER_PTR) @@ -147,7 +151,7 @@ void setup_mm_for_reboot(char mode) * some more work to get it to fit into our separate processor and * architecture structure. */ -void __init pagetable_init(struct meminfo *mi) +void __init memtable_init(struct meminfo *mi) { pte_t *pte; int i; @@ -162,6 +166,11 @@ void __init pagetable_init(struct meminfo *mi) pgd_val(swapper_pg_dir[i]) = 0; } +void __init iotable_init(struct map_desc *io_desc) +{ + /* nothing to do */ +} + /* * We never have holes in the memmap */ diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index e656a25d2..9ddcc84bc 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -1,9 +1,13 @@ /* * linux/arch/arm/mm/mm-armv.c * - * Page table sludge for ARM v3 and v4 processor architectures. - * * Copyright (C) 1998-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Page table sludge for ARM v3 and v4 processor architectures. */ #include <linux/sched.h> #include <linux/mm.h> @@ -16,7 +20,7 @@ #include <asm/io.h> #include <asm/setup.h> -#include "map.h" +#include <asm/mach/map.h> unsigned long *valid_addr_bitmap; @@ -62,6 +66,10 @@ __setup("nowb", nowrite_setup); #define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) +#define clean_cache_area(start,size) \ + cpu_cache_clean_invalidate_range((unsigned long)start, ((unsigned long)start) + size, 0); + + /* * need to get a 16k page for level 1 */ @@ -72,10 +80,13 @@ pgd_t *get_pgd_slow(void) if (pgd) { pgd_t *init = pgd_offset_k(0); - + memzero(pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); memcpy(pgd + FIRST_KERNEL_PGD_NR, init + FIRST_KERNEL_PGD_NR, (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); + /* + * FIXME: this should not be necessary + */ clean_cache_area(pgd, PTRS_PER_PGD * sizeof(pgd_t)); /* @@ -310,18 +321,17 @@ void setup_mm_for_reboot(char mode) } } -void __init pagetable_init(struct meminfo *mi) +/* + * Setup initial mappings. We use the page we allocated for zero page to hold + * the mappings, which will get overwritten by the vectors in traps_init(). + * The mappings must be in virtual address order. + */ +void __init memtable_init(struct meminfo *mi) { struct map_desc *init_maps, *p, *q; unsigned long address = 0; int i; - /* - * Setup initial mappings. We use the page we allocated - * for zero page to hold the mappings, which will get - * overwritten by the vectors in traps_init(). The - * mappings must be in virtual address order. - */ init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE); p->physical = virt_to_phys(init_maps); @@ -401,16 +411,21 @@ void __init pagetable_init(struct meminfo *mi) } } while (address != 0); - /* - * Create the architecture specific mappings - */ - for (i = 0; i < io_desc_size; i++) - create_mapping(io_desc + i); - flush_cache_all(); } -static inline void free_memmap(unsigned long start, unsigned long end) +/* + * Create the architecture specific mappings + */ +void __init iotable_init(struct map_desc *io_desc) +{ + int i; + + for (i = 0; io_desc[i].last == 0; i++) + create_mapping(io_desc + i); +} + +static inline void free_memmap(int node, unsigned long start, unsigned long end) { unsigned long pg, pgend; @@ -422,10 +437,8 @@ static inline void free_memmap(unsigned long start, unsigned long end) start = __virt_to_phys(pg); end = __virt_to_phys(pgend); - /* - * The mem_map is always stored in node 0 - */ - free_bootmem_node(0, start, end - start); + + free_bootmem_node(node, start, end - start); } static inline void free_unused_memmap_node(int node, struct meminfo *mi) @@ -449,7 +462,7 @@ static inline void free_unused_memmap_node(int node, struct meminfo *mi) * between the current bank and the previous, free it. */ if (prev_bank_end && prev_bank_end != bank_start) - free_memmap(prev_bank_end, bank_start); + free_memmap(node, prev_bank_end, bank_start); prev_bank_end = PAGE_ALIGN(mi->bank[i].start + mi->bank[i].size); diff --git a/arch/arm/mm/mm-clps7500.c b/arch/arm/mm/mm-clps7500.c index b9199de80..765367c47 100644 --- a/arch/arm/mm/mm-clps7500.c +++ b/arch/arm/mm/mm-clps7500.c @@ -1,12 +1,11 @@ /* - * arch/arm/mm/mm-cl7500.c + * linux/arch/arm/mm/mm-cl7500.c * - * Extra MM routines for CL7500 architecture + * Copyright (C) 1998 Russell King + * Copyright (C) 1999 Nexus Electronics Ltd * - * Copyright (C) 1998 Russell King - * Copyright (C) 1999 Nexus Electronics Ltd + * Extra MM routines for CL7500 architecture */ - #include <linux/init.h> #include <asm/hardware.h> @@ -14,15 +13,17 @@ #include <asm/proc/domain.h> #include <asm/setup.h> -#include "map.h" - -#define SIZE(x) (sizeof(x) / sizeof(x[0])) +#include <asm/mach/map.h> -struct map_desc io_desc[] __initdata = { +static struct map_desc cl7500_io_desc[] __initdata = { { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1 }, /* IO space */ { ISA_BASE, ISA_START, ISA_SIZE , DOMAIN_IO, 0, 1 }, /* ISA space */ { FLASH_BASE, FLASH_START, FLASH_SIZE, DOMAIN_IO, 0, 1 }, /* Flash */ - { LED_BASE, LED_START, LED_SIZE , DOMAIN_IO, 0, 1 } /* LED */ + { LED_BASE, LED_START, LED_SIZE , DOMAIN_IO, 0, 1 }, /* LED */ + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init clps7500_map_io(void) +{ + iotable_init(cl7500_io_desc); +} diff --git a/arch/arm/mm/mm-ebsa110.c b/arch/arm/mm/mm-ebsa110.c index f16c93793..9402dfb8f 100644 --- a/arch/arm/mm/mm-ebsa110.c +++ b/arch/arm/mm/mm-ebsa110.c @@ -1,9 +1,13 @@ /* - * arch/arm/mm/mm-ebsa110.c + * linux/arch/arm/mm/mm-ebsa110.c * - * Extra MM routines for the EBSA-110 architecture + * Copyright (C) 1998-1999 Russell King * - * Copyright (C) 1998-1999 Russell King + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Extra MM routines for the EBSA-110 architecture */ #include <linux/mm.h> #include <linux/init.h> @@ -12,13 +16,15 @@ #include <asm/pgtable.h> #include <asm/page.h> -#include "map.h" +#include <asm/mach/map.h> -#define SIZE(x) (sizeof(x) / sizeof(x[0])) - -struct map_desc io_desc[] __initdata = { +static struct map_desc ebsa110_io_desc[] __initdata = { { IO_BASE - PGDIR_SIZE, 0xc0000000, PGDIR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, - { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 } + { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init ebsa110_map_io(void) +{ + iotable_init(ebsa110_io_desc); +} diff --git a/arch/arm/mm/mm-footbridge.c b/arch/arm/mm/mm-footbridge.c index 2c555f46d..b0eff7485 100644 --- a/arch/arm/mm/mm-footbridge.c +++ b/arch/arm/mm/mm-footbridge.c @@ -1,9 +1,13 @@ /* - * arch/arm/mm/mm-footbridge.c + * linux/arch/arm/mm/mm-footbridge.c * - * Extra MM routines for the EBSA285 architecture + * Copyright (C) 1998-2000 Russell King, Dave Gilbert. * - * Copyright (C) 1998-1999 Russell King, Dave Gilbert. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Extra MM routines for the EBSA285 architecture */ #include <linux/config.h> #include <linux/sched.h> @@ -13,73 +17,83 @@ #include <asm/pgtable.h> #include <asm/page.h> #include <asm/io.h> -#include <asm/dec21285.h> - -#include "map.h" +#include <asm/hardware/dec21285.h> +#include <asm/mach-types.h> -#define SIZE(x) (sizeof(x) / sizeof(x[0])) +#include <asm/mach/map.h> /* - * The first entry allows us to fiddle with the EEPROM from user-space. - * This entry will go away in time, once the fmu32 can mmap() the - * flash. It can't at the moment. - * - * If you want to fiddle with PCI VGA cards from user space, then - * change the '0, 1 }' for the PCI MEM and PCI IO to '1, 1 }' - * You can then access the PCI bus at 0xe0000000 and 0xffe00000. + * Common mapping for all systems. Note that the outbound write flush is + * commented out since there is a "No Fix" problem with it. Not mapping + * it means that we have extra bullet protection on our feet. */ - -#ifdef CONFIG_FOOTBRIDGE_HOST +static struct map_desc fb_common_io_desc[] __initdata = { + { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + LAST_DESC +}; /* - * The mapping when the footbridge is in host mode. + * The mapping when the footbridge is in host mode. We don't map any of + * this when we are in add-in mode. */ -#define MAPPING \ - { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 } - -#else +static struct map_desc ebsa285_host_io_desc[] __initdata = { +#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST) + { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, +#endif + LAST_DESC +}; /* - * The mapping when the footbridge is in add-in mode. + * The CO-ebsa285 mapping. */ -#define MAPPING \ - { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 } - +static struct map_desc co285_io_desc[] __initdata = { +#ifdef CONFIG_ARCH_CO285 + { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, #endif - -struct map_desc io_desc[] __initdata = { - MAPPING + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); - +void __init footbridge_map_io(void) +{ + struct map_desc *desc = NULL; + + /* + * Set up the common mapping first; we need this to + * determine whether we're in host mode or not. + */ + iotable_init(fb_common_io_desc); + + /* + * Now, work out what we've got to map in addition on this + * platform. + */ + if (machine_is_co285()) + desc = co285_io_desc; + else if (footbridge_cfn_mode()) + desc = ebsa285_host_io_desc; + + if (desc) + iotable_init(desc); +} #ifdef CONFIG_FOOTBRIDGE_ADDIN /* - * These two functions convert virtual addresses to PCI addresses - * and PCI addresses to virtual addresses. Note that it is only - * legal to use these on memory obtained via get_free_page or - * kmalloc. + * These two functions convert virtual addresses to PCI addresses and PCI + * addresses to virtual addresses. Note that it is only legal to use these + * on memory obtained via get_free_page or kmalloc. */ unsigned long __virt_to_bus(unsigned long res) { #ifdef CONFIG_DEBUG_ERRORS if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) { - printk("__virt_to_phys: invalid virtual address 0x%08lx\n", res); + printk("__virt_to_bus: invalid virtual address 0x%08lx\n", res); __backtrace(); } #endif @@ -93,7 +107,7 @@ unsigned long __bus_to_virt(unsigned long res) #ifdef CONFIG_DEBUG_ERRORS if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) { - printk("__phys_to_virt: invalid virtual address 0x%08lx\n", res); + printk("__bus_to_virt: invalid virtual address 0x%08lx\n", res); __backtrace(); } #endif diff --git a/arch/arm/mm/mm-l7200.c b/arch/arm/mm/mm-l7200.c index 8a252d684..bd7c6e2dd 100644 --- a/arch/arm/mm/mm-l7200.c +++ b/arch/arm/mm/mm-l7200.c @@ -1,11 +1,10 @@ /* - * arch/arm/mm/mm-lusl7200.c + * linux/arch/arm/mm/mm-lusl7200.c * - * Extra MM routines for L7200 architecture + * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) * - * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) + * Extra MM routines for L7200 architecture */ - #include <linux/init.h> #include <asm/hardware.h> @@ -13,13 +12,15 @@ #include <asm/proc/domain.h> #include <asm/setup.h> -#include "map.h" - -#define SIZE(x) (sizeof(x) / sizeof(x[0])) +#include <asm/mach/map.h> -struct map_desc io_desc[] __initdata = { +static struct map_desc l7200_io_desc[] __initdata = { { IO_BASE, IO_START, IO_SIZE, DOMAIN_IO, 0, 1 ,0 ,0}, { IO_BASE_2, IO_START_2, IO_SIZE_2, DOMAIN_IO, 0, 1 ,0 ,0}, + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init l7200_map_io(void) +{ + iotable_init(l7200_io_desc); +} diff --git a/arch/arm/mm/mm-nexuspci.c b/arch/arm/mm/mm-nexuspci.c index ccb6c8a5c..31d619433 100644 --- a/arch/arm/mm/mm-nexuspci.c +++ b/arch/arm/mm/mm-nexuspci.c @@ -1,13 +1,12 @@ /* - * arch/arm/mm/mm-nexuspci.c - * from arch/arm/mm/mm-ebsa110.c + * linux/arch/arm/mm/mm-nexuspci.c + * from linux/arch/arm/mm/mm-ebsa110.c * - * Extra MM routines for the FTV/PCI architecture + * Copyright (C) 1998-1999 Phil Blundell + * Copyright (C) 1998-1999 Russell King * - * Copyright (C) 1998-1999 Phil Blundell - * Copyright (C) 1998-1999 Russell King + * Extra MM routines for the FTV/PCI architecture */ - #include <linux/sched.h> #include <linux/mm.h> #include <linux/init.h> @@ -16,16 +15,18 @@ #include <asm/page.h> #include <asm/io.h> -#include "map.h" - -struct map_desc io_desc[] __initdata = { +#include <asm/mach/map.h> + +static struct map_desc nexuspci_io_desc[] __initdata = { { INTCONT_BASE, INTCONT_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, { PLX_BASE, PLX_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, { PCIO_BASE, PLX_IO_START, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, { DUART_BASE, DUART_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { STATUS_BASE, STATUS_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 } + { STATUS_BASE, STATUS_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, + LAST_DESC }; -#define SIZE(x) (sizeof(x) / sizeof(x[0])) - -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init nexuspci_map_io(void) +{ + iotable_init(nexuspci_io_desc); +} diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c index 494a61988..023fee8e0 100644 --- a/arch/arm/mm/mm-rpc.c +++ b/arch/arm/mm/mm-rpc.c @@ -1,9 +1,13 @@ /* - * arch/arm/mm/mm-rpc.c + * linux/arch/arm/mm/mm-rpc.c * - * Extra MM routines for RiscPC architecture + * Copyright (C) 1998-1999 Russell King * - * Copyright (C) 1998-1999 Russell King + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Extra MM routines for RiscPC architecture */ #include <linux/init.h> @@ -12,17 +16,16 @@ #include <asm/proc/domain.h> #include <asm/setup.h> -#include "map.h" - -#define SIZE(x) (sizeof(x) / sizeof(x[0])) +#include <asm/mach/map.h> -struct map_desc io_desc[] __initdata = { - /* VRAM */ - { SCREEN_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 }, - /* IO space */ - { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, - /* EASI space */ - { EASI_BASE, EASI_START, EASI_SIZE, DOMAIN_IO, 0, 1, 0, 0 } +static struct map_desc rpc_io_desc[] __initdata = { + { SCREEN_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 }, /* VRAM */ + { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, /* IO space */ + { EASI_BASE, EASI_START, EASI_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, /* EASI space */ + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init rpc_map_io(void) +{ + iotable_init(rpc_io_desc); +} diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c index aaf28f880..54fe435c6 100644 --- a/arch/arm/mm/mm-sa1100.c +++ b/arch/arm/mm/mm-sa1100.c @@ -1,20 +1,19 @@ /* - * arch/arm/mm/mm-sa1100.c + * linux/arch/arm/mm/mm-sa1100.c * - * Extra MM routines for the SA1100 architecture + * Copyright (C) 1998-1999 Russell King + * Copyright (C) 1999 Hugo Fiennes * - * Copyright (C) 1998-1999 Russell King - * Copyright (C) 1999 Hugo Fiennes + * Extra MM routines for the SA1100 architecture * - * 1999/12/04 Nicolas Pitre <nico@cam.org> + * 1999/12/04 Nicolas Pitre <nico@cam.org> * Converted memory definition for struct meminfo initialisations. * Memory is listed physically now. * - * 2000/04/07 Nicolas Pitre <nico@cam.org> + * 2000/04/07 Nicolas Pitre <nico@cam.org> * Reworked for run-time selection of memory definitions * */ - #include <linux/config.h> #include <linux/mm.h> #include <linux/init.h> @@ -25,171 +24,158 @@ #include <asm/page.h> #include <asm/mach-types.h> -#include "map.h" +#include <asm/mach/map.h> -#define SIZE(x) (sizeof(x) / sizeof(x[0])) - - -#define SA1100_STD_IO_MAPPING \ +static struct map_desc standard_io_desc[] __initdata = { /* virtual physical length domain r w c b */ \ - { 0xe0000000, 0x20000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 IO */ \ - { 0xe4000000, 0x30000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 IO */ \ - { 0xe8000000, 0x28000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 attr */ \ - { 0xec000000, 0x38000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 attr */ \ - { 0xf0000000, 0x2c000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 mem */ \ - { 0xf4000000, 0x3c000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 mem */ \ - { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */ \ - { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */ \ - { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */ \ - { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 } /* LCD + DMA */ + { 0xf6000000, 0x20000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 IO */ + { 0xf7000000, 0x30000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 IO */ + { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */ + { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */ + { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */ + { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* LCD + DMA */ + LAST_DESC +}; +/* + * Typically, static virtual address mappings are as follow: + * + * 0xe8000000-0xefffffff: flash memory (especially when multiple flash + * banks need to be mapped contigously) + * 0xf0000000-0xf3ffffff: miscellaneous stuff (CPLDs, etc.) + * 0xf4000000-0xf4ffffff: SA-1111 + * 0xf5000000-0xf5ffffff: reserved (used by cache flushing area) + * 0xf6000000-0xffffffff: reserved (internal SA1100 IO defined above) + * + * Below 0xe8000000 is reserved for vm allocation. + */ static struct map_desc assabet_io_desc[] __initdata = { #ifdef CONFIG_SA1100_ASSABET - { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ - { 0xd4000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */ - { 0xdc000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */ - { 0xd8000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */ - SA1100_STD_IO_MAPPING -#endif -}; - -static struct map_desc nanoengine_io_desc[] __initdata = { -#ifdef CONFIG_SA1100_NANOENGINE - { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ - { 0xd4000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */ - { 0xdc000000, 0x18A00000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Internal PCI Config Space */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */ + { 0xf1000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */ + { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* MQ200 */ + { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */ #endif + LAST_DESC }; static struct map_desc bitsy_io_desc[] __initdata = { #ifdef CONFIG_SA1100_BITSY - { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ - { 0xdc000000, 0x49000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* EGPIO 0 */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + { 0xf0000000, 0x49000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* EGPIO 0 */ #endif + LAST_DESC }; static struct map_desc cerf_io_desc[] __initdata = { #ifdef CONFIG_SA1100_CERF - { 0xd8000000, 0x08000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Crystal Chip */ - { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + { 0xf0000000, 0x08000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Crystal Chip */ #endif + LAST_DESC }; static struct map_desc empeg_io_desc[] __initdata = { #ifdef CONFIG_SA1100_EMPEG { EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ - SA1100_STD_IO_MAPPING #endif + LAST_DESC }; static struct map_desc graphicsclient_io_desc[] __initdata = { #ifdef CONFIG_SA1100_GRAPHICSCLIENT - { 0xd0000000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ - { 0xd0800000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 3 */ - { 0xdc000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ + { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */ #endif + LAST_DESC }; static struct map_desc lart_io_desc[] __initdata = { #ifdef CONFIG_SA1100_LART - { 0xd0000000, 0x00000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash memory */ - { 0xd8000000, 0x08000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash, alternative location */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash memory */ + { 0xec000000, 0x08000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash, alternative location */ #endif + LAST_DESC +}; + +static struct map_desc nanoengine_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_NANOENGINE + { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */ + { 0xf1000000, 0x18A00000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Internal PCI Config Space */ +#endif + LAST_DESC }; static struct map_desc thinclient_io_desc[] __initdata = { #ifdef CONFIG_SA1100_THINCLIENT #if 0 - { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 when JP1 2-4 */ + { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 when JP1 2-4 */ #else - { 0xd0000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 when JP1 3-4 */ + { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 when JP1 3-4 */ #endif - { 0xdc000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */ - SA1100_STD_IO_MAPPING + { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */ #endif + LAST_DESC }; static struct map_desc tifon_io_desc[] __initdata = { #ifdef CONFIG_SA1100_TIFON - { 0xd0000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ - { 0xd0800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ + { 0xe8800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */ #endif + LAST_DESC }; static struct map_desc victor_io_desc[] __initdata = { #ifdef CONFIG_SA1100_VICTOR - { 0xd0000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ #endif + LAST_DESC }; static struct map_desc xp860_io_desc[] __initdata = { #ifdef CONFIG_SA1100_XP860 - { 0xd8000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */ - { 0xda000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SCSI */ - { 0xdc000000, 0x18000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* LAN */ - SA1100_STD_IO_MAPPING + { 0xf4000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */ + { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SCSI */ + { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* LAN */ #endif + LAST_DESC }; -static struct map_desc default_io_desc[] __initdata = { - SA1100_STD_IO_MAPPING -}; - - -/* - * Here it would be wiser to simply assign a pointer to the appropriate - * list, but io_desc is already declared as an array in "map.h". - */ -struct map_desc io_desc[20] __initdata = {}; -unsigned int io_desc_size; - -void __init select_sa1100_io_desc(void) +void __init sa1100_map_io(void) { - if( machine_is_assabet() ) { - memcpy( io_desc, assabet_io_desc, sizeof(assabet_io_desc) ); - io_desc_size = SIZE(assabet_io_desc); - } else if( machine_is_nanoengine() ) { - memcpy( io_desc, nanoengine_io_desc, sizeof(nanoengine_io_desc) ); - io_desc_size = SIZE(nanoengine_io_desc); - } else if( machine_is_bitsy() ) { - memcpy( io_desc, bitsy_io_desc, sizeof(bitsy_io_desc) ); - io_desc_size = SIZE(bitsy_io_desc); - } else if( machine_is_cerf() ) { - memcpy( io_desc, cerf_io_desc, sizeof(cerf_io_desc) ); - io_desc_size = SIZE(cerf_io_desc); - } else if( machine_is_empeg() ) { - memcpy( io_desc, empeg_io_desc, sizeof(empeg_io_desc) ); - io_desc_size = SIZE(empeg_io_desc); - } else if( machine_is_graphicsclient() ) { - memcpy( io_desc, graphicsclient_io_desc, sizeof(graphicsclient_io_desc) ); - io_desc_size = SIZE(graphicsclient_io_desc); - } else if( machine_is_lart() ) { - memcpy( io_desc, lart_io_desc, sizeof(lart_io_desc) ); - io_desc_size = SIZE(lart_io_desc); - } else if( machine_is_thinclient() ) { - memcpy( io_desc, thinclient_io_desc, sizeof(thinclient_io_desc) ); - io_desc_size = SIZE(thinclient_io_desc); - } else if( machine_is_tifon() ) { - memcpy( io_desc, tifon_io_desc, sizeof(tifon_io_desc) ); - io_desc_size = SIZE(tifon_io_desc); - } else if( machine_is_victor() ) { - memcpy( io_desc, victor_io_desc, sizeof(victor_io_desc) ); - io_desc_size = SIZE(victor_io_desc); - } else if( machine_is_xp860() ) { - memcpy( io_desc, xp860_io_desc, sizeof(xp860_io_desc) ); - io_desc_size = SIZE(xp860_io_desc); - } else { - memcpy( io_desc, default_io_desc, sizeof(default_io_desc) ); - io_desc_size = SIZE(default_io_desc); - } + struct map_desc *desc = NULL; + + iotable_init(standard_io_desc); + + if (machine_is_assabet()) + desc = assabet_io_desc; + else if (machine_is_nanoengine()) + desc = nanoengine_io_desc; + else if (machine_is_bitsy()) + desc = bitsy_io_desc; + else if (machine_is_cerf()) + desc = cerf_io_desc; + else if (machine_is_empeg()) + desc = empeg_io_desc; + else if (machine_is_graphicsclient()) + desc = graphicsclient_io_desc; + else if (machine_is_lart()) + desc = lart_io_desc; + else if (machine_is_thinclient()) + desc = thinclient_io_desc; + else if (machine_is_tifon()) + desc = tifon_io_desc; + else if (machine_is_victor()) + desc = victor_io_desc; + else if (machine_is_xp860()) + desc = xp860_io_desc; + + if (desc) + iotable_init(desc); } diff --git a/arch/arm/mm/mm-shark.c b/arch/arm/mm/mm-shark.c deleted file mode 100644 index dc8e6e12b..000000000 --- a/arch/arm/mm/mm-shark.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * arch/arm/mm/mm-shark.c - * - * by Alexander.Schulz@stud.uni-karlsruhe.de - */ -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/init.h> - -#include <asm/pgtable.h> -#include <asm/page.h> -#include <asm/io.h> - -#include "map.h" - -struct map_desc io_desc[] __initdata = { - { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, - { FB_BASE , FB_START , FB_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, - { FBREG_BASE , FBREG_START , FBREG_SIZE , DOMAIN_IO, 0, 1, 0, 0 } -}; - - -#define SIZEOFMAP (sizeof(io_desc) / sizeof(io_desc[0])) - -unsigned int __initdata io_desc_size = SIZEOFMAP; diff --git a/arch/arm/mm/mm-tbox.c b/arch/arm/mm/mm-tbox.c index 78250336e..e927d05d3 100644 --- a/arch/arm/mm/mm-tbox.c +++ b/arch/arm/mm/mm-tbox.c @@ -1,13 +1,11 @@ /* - * arch/arm/mm/mm-tbox.c - * from arch/arm/mm/mm-ebsa110.c + * linux/arch/arm/mm/mm-tbox.c * - * Extra MM routines for the Tbox architecture + * Copyright (C) 1998, 1999, 2000 Phil Blundell + * Copyright (C) 1998-1999 Russell King * - * Copyright (C) 1998 Phil Blundell - * Copyright (C) 1998-1999 Russell King + * Extra MM routines for the Tbox architecture */ - #include <linux/sched.h> #include <linux/mm.h> #include <linux/init.h> @@ -16,44 +14,15 @@ #include <asm/pgtable.h> #include <asm/page.h> -#include "map.h" +#include <asm/mach/map.h> -#define SIZE(x) (sizeof(x) / sizeof(x[0])) - -/* Logical Physical - * 0xffff1000 0x00100000 DMA registers - * 0xffff2000 0x00200000 MPEG - * 0xffff3000 0x00300000 FPGA1 local control - * 0xffff4000 0x00400000 External serial - * 0xffff5000 0x00500000 Internal serial - * 0xffff6000 0x00600000 Parallel - * 0xffff7000 0x00700000 Interrupt control - * 0xffff8000 0x00800000 Computer video - * 0xffff9000 0x00900000 Control register 0 - * 0xffffs000 0x00a00000 Control register 1 - * 0xffffb000 0x00b00000 Control register 2 - * 0xffffc000 0x00c00000 FPGA2 local control - * 0xffffd000 0x00d00000 Interrupt reset - * 0xffffe000 0x00e00000 MPEG DMA throttle - */ - -const struct map_desc io_desc[] __initdata = { - { 0xffff0000, 0x01000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff1000, 0x00100000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff2000, 0x00200000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff3000, 0x00300000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff4000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xfe000000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff5000, 0x00500000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff6000, 0x00600000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff7000, 0x00700000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff8000, 0x00800000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff9000, 0x00900000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffffa000, 0x00a00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffffb000, 0x00b00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffffc000, 0x00c00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffffd000, 0x00d00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffffe000, 0x00e00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 } +static struct map_desc tbox_io_desc[] __initdata = { + /* See hardware.h for details */ + { IO_BASE, IO_START, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init tbox_map_io(void) +{ + iotable_init(tbox_io_desc); +} diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S index 6dd48c919..76377cf9c 100644 --- a/arch/arm/mm/proc-arm2,3.S +++ b/arch/arm/mm/proc-arm2,3.S @@ -1,10 +1,16 @@ /* - * linux/arch/arm/mm/proc-arm2,3.S: MMU functions for ARM2,3 + * linux/arch/arm/mm/proc-arm2,3.S * - * (C) 1997-1999 Russell King + * Copyright (C) 1997-1999 Russell King * - * These are the low level assembler for performing cache - * and memory functions on ARM2, ARM250 and ARM3 processors. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * MMU functions for ARM2,3 + * + * These are the low level assembler for performing cache + * and memory functions on ARM2, ARM250 and ARM3 processors. */ #include <linux/linkage.h> #include <asm/assembler.h> diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S index b18d69d98..61e135e19 100644 --- a/arch/arm/mm/proc-arm6,7.S +++ b/arch/arm/mm/proc-arm6,7.S @@ -1,20 +1,25 @@ /* - * linux/arch/arm/mm/proc-arm6,7.S: MMU functions for ARM6 + * linux/arch/arm/mm/proc-arm6,7.S * - * (C) 1997-2000 Russell King + * Copyright (C) 1997-2000 Russell King * - * These are the low level assembler for performing cache and TLB - * functions on the ARM6 & ARM7. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * MMU functions for ARM6 + * + * These are the low level assembler for performing cache and TLB + * functions on the ARM6 & ARM7. */ #include <linux/linkage.h> #include <asm/assembler.h> #include <asm/procinfo.h> -#include <asm/errno.h> #include "../lib/constants.h" /* - * Function: arm6_7_flush_cache_all (void) - * : arm6_7_flush_cache_page (unsigned long address, int size, int flags) + * Function: arm6_7_cache_clean_invalidate_all (void) + * : arm6_7_cache_clean_invalidate_page (unsigned long address, int size, int flags) * * Params : address Area start address * : size size of area @@ -22,41 +27,41 @@ * * Purpose : Flush all cache lines */ -ENTRY(cpu_arm6_flush_cache_all) -ENTRY(cpu_arm7_flush_cache_all) -ENTRY(cpu_arm6_flush_cache_area) -ENTRY(cpu_arm7_flush_cache_area) -ENTRY(cpu_arm6_flush_cache_entry) -ENTRY(cpu_arm7_flush_cache_entry) -ENTRY(cpu_arm6_flush_icache_area) -ENTRY(cpu_arm7_flush_icache_area) -ENTRY(cpu_arm6_flush_icache_page) -ENTRY(cpu_arm7_flush_icache_page) -ENTRY(cpu_arm6_cache_wback_area) -ENTRY(cpu_arm7_cache_wback_area) -ENTRY(cpu_arm6_cache_purge_area) -ENTRY(cpu_arm7_cache_purge_area) +ENTRY(cpu_arm6_cache_clean_invalidate_all) +ENTRY(cpu_arm7_cache_clean_invalidate_all) +ENTRY(cpu_arm6_cache_clean_invalidate_range) +ENTRY(cpu_arm7_cache_clean_invalidate_range) +ENTRY(cpu_arm6_invalidate_icache_range) +ENTRY(cpu_arm7_invalidate_icache_range) +ENTRY(cpu_arm6_invalidate_icache_page) +ENTRY(cpu_arm7_invalidate_icache_page) +ENTRY(cpu_arm6_dcache_clean_range) +ENTRY(cpu_arm7_dcache_clean_range) +ENTRY(cpu_arm6_dcache_invalidate_range) +ENTRY(cpu_arm7_dcache_invalidate_range) mov r0, #0 mcr p15, 0, r0, c7, c0, 0 @ flush cache -ENTRY(cpu_arm6_clean_cache_area) -ENTRY(cpu_arm7_clean_cache_area) +ENTRY(cpu_arm6_dcache_clean_page) +ENTRY(cpu_arm7_dcache_clean_page) +ENTRY(cpu_arm6_dcache_clean_entry) +ENTRY(cpu_arm7_dcache_clean_entry) ENTRY(cpu_arm6_flush_ram_page) ENTRY(cpu_arm7_flush_ram_page) mov pc, lr /* - * Function: arm6_7_flush_tlb_all (void) + * Function: arm6_7_tlb_invalidate_all (void) * * Purpose : flush all TLB entries in all caches */ -ENTRY(cpu_arm6_flush_tlb_all) -ENTRY(cpu_arm7_flush_tlb_all) +ENTRY(cpu_arm6_tlb_invalidate_all) +ENTRY(cpu_arm7_tlb_invalidate_all) mov r0, #0 mcr p15, 0, r0, c5, c0, 0 @ flush TLB mov pc, lr /* - * Function: arm6_7_flush_tlb_page (unsigned long address, int end, int flags) + * Function: arm6_7_tlb_invalidate_page (unsigned long address, int end, int flags) * * Params : address Area start address * : end Area end address @@ -64,8 +69,8 @@ ENTRY(cpu_arm7_flush_tlb_all) * * Purpose : flush a TLB entry */ -ENTRY(cpu_arm6_flush_tlb_area) -ENTRY(cpu_arm7_flush_tlb_area) +ENTRY(cpu_arm6_tlb_invalidate_range) +ENTRY(cpu_arm7_tlb_invalidate_range) 1: mcr p15, 0, r0, c6, c0, 0 @ flush TLB add r0, r0, #4096 cmp r0, r1 @@ -73,15 +78,15 @@ ENTRY(cpu_arm7_flush_tlb_area) mov pc, lr /* - * Function: arm6_7_flush_tlb_page (unsigned long address, int flags) + * Function: arm6_7_tlb_invalidate_page (unsigned long address, int flags) * * Params : address Address * : flags b0 = I-TLB as well * * Purpose : flush a TLB entry */ -ENTRY(cpu_arm6_flush_tlb_page) -ENTRY(cpu_arm7_flush_tlb_page) +ENTRY(cpu_arm6_tlb_invalidate_page) +ENTRY(cpu_arm7_tlb_invalidate_page) mcr p15, 0, r0, c6, c0, 0 @ flush TLB mov pc, lr @@ -392,23 +397,33 @@ ENTRY(arm6_processor_functions) .word cpu_arm6_check_bugs .word cpu_arm6_proc_init .word cpu_arm6_proc_fin - .word cpu_arm6_flush_cache_all - .word cpu_arm6_flush_cache_area - .word cpu_arm6_flush_cache_entry - .word cpu_arm6_clean_cache_area + .word cpu_arm6_reset + .word cpu_arm6_do_idle + + /* cache */ + .word cpu_arm6_cache_clean_invalidate_all + .word cpu_arm6_cache_clean_invalidate_range .word cpu_arm6_flush_ram_page - .word cpu_arm6_flush_tlb_all - .word cpu_arm6_flush_tlb_area + + /* dcache */ + .word cpu_arm6_dcache_invalidate_range + .word cpu_arm6_dcache_clean_range + .word cpu_arm6_dcache_clean_page + .word cpu_arm6_dcache_clean_entry + + /* icache */ + .word cpu_arm6_invalidate_icache_range + .word cpu_arm6_invalidate_icache_page + + /* tlb */ + .word cpu_arm6_tlb_invalidate_all + .word cpu_arm6_tlb_invalidate_range + .word cpu_arm6_tlb_invalidate_page + + /* pgtable */ .word cpu_arm6_set_pgd .word cpu_arm6_set_pmd .word cpu_arm6_set_pte - .word cpu_arm6_reset - .word cpu_arm6_flush_icache_area - .word cpu_arm6_cache_wback_area - .word cpu_arm6_cache_purge_area - .word cpu_arm6_flush_tlb_page - .word cpu_arm6_do_idle - .word cpu_arm6_flush_icache_page .size arm6_processor_functions, . - arm6_processor_functions /* @@ -421,23 +436,33 @@ ENTRY(arm7_processor_functions) .word cpu_arm7_check_bugs .word cpu_arm7_proc_init .word cpu_arm7_proc_fin - .word cpu_arm7_flush_cache_all - .word cpu_arm7_flush_cache_area - .word cpu_arm7_flush_cache_entry - .word cpu_arm7_clean_cache_area + .word cpu_arm7_reset + .word cpu_arm7_do_idle + + /* cache */ + .word cpu_arm7_cache_clean_invalidate_all + .word cpu_arm7_cache_clean_invalidate_range .word cpu_arm7_flush_ram_page - .word cpu_arm7_flush_tlb_all - .word cpu_arm7_flush_tlb_area + + /* dcache */ + .word cpu_arm7_dcache_invalidate_range + .word cpu_arm7_dcache_clean_range + .word cpu_arm7_dcache_clean_page + .word cpu_arm7_dcache_clean_entry + + /* icache */ + .word cpu_arm7_invalidate_icache_range + .word cpu_arm7_invalidate_icache_page + + /* tlb */ + .word cpu_arm7_tlb_invalidate_all + .word cpu_arm7_tlb_invalidate_range + .word cpu_arm7_tlb_invalidate_page + + /* pgtable */ .word cpu_arm7_set_pgd .word cpu_arm7_set_pmd .word cpu_arm7_set_pte - .word cpu_arm7_reset - .word cpu_arm7_flush_icache_area - .word cpu_arm7_cache_wback_area - .word cpu_arm7_cache_purge_area - .word cpu_arm7_flush_tlb_page - .word cpu_arm7_do_idle - .word cpu_arm7_flush_icache_page .size arm7_processor_functions, . - arm7_processor_functions .type cpu_arm6_info, #object @@ -479,7 +504,7 @@ cpu_elf_name: .asciz "v3" __arm6_proc_info: .long 0x41560600 .long 0xfffffff0 - .long 0x00000c12 + .long 0x00000c1e b __arm6_setup .long cpu_arch_name .long cpu_elf_name @@ -492,7 +517,7 @@ __arm6_proc_info: __arm610_proc_info: .long 0x41560610 .long 0xfffffff0 - .long 0x00000c12 + .long 0x00000c1e b __arm6_setup .long cpu_arch_name .long cpu_elf_name @@ -505,7 +530,7 @@ __arm610_proc_info: __arm7_proc_info: .long 0x41007000 .long 0xffffff00 - .long 0x00000c12 + .long 0x00000c1e b __arm7_setup .long cpu_arch_name .long cpu_elf_name @@ -518,7 +543,7 @@ __arm7_proc_info: __arm710_proc_info: .long 0x41007100 .long 0xfff8ff00 - .long 0x00000c12 + .long 0x00000c1e b __arm7_setup .long cpu_arch_name .long cpu_elf_name diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S index 262a4fd8b..13620ad5f 100644 --- a/arch/arm/mm/proc-arm720.S +++ b/arch/arm/mm/proc-arm720.S @@ -1,27 +1,44 @@ /* - * linux/arch/arm/mm/proc-arm720.S: MMU functions for ARM720 + * linux/arch/arm/mm/proc-arm720.S: MMU functions for ARM720 + * + * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) + * Rob Scott (rscott@mtrob.fdns.net) + * Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd. + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) - * Rob Scott (rscott@mtrob.fdns.net) * * These are the low level assembler for performing cache and TLB - * functions on the ARM720T. + * functions on the ARM720T. The ARM720T has a writethrough IDC + * cache, so we don't need to clean it. * - * Changelog: - * 05-09-2000 SJH Created by moving 720 specific functions - * out of 'proc-arm6,7.S' per RSK discussion - * 07-25-2000 SJH Added idle function. + * Changelog: + * 05-09-2000 SJH Created by moving 720 specific functions + * out of 'proc-arm6,7.S' per RMK discussion + * 07-25-2000 SJH Added idle function. + * 08-25-2000 DBS Updated for integration of ARM Ltd version. */ #include <linux/linkage.h> #include <asm/assembler.h> #include <asm/procinfo.h> -#include <asm/errno.h> #include <asm/hardware.h> #include "../lib/constants.h" /* - * Function: arm720_flush_cache_all (void) - * : arm720_flush_cache_page (unsigned long address, int size, + * Function: arm720_cache_clean_invalidate_all (void) + * : arm720_cache_clean_invalidate_page (unsigned long address, int size, * int flags) * * Params : address Area start address @@ -30,33 +47,37 @@ * * Purpose : Flush all cache lines */ -ENTRY(cpu_arm720_flush_cache_all) -ENTRY(cpu_arm720_flush_cache_area) -ENTRY(cpu_arm720_flush_cache_entry) -ENTRY(cpu_arm720_flush_icache_area) -ENTRY(cpu_arm720_flush_icache_page) -ENTRY(cpu_arm720_cache_wback_area) -ENTRY(cpu_arm720_cache_purge_area) +ENTRY(cpu_arm720_cache_clean_invalidate_all) +ENTRY(cpu_arm720_cache_clean_invalidate_range) +ENTRY(cpu_arm720_icache_invalidate_range) +ENTRY(cpu_arm720_icache_invalidate_page) +ENTRY(cpu_arm720_dcache_invalidate_range) mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ flush cache mov pc, lr -ENTRY(cpu_arm720_clean_cache_area) +/* + * These just expect cache lines to be cleaned. Since we have a writethrough + * cache, we never have any dirty cachelines to worry about. + */ +ENTRY(cpu_arm720_dcache_clean_range) +ENTRY(cpu_arm720_dcache_clean_page) +ENTRY(cpu_arm720_dcache_clean_entry) ENTRY(cpu_arm720_flush_ram_page) mov pc, lr /* - * Function: arm720_flush_tlb_all (void) + * Function: arm720_tlb_invalidate_all (void) * * Purpose : flush all TLB entries in all caches */ -ENTRY(cpu_arm720_flush_tlb_all) +ENTRY(cpu_arm720_tlb_invalidate_all) mov r0, #0 mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) mov pc, lr /* - * Function: arm720_flush_tlb_page (unsigned long address, int end, int flags) + * Function: arm720_tlb_invalidate_page (unsigned long address, int end, int flags) * * Params : address Area start address * : end Area end address @@ -64,7 +85,7 @@ ENTRY(cpu_arm720_flush_tlb_all) * * Purpose : flush a TLB entry */ -ENTRY(cpu_arm720_flush_tlb_area) +ENTRY(cpu_arm720_tlb_invalidate_range) 1: mcr p15, 0, r0, c8, c7, 1 @ flush TLB (v4) add r0, r0, #4096 cmp r0, r1 @@ -72,14 +93,14 @@ ENTRY(cpu_arm720_flush_tlb_area) mov pc, lr /* - * Function: arm720_flush_tlb_page (unsigned long address, int flags) + * Function: arm720_tlb_invalidate_page (unsigned long address, int flags) * * Params : address Address * : flags b0 = I-TLB as well * * Purpose : flush a TLB entry */ -ENTRY(cpu_arm720_flush_tlb_page) +ENTRY(cpu_arm720_tlb_invalidate_page) mcr p15, 0, r0, c8, c7, 1 @ flush TLB (v4) mov pc, lr @@ -262,12 +283,15 @@ ENTRY(cpu_arm720_proc_init) mov pc, lr ENTRY(cpu_arm720_proc_fin) - mrs r0, cpsr - orr r0, r0, #F_BIT | I_BIT - msr cpsr, r0 - mov r0, #0x31 @ ....S..DP...M + stmfd sp!, {lr} + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. mcr p15, 0, r0, c1, c0, 0 @ disable caches - mov pc, lr + mcr p15, 0, r1, c7, c7, 0 @ invalidate cache + ldmfd sp!, {pc} /* * Function: arm720_proc_do_idle (void) @@ -281,10 +305,12 @@ ENTRY(cpu_arm720_proc_fin) * Purpose : put the processer in proper idle mode */ ENTRY(cpu_arm720_do_idle) +#if 0 /* FIXME: is this part of the processor? */ ldr r2, =IO_BASE @ Virt addr of IO add r2, r2, #0x00050000 @ Start of PMU regs mov r1, #0x01 @ Idle mode - str r1, [r2, #4] + str r1, [r2, #4] +#endif mov pc, lr /* @@ -295,7 +321,7 @@ ENTRY(cpu_arm720_do_idle) */ ENTRY(cpu_arm720_set_pgd) mov r1, #0 - mcr p15, 0, r1, c7, c7, 0 @ flush cache + mcr p15, 0, r1, c7, c7, 0 @ invalidate cache mcr p15, 0, r0, c2, c0, 0 @ update page table ptr mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4) mov pc, lr @@ -340,9 +366,6 @@ ENTRY(cpu_arm720_set_pte) movne r2, #0 str r2, [r0] @ hardware version - - mcr p15, 0, r0, c7, c7, 0 @ flush cache - mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) mov pc, lr /* @@ -351,30 +374,37 @@ ENTRY(cpu_arm720_set_pte) * Notes : This sets up everything for a reset */ ENTRY(cpu_arm720_reset) - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 @ flush cache - mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) - mov pc, lr + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate cache + mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) + mrc p15, 0, ip, c1, c0, 0 @ get ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x2100 @ ..v....s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 cpu_armvlsi_name: .asciz "ARM/VLSI" cpu_arm720_name: - .asciz "ARM 720" + .asciz "ARM720T" .align .section ".text.init", #alloc, #execinstr __arm720_setup: mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 @ flush caches on v4 + mcr p15, 0, r0, c7, c7, 0 @ invalidate caches mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) mcr p15, 0, r4, c2, c0 @ load page table pointer mov r0, #0x1f @ Domains 0, 1 = client mcr p15, 0, r0, c3, c0 @ load domain access register - - /* Set CP15 Control reg bits (RSBLDPWCAM) */ - mov r0, #0x7d @ ...LDPWC.M - orr r0, r0, #0x100 @ .S.LDPWC.M + + mrc p15, 0, r0, c1, c0 @ get control register + bic r0, r0, #0x2e00 + bic r0, r0, #0x000e + orr r0, r0, #0x0031 @ ..V...RSBLDPWCAM + orr r0, r0, #0x0100 @ .........111.... (old) + orr r0, r0, #0x000c @ ..0...01..111101 (new) mov pc, lr @ __ret (head-armv.S) /* @@ -387,23 +417,33 @@ ENTRY(arm720_processor_functions) .word cpu_arm720_check_bugs .word cpu_arm720_proc_init .word cpu_arm720_proc_fin - .word cpu_arm720_flush_cache_all - .word cpu_arm720_flush_cache_area - .word cpu_arm720_flush_cache_entry - .word cpu_arm720_clean_cache_area + .word cpu_arm720_reset + .word cpu_arm720_do_idle + + /* cache */ + .word cpu_arm720_cache_clean_invalidate_all + .word cpu_arm720_cache_clean_invalidate_range .word cpu_arm720_flush_ram_page - .word cpu_arm720_flush_tlb_all - .word cpu_arm720_flush_tlb_area + + /* dcache */ + .word cpu_arm720_dcache_invalidate_range + .word cpu_arm720_dcache_clean_range + .word cpu_arm720_dcache_clean_page + .word cpu_arm720_dcache_clean_entry + + /* icache */ + .word cpu_arm720_icache_invalidate_range + .word cpu_arm720_icache_invalidate_page + + /* tlb */ + .word cpu_arm720_tlb_invalidate_all + .word cpu_arm720_tlb_invalidate_range + .word cpu_arm720_tlb_invalidate_page + + /* pgtable */ .word cpu_arm720_set_pgd .word cpu_arm720_set_pmd .word cpu_arm720_set_pte - .word cpu_arm720_reset - .word cpu_arm720_flush_icache_area - .word cpu_arm720_cache_wback_area - .word cpu_arm720_cache_purge_area - .word cpu_arm720_flush_tlb_page - .word cpu_arm720_do_idle - .word cpu_arm720_flush_icache_page .size arm720_processor_functions, . - arm720_processor_functions .type cpu_arm720_info, #object @@ -431,11 +471,11 @@ cpu_elf_name: .asciz "v4" __arm720_proc_info: .long 0x41807200 @ cpu_val .long 0xffffff00 @ cpu_mask - .long 0x00000c12 @ __cpu_mmu_flags + .long 0x00000c0e @ __cpu_mmu_flags b __arm720_setup @ --cpu_flush .long cpu_arch_name @ arch_name .long cpu_elf_name @ elf_name - .long HWCAP_SWP | HWCAP_26BIT @ elf_hwcap + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT @ elf_hwcap .long cpu_arm720_info @ info .long arm720_processor_functions .size __arm720_proc_info, . - __arm720_proc_info diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S new file mode 100644 index 000000000..a4306f08a --- /dev/null +++ b/arch/arm/mm/proc-arm920.S @@ -0,0 +1,602 @@ +/* + * linux/arch/arm/mm/arm920.S: MMU functions for ARM920 + * + * Copyright (C) 1999,2000 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd. + * + * 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. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * These are the low level assembler for performing cache and TLB + * functions on the arm920. + */ +#include <linux/linkage.h> +#include <linux/config.h> +#include <asm/assembler.h> +#include <asm/procinfo.h> +#include <asm/hardware.h> +#include "../lib/constants.h" + +/* + * This is the maximum size of an area which will be invalidated + * using the single invalidate entry instructions. Anything larger + * than this, and we go for the whole cache. + * + * This value should be chosen such that we choose the cheapest + * alternative. + */ +#define MAX_AREA_SIZE 16384 + +/* + * the cache line size of the I and D cache + */ +#define DCACHELINESIZE 32 +#define ICACHELINESIZE 32 + +/* + * and the page size + */ +#define PAGESIZE 4096 + + .text + +/* + * cpu_arm920_data_abort() + * + * obtain information about current aborted instruction + * + * r0 = address of aborted instruction + * + * Returns: + * r0 = address of abort + * r1 != 0 if writing + * r3 = FSR + */ + .align 5 +ENTRY(cpu_arm920_data_abort) + ldr r1, [r0] @ read aborted instruction + mrc p15, 0, r0, c6, c0, 0 @ get FAR + mov r1, r1, lsr #19 @ b1 = L + mrc p15, 0, r3, c5, c0, 0 @ get FSR + and r1, r1, #2 + and r3, r3, #255 + mov pc, lr + +/* + * cpu_arm920_check_bugs() + */ +ENTRY(cpu_arm920_check_bugs) + mrs ip, cpsr + bic ip, ip, #F_BIT + msr cpsr, ip + mov pc, lr + +/* + * cpu_arm920_proc_init() + */ +ENTRY(cpu_arm920_proc_init) + mov pc, lr + +/* + * cpu_arm920_proc_fin() + */ +ENTRY(cpu_arm920_proc_fin) + stmfd sp!, {lr} + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip + bl cpu_arm920_cache_clean_invalidate_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm920_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm920_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm920_do_idle() + */ + .align 5 +ENTRY(cpu_arm920_do_idle) +#if defined(CONFIG_CPU_ARM920_CPU_IDLE) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt +#endif + mov pc, lr + +/* ================================= CACHE ================================ */ + + +/* + * cpu_arm920_cache_clean_invalidate_all() + * + * clean and invalidate all cache lines + * + * Note: + * 1. we should preserve r0 at all times + */ + .align 5 +ENTRY(cpu_arm920_cache_clean_invalidate_all) + mov r2, #1 +cpu_arm920_cache_clean_invalidate_all_r2: + mov ip, #0 +#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +/* + * 'Clean & Invalidate whole DCache' + * Re-written to use Index Ops. + * Uses registers r1, r3 and ip + */ + mov r1, #7 << 5 @ 8 segments +1: orr r3, r1, #63 << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 7 to 0 +#endif + teq r2, #0 + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm920_cache_clean_invalidate_range(start, end, flags) + * + * clean and invalidate all cache lines associated with this area of memory + * + * start: Area start address + * end: Area end address + * flags: nonzero for I cache as well + */ + .align 5 +ENTRY(cpu_arm920_cache_clean_invalidate_range) + bic r0, r0, #DCACHELINESIZE - 1 @ && added by PGM + sub r3, r1, r0 + cmp r3, #MAX_AREA_SIZE + bgt cpu_arm920_cache_clean_invalidate_all_r2 +1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blt 1b + teq r2, #0 + movne r0, #0 + mcrne p15, 0, r0, c7, c5, 0 @ invalidate I cache + mov pc, lr + +/* + * cpu_arm920_flush_ram_page(page) + * + * clean and invalidate all cache lines associated with this area of memory + * + * page: page to clean and invalidate + */ + .align 5 +ENTRY(cpu_arm920_flush_ram_page) + mov r1, #PAGESIZE +1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bne 1b + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ D-CACHE =============================== */ + +/* + * cpu_arm920_dcache_invalidate_range(start, end) + * + * throw away all D-cached data in specified region without an obligation + * to write them back. Note however that we must clean the D-cached entries + * around the boundaries if the start and/or end address are not cache + * aligned. + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm920_dcache_invalidate_range) + tst r0, #DCACHELINESIZE - 1 + bic r0, r0, #DCACHELINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #DCACHELINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blt 1b + mov pc, lr + +/* + * cpu_arm920_dcache_clean_range(start, end) + * + * For the specified virtual address range, ensure that all caches contain + * clean data, such that peripheral accesses to the physical RAM fetch + * correct data. + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm920_dcache_clean_range) + bic r0, r0, #DCACHELINESIZE - 1 + sub r1, r1, r0 + cmp r1, #MAX_AREA_SIZE + mov r2, #0 + bgt cpu_arm920_cache_clean_invalidate_all_r2 + +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bpl 1b + mcr p15, 0, r2, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm920_dcache_clean_page(page) + * + * Cleans a single page of dcache so that if we have any future aliased + * mappings, they will be consistent at the time that they are created. + * + * page: virtual address of page to clean from dcache + * + * Note: + * 1. we don't need to flush the write buffer in this case. + * 2. we don't invalidate the entries since when we write the page + * out to disk, the entries may get reloaded into the cache. + */ + .align 5 +ENTRY(cpu_arm920_dcache_clean_page) +#ifndef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + mov r1, #PAGESIZE +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bne 1b +#endif + mov pc, lr + +/* + * cpu_arm920_dcache_clean_entry(addr) + * + * Clean the specified entry of any caches such that the MMU + * translation fetches will obtain correct data. + * + * addr: cache-unaligned virtual address + */ + .align 5 +ENTRY(cpu_arm920_dcache_clean_entry) +#ifndef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ I-CACHE =============================== */ + +/* + * cpu_arm920_icache_invalidate_range(start, end) + * + * invalidate a range of virtual addresses from the Icache + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm920_icache_invalidate_range) +1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB +ENTRY(cpu_arm920_icache_invalidate_page) + /* why no invalidate I cache --rmk */ + mov pc, lr + + +/* ================================== TLB ================================= */ + +/* + * cpu_arm920_tlb_invalidate_all() + * + * Invalidate all TLB entries + */ + .align 5 +ENTRY(cpu_arm920_tlb_invalidate_all) + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm920_tlb_invalidate_range(start, end) + * + * invalidate TLB entries covering the specified range + * + * start: range start address + * end: range end address + */ + .align 5 +ENTRY(cpu_arm920_tlb_invalidate_range) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB +1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry + add r0, r0, #PAGESIZE + cmp r0, r1 + blt 1b + mov pc, lr + +/* + * cpu_arm920_tlb_invalidate_page(page, flags) + * + * invalidate the TLB entries for the specified page. + * + * page: page to invalidate + * flags: non-zero if we include the I TLB + */ + .align 5 +ENTRY(cpu_arm920_tlb_invalidate_page) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + teq r1, #0 + mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm920_set_pgd(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm920_set_pgd) + mov ip, #0 +#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + /* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */ + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +@ && 'Clean & Invalidate whole DCache' +@ && Re-written to use Index Ops. +@ && Uses registers r1, r3 and ip + + mov r1, #7 << 5 @ 8 segments +1: orr r3, r1, #63 << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 7 to 0 +#endif + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm920_set_pmd(pmdp, pmd) + * + * Set a level 1 translation table entry, and clean it out of + * any caches such that the MMUs can load it correctly. + * + * pmdp: pointer to PMD entry + * pmd: PMD value to store + */ + .align 5 +ENTRY(cpu_arm920_set_pmd) +#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + eor r2, r1, #0x0a @ C & Section + tst r2, #0x0b + biceq r1, r1, #4 @ clear bufferable bit +#endif + str r1, [r0] + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm920_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm920_set_pte) + str r1, [r0], #-1024 @ linux version + + eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY + + bic r2, r1, #0xff0 + bic r2, r2, #3 + orr r2, r2, #HPTE_TYPE_SMALL + + tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec? + orrne r2, r2, #HPTE_AP_READ + + tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty? + orreq r2, r2, #HPTE_AP_WRITE + + tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + eor r3, r1, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + +cpu_manu_name: + .asciz "ARM/VLSI" +ENTRY(cpu_arm920_name) + .ascii "Arm920" +#if defined(CONFIG_CPU_ARM920_CPU_IDLE) + .ascii "s" +#endif +#if defined(CONFIG_CPU_ARM920_I_CACHE_ON) + .ascii "i" +#endif +#if defined(CONFIG_CPU_ARM920_D_CACHE_ON) + .ascii "d" +#if defined(CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH) + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#endif + .ascii "\0" + .align + + .section ".text.init", #alloc, #execinstr + +__arm920_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mcr p15, 0, r4, c2, c0 @ load page table pointer + mov r0, #0x1f @ Domains 0, 1 = client + mcr p15, 0, r0, c3, c0 @ load domain access register + mrc p15, 0, r0, c1, c0 @ get control register v4 +/* + * Clear out 'unwanted' bits (then put them in if we need them) + */ + bic r0, r0, #0x0e00 @ ....??r......... + bic r0, r0, #0x0002 @ ..............a. + bic r0, r0, #0x000c @ W,D + bic r0, r0, #0x1000 @ I +/* + * Turn on what we want + */ + orr r0, r0, #0x0031 @ ..........DP...M + orr r0, r0, #0x0100 @ .......S........ + +#ifdef CONFIG_CPU_ARM920_D_CACHE_ON + orr r0, r0, #0x0004 @ Enable D cache +#endif +#ifdef CONFIG_CPU_ARM920_I_CACHE_ON + orr r0, r0, #0x1000 @ I Cache on +#endif + mov pc, lr + + .text + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm920_processor_functions, #object +arm920_processor_functions: + .word cpu_arm920_data_abort + .word cpu_arm920_check_bugs + .word cpu_arm920_proc_init + .word cpu_arm920_proc_fin + .word cpu_arm920_reset + .word cpu_arm920_do_idle + + /* cache */ + .word cpu_arm920_cache_clean_invalidate_all + .word cpu_arm920_cache_clean_invalidate_range + .word cpu_arm920_flush_ram_page + + /* dcache */ + .word cpu_arm920_dcache_invalidate_range + .word cpu_arm920_dcache_clean_range + .word cpu_arm920_dcache_clean_page + .word cpu_arm920_dcache_clean_entry + + /* icache */ + .word cpu_arm920_icache_invalidate_range + .word cpu_arm920_icache_invalidate_page + + /* tlb */ + .word cpu_arm920_tlb_invalidate_all + .word cpu_arm920_tlb_invalidate_range + .word cpu_arm920_tlb_invalidate_page + + /* pgtable */ + .word cpu_arm920_set_pgd + .word cpu_arm920_set_pmd + .word cpu_arm920_set_pte + .size arm920_processor_functions, . - arm920_processor_functions + + .type cpu_arm920_info, #object +cpu_arm920_info: + .long cpu_manu_name + .long cpu_arm920_name + .size cpu_arm920_info, . - cpu_arm920_info + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm920_proc_info,#object +__arm920_proc_info: + .long 0x41009200 + .long 0xff00fff0 + .long 0x00000c1e @ mmuflags + b __arm920_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_arm920_info + .long arm920_processor_functions + .size __arm920_proc_info, . - __arm920_proc_info diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index bf75c97a2..031ba648a 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -1,15 +1,21 @@ /* - * linux/arch/arm/mm/proc-sa110.S: MMU functions for SA110 + * linux/arch/arm/mm/proc-sa110.S * - * (C) 1997-2000 Russell King + * Copyright (C) 1997-2000 Russell King * - * These are the low level assembler for performing cache and TLB - * functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * MMU functions for SA110 + * + * These are the low level assembler for performing cache and TLB + * functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110. * - * Note that SA1100 and SA1110 share everything but their name and CPU ID. + * Note that SA1100 and SA1110 share everything but their name and CPU ID. * - * 12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl): - * Flush the read buffer at context switches + * 12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl): + * Flush the read buffer at context switches */ #include <linux/linkage.h> #include <asm/assembler.h> @@ -21,24 +27,35 @@ * is larger than this, then we flush the whole cache */ #define MAX_AREA_SIZE 32768 + +/* + * the cache line size of the I and D cache + */ +#define DCACHELINESIZE 32 + +/* + * and the page size + */ +#define PAGESIZE 4096 + #define FLUSH_OFFSET 32768 .macro flush_110_dcache rd, ra, re add \re, \ra, #16384 @ only necessary for 16k -1001: ldr \rd, [\ra], #32 +1001: ldr \rd, [\ra], #DCACHELINESIZE teq \re, \ra bne 1001b .endm .macro flush_1100_dcache rd, ra, re add \re, \ra, #8192 @ only necessary for 8k -1001: ldr \rd, [\ra], #32 +1001: ldr \rd, [\ra], #DCACHELINESIZE teq \re, \ra bne 1001b #ifdef FLUSH_BASE_MINICACHE add \ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE add \re, \ra, #512 @ only 512 bytes -1002: ldr \rd, [\ra], #32 +1002: ldr \rd, [\ra], #DCACHELINESIZE teq \re, \ra bne 1002b #endif @@ -48,610 +65,705 @@ Lclean_switch: .long 0 .text + /* - * Function: sa110_flush_cache_all (void) - * Purpose : Flush all cache lines + * cpu_sa110_data_abort() + * + * obtain information about current aborted instruction + * + * r0 = address of aborted instruction + * + * Returns: + * r0 = address of abort + * r1 != 0 if writing + * r3 = FSR */ - .align 5 -ENTRY(cpu_sa110_flush_cache_all) @ preserves r0 - mov r2, #1 -cpu_sa110_flush_cache_all_r2: - ldr r3, =Lclean_switch - ldr ip, =FLUSH_BASE - ldr r1, [r3] - ands r1, r1, #1 - eor r1, r1, #1 - str r1, [r3] - addne ip, ip, #FLUSH_OFFSET - flush_110_dcache r3, ip, r1 - mov ip, #0 - teq r2, #0 - mcrne p15, 0, ip, c7, c5, 0 @ flush I cache - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - - .align 5 -ENTRY(cpu_sa1100_flush_cache_all) @ preserves r0 - mov r2, #1 -cpu_sa1100_flush_cache_all_r2: - ldr r3, =Lclean_switch - ldr ip, =FLUSH_BASE - ldr r1, [r3] - ands r1, r1, #1 - eor r1, r1, #1 - str r1, [r3] - addne ip, ip, #FLUSH_OFFSET - flush_1100_dcache r3, ip, r1 - mov ip, #0 - teq r2, #0 - mcrne p15, 0, ip, c7, c5, 0 @ flush I cache - mcr p15, 0, r1, c9, c0, 0 @ flush RB - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr + .align 5 +ENTRY(cpu_sa110_data_abort) +ENTRY(cpu_sa1100_data_abort) + ldr r1, [r0] @ read aborted instruction + mrc p15, 0, r0, c6, c0, 0 @ get FAR + mov r1, r1, lsr #19 @ b1 = L + mrc p15, 0, r3, c5, c0, 0 @ get FSR + and r1, r1, #2 + and r3, r3, #255 + mov pc, lr /* - * Function: sa110_flush_cache_area (unsigned long address, int end, int flags) - * Params : address Area start address - * : end Area end address - * : flags b0 = I cache as well - * Purpose : clean & flush all cache lines associated with this area of memory + * cpu_sa110_check_bugs() */ - .align 5 -ENTRY(cpu_sa110_flush_cache_area) - sub r3, r1, r0 - cmp r3, #MAX_AREA_SIZE - bgt cpu_sa110_flush_cache_all_r2 -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry - mcr p15, 0, r0, c7, c6, 1 @ flush D entry - add r0, r0, #32 - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - mcr p15, 0, r0, c7, c6, 1 @ flush D entry - add r0, r0, #32 - cmp r0, r1 - blt 1b - teq r2, #0 - movne r0, #0 - mcrne p15, 0, r0, c7, c5, 0 @ flush I cache - mov pc, lr - -ENTRY(cpu_sa1100_flush_cache_area) - sub r3, r1, r0 - cmp r3, #MAX_AREA_SIZE - bgt cpu_sa1100_flush_cache_all_r2 - b 1b +ENTRY(cpu_sa110_check_bugs) +ENTRY(cpu_sa1100_check_bugs) + mrs ip, cpsr + bic ip, ip, #F_BIT + msr cpsr, ip + mov pc, lr /* - * Function: sa110_cache_wback_area(unsigned long address, unsigned long end) - * Params : address Area start address - * : end Area end address - * Purpose : ensure all dirty cachelines in the specified area have been - * written out to memory (for DMA) + * cpu_sa110_proc_init() */ - .align 5 -ENTRY(cpu_sa110_cache_wback_area) - sub r3, r1, r0 - cmp r3, #MAX_AREA_SIZE - mov r2, #0 - bgt cpu_sa110_flush_cache_all_r2 - bic r0, r0, #31 -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #32 - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #32 - cmp r0, r1 - blt 1b - mcr p15, 0, r2, c7, c10, 4 @ drain WB - mov pc, lr - -ENTRY(cpu_sa1100_cache_wback_area) - sub r3, r1, r0 - cmp r3, #MAX_AREA_SIZE - mov r2, #0 - bgt cpu_sa1100_flush_cache_all_r2 - bic r0, r0, #31 - b 1b +ENTRY(cpu_sa110_proc_init) +ENTRY(cpu_sa1100_proc_init) + mov r0, #0 + mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching + mov pc, lr + /* - * Function: sa110_cache_purge_area(unsigned long address, unsigned long end) - * Params : address Area start address - * : end Area end address - * Purpose : throw away all D-cached data in specified region without - * an obligation to write it back. - * Note : Must clean the D-cached entries around the boundaries if the - * start and/or end address are not cache aligned. + * cpu_sa110_proc_fin() */ - .align 5 -ENTRY(cpu_sa110_cache_purge_area) -ENTRY(cpu_sa1100_cache_purge_area) - tst r0, #31 - bic r0, r0, #31 - mcrne p15, 0, r0, c7, c10, 1 @ clean D entry - tst r1, #31 - mcrne p15, 0, r1, c7, c10, 1 @ clean D entry -1: mcr p15, 0, r0, c7, c6, 1 @ flush D entry - add r0, r0, #32 - cmp r0, r1 - blt 1b - mov pc, lr +ENTRY(cpu_sa110_proc_fin) + stmfd sp!, {lr} + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip + bl cpu_sa110_cache_clean_invalidate_all @ clean caches +1: mov r0, #0 + mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +ENTRY(cpu_sa1100_proc_fin) + stmfd sp!, {lr} + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip + bl cpu_sa1100_cache_clean_invalidate_all @ clean caches + b 1b /* - * Function: sa110_flush_cache_entry (unsigned long address) - * Params : address Address of cache line to flush - * Purpose : clean & flush an entry + * cpu_sa110_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset */ - .align 5 -ENTRY(cpu_sa110_flush_cache_entry) -ENTRY(cpu_sa1100_flush_cache_entry) - mov r1, #0 - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - mcr p15, 0, r1, c7, c10, 4 @ drain WB - mcr p15, 0, r1, c7, c5, 0 @ flush I cache - mov pc, lr + .align 5 +ENTRY(cpu_sa110_reset) +ENTRY(cpu_sa1100_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 /* - * Function: sa110_clean_cache_area(unsigned long start, unsigned long size) - * Params : address Address of cache line to clean - * Purpose : Ensure that physical memory reflects cache at this location - * for page table purposes. + * cpu_sa110_do_idle(type) + * + * Cause the processor to idle + * + * type: call type: + * 0 = slow idle + * 1 = fast idle + * 2 = switch to slow processor clock + * 3 = switch to fast processor clock */ -ENTRY(cpu_sa110_clean_cache_area) -ENTRY(cpu_sa1100_clean_cache_area) -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns) - add r0, r0, #32 - subs r1, r1, #32 - bhi 1b - mov pc, lr + .align 5 +idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned + mov r0, r0 @ safety + mov pc, lr + +ENTRY(cpu_sa110_do_idle) + mov ip, #0 + cmp r0, #4 + addcc pc, pc, r0, lsl #2 + mov pc, lr + + b idle + b idle + b slow_clock + b fast_clock + +fast_clock: + mcr p15, 0, ip, c15, c1, 2 @ enable clock switching + mov pc, lr + +slow_clock: + mcr p15, 0, ip, c15, c2, 2 @ disable clock switching + ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc + ldr r1, [r1, #0] @ force switch to MCLK + mov pc, lr + + .align 5 +ENTRY(cpu_sa1100_do_idle) + mov r0, r0 @ 4 nop padding + mov r0, r0 + mov r0, r0 + mov r0, #0 + ldr r1, =UNCACHEABLE_ADDR @ ptr to uncacheable address + mrs r2, cpsr + orr r3, r2, #192 @ disallow interrupts + msr cpsr_c, r3 + @ --- aligned to a cache line + mcr p15, 0, r0, c15, c2, 2 @ disable clock switching + ldr r1, [r1, #0] @ force switch to MCLK + mcr p15, 0, r0, c15, c8, 2 @ wait for interrupt + mov r0, r0 @ safety + mcr p15, 0, r0, c15, c1, 2 @ enable clock switching + msr cpsr_c, r2 @ allow interrupts + mov pc, lr + +/* ================================= CACHE ================================ */ + /* - * Function: sa110_flush_ram_page (unsigned long page) - * Params : page Area start address - * Purpose : clean all cache lines associated with this area of memory + * cpu_sa110_cache_clean_invalidate_all (void) + * + * clean and invalidate all cache lines + * + * Note: + * 1. we should preserve r0 at all times */ - .align 5 -ENTRY(cpu_sa110_flush_ram_page) -ENTRY(cpu_sa1100_flush_ram_page) - mov r1, #4096 -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #32 - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #32 - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #32 - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #32 - subs r1, r1, #128 - bne 1b - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr + .align 5 +ENTRY(cpu_sa110_cache_clean_invalidate_all) + mov r2, #1 +cpu_sa110_cache_clean_invalidate_all_r2: + ldr r3, =Lclean_switch + ldr ip, =FLUSH_BASE + ldr r1, [r3] + ands r1, r1, #1 + eor r1, r1, #1 + str r1, [r3] + addne ip, ip, #FLUSH_OFFSET + flush_110_dcache r3, ip, r1 + mov ip, #0 + teq r2, #0 + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + + .align 5 +ENTRY(cpu_sa1100_cache_clean_invalidate_all) + mov r2, #1 +cpu_sa1100_cache_clean_invalidate_all_r2: + ldr r3, =Lclean_switch + ldr ip, =FLUSH_BASE + ldr r1, [r3] + ands r1, r1, #1 + eor r1, r1, #1 + str r1, [r3] + addne ip, ip, #FLUSH_OFFSET + flush_1100_dcache r3, ip, r1 + mov ip, #0 + teq r2, #0 + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r1, c9, c0, 0 @ invalidate RB + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr /* - * Function: sa110_flush_tlb_all (void) - * Purpose : flush all TLB entries in all caches + * cpu_sa110_cache_clean_invalidate_range(start, end, flags) + * + * clean and invalidate all cache lines associated with this area of memory + * + * start: Area start address + * end: Area end address + * flags: nonzero for I cache as well */ - .align 5 -ENTRY(cpu_sa110_flush_tlb_all) -ENTRY(cpu_sa1100_flush_tlb_all) - mov ip, #0 - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mcr p15, 0, ip, c8, c7, 0 @ flush I & D tlbs - mov pc, lr + .align 5 +ENTRY(cpu_sa110_cache_clean_invalidate_range) + bic r0, r0, #DCACHELINESIZE - 1 + sub r3, r1, r0 + cmp r3, #MAX_AREA_SIZE + bgt cpu_sa110_cache_clean_invalidate_all_r2 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blt 1b + teq r2, #0 + movne r0, #0 + mcrne p15, 0, r0, c7, c5, 0 @ invalidate I cache + mov pc, lr + +ENTRY(cpu_sa1100_cache_clean_invalidate_range) + sub r3, r1, r0 + cmp r3, #MAX_AREA_SIZE + bgt cpu_sa1100_cache_clean_invalidate_all_r2 + b 1b /* - * Function: sa110_flush_tlb_area (unsigned long address, unsigned long end, int flags) - * Params : address Area start address - * : end Area end address - * : flags b0 = I-TLB as well - * Purpose : flush a TLB entry + * cpu_sa110_flush_ram_page(page) + * + * clean and invalidate all cache lines associated with this area of memory + * + * page: page to clean and invalidate */ - .align 5 -ENTRY(cpu_sa110_flush_tlb_area) -ENTRY(cpu_sa1100_flush_tlb_area) - mov r3, #0 - mcr p15, 0, r3, c7, c10, 4 @ drain WB -1: cmp r0, r1 - mcrlt p15, 0, r0, c8, c6, 1 @ flush D TLB entry - addlt r0, r0, #4096 - cmp r0, r1 - mcrlt p15, 0, r0, c8, c6, 1 @ flush D TLB entry - addlt r0, r0, #4096 - blt 1b - teq r2, #0 - mcrne p15, 0, r3, c8, c5, 0 @ flush I TLB - mov pc, lr + .align 5 +ENTRY(cpu_sa110_flush_ram_page) +ENTRY(cpu_sa1100_flush_ram_page) + mov r1, #PAGESIZE +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bne 1b + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ D-CACHE =============================== */ /* - * Function: sa110_flush_tlb_page (unsigned long address, int flags) - * Params : address Address to flush - * : flags b0 = I-TLB as well - * Purpose : flush a TLB entry + * cpu_sa110_dcache_invalidate_range(start, end) + * + * throw away all D-cached data in specified region without an obligation + * to write them back. Note however that we must clean the D-cached entries + * around the boundaries if the start and/or end address are not cache + * aligned. + * + * start: virtual start address + * end: virtual end address */ - .align 5 -ENTRY(cpu_sa110_flush_tlb_page) -ENTRY(cpu_sa1100_flush_tlb_page) - mov r3, #0 - mcr p15, 0, r3, c7, c10, 4 @ drain WB - mcr p15, 0, r0, c8, c6, 1 @ flush D TLB entry - teq r1, #0 - mcrne p15, 0, r3, c8, c5, 0 @ flush I TLB - mov pc, lr + .align 5 +ENTRY(cpu_sa110_dcache_invalidate_range) +ENTRY(cpu_sa1100_dcache_invalidate_range) + tst r0, #DCACHELINESIZE - 1 + bic r0, r0, #DCACHELINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #DCACHELINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blt 1b + mov pc, lr /* - * Function: sa110_flush_icache_area (unsigned long address, unsigned long size) - * Params : address Address of area to flush - * : size Size of area to flush - * Purpose : flush an area from the Icache + * cpu_sa110_dcache_clean_range(start, end) + * + * For the specified virtual address range, ensure that all caches contain + * clean data, such that peripheral accesses to the physical RAM fetch + * correct data. + * + * start: virtual start address + * end: virtual end address */ - .align 5 -ENTRY(cpu_sa110_flush_icache_area) -ENTRY(cpu_sa1100_flush_icache_area) -1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry - add r0, r0, #32 - subs r1, r1, #32 - bhi 1b - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mcr p15, 0, r0, c7, c5, 0 @ flush I cache - mov pc, lr - - .align 5 -ENTRY(cpu_sa110_flush_icache_page) -ENTRY(cpu_sa1100_flush_icache_page) - mcr p15, 0, r0, c7, c5, 0 @ flush I cache - mov pc, lr + .align 5 +ENTRY(cpu_sa110_dcache_clean_range) + bic r0, r0, #DCACHELINESIZE - 1 + sub r1, r1, r0 + cmp r1, #MAX_AREA_SIZE + mov r2, #0 + bgt cpu_sa110_cache_clean_invalidate_all_r2 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bpl 1b + mcr p15, 0, r2, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(cpu_sa1100_dcache_clean_range) + bic r0, r0, #DCACHELINESIZE - 1 + sub r1, r1, r0 + cmp r1, #MAX_AREA_SIZE + mov r2, #0 + bgt cpu_sa1100_cache_clean_invalidate_all_r2 + b 1b /* - * Function: sa110_data_abort () - * Params : r0 = address of aborted instruction - * Purpose : obtain information about current aborted instruction - * Returns : r0 = address of abort - * : r1 != 0 if writing - * : r3 = FSR + * cpu_sa110_clean_dcache_page(page) + * + * Cleans a single page of dcache so that if we have any future aliased + * mappings, they will be consistent at the time that they are created. + * + * Note: + * 1. we don't need to flush the write buffer in this case. + * 2. we don't invalidate the entries since when we write the page + * out to disk, the entries may get reloaded into the cache. */ - .align 5 -ENTRY(cpu_sa110_data_abort) -ENTRY(cpu_sa1100_data_abort) - ldr r1, [r0] @ read instruction causing problem - mrc p15, 0, r0, c6, c0, 0 @ get FAR - mov r1, r1, lsr #19 @ b1 = L - mrc p15, 0, r3, c5, c0, 0 @ get FSR - and r1, r1, #2 - and r3, r3, #255 - mov pc, lr - - .align 5 + .align 5 +ENTRY(cpu_sa110_dcache_clean_page) +ENTRY(cpu_sa1100_dcache_clean_page) + mov r1, #PAGESIZE +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bne 1b + mov pc, lr + /* - * Function: sa110_set_pgd(unsigned long pgd_phys) - * Params : pgd_phys Physical address of page table - * Purpose : Perform a task switch, saving the old processes state, and restoring - * the new. + * cpu_sa110_dcache_clean_entry(addr) + * + * Clean the specified entry of any caches such that the MMU + * translation fetches will obtain correct data. + * + * addr: cache-unaligned virtual address */ - .align 5 -ENTRY(cpu_sa110_set_pgd) - ldr r3, =Lclean_switch - ldr ip, =FLUSH_BASE - ldr r2, [r3] - ands r2, r2, #1 - eor r2, r2, #1 - str r2, [r3] - addne ip, ip, #FLUSH_OFFSET - flush_110_dcache r3, ip, r1 - mov r1, #0 - mcr p15, 0, r1, c7, c5, 0 @ flush I cache - mcr p15, 0, r1, c7, c10, 4 @ drain WB - mcr p15, 0, r0, c2, c0, 0 @ load page table pointer - mcr p15, 0, r1, c8, c7, 0 @ flush TLBs - mov pc, lr - - .align 5 -ENTRY(cpu_sa1100_set_pgd) - ldr r3, =Lclean_switch - ldr ip, =FLUSH_BASE - ldr r2, [r3] - ands r2, r2, #1 - eor r2, r2, #1 - str r2, [r3] - addne ip, ip, #FLUSH_OFFSET - flush_1100_dcache r3, ip, r1 - mov r1, #0 - mcr p15, 0, r1, c7, c5, 0 @ flush I cache - mcr p15, 0, r1, c9, c0, 0 @ flush RB - mcr p15, 0, r1, c7, c10, 4 @ drain WB - mcr p15, 0, r0, c2, c0, 0 @ load page table pointer - mcr p15, 0, r1, c8, c7, 0 @ flush TLBs - mov pc, lr + .align 5 +ENTRY(cpu_sa110_dcache_clean_entry) +ENTRY(cpu_sa1100_dcache_clean_entry) + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ I-CACHE =============================== */ /* - * Function: sa110_set_pmd(pmd_t *pmdp, pmd_t pmd) - * Params : r0 = Address to set - * : r1 = value to set - * Purpose : Set a PMD and flush it out + * cpu_sa110_icache_invalidate_range(start, end) + * + * invalidate a range of virtual addresses from the Icache + * + * start: virtual start address + * end: virtual end address */ - .align 5 -ENTRY(cpu_sa110_set_pmd) -ENTRY(cpu_sa1100_set_pmd) - str r1, [r0] - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr + .align 5 +ENTRY(cpu_sa110_icache_invalidate_range) +ENTRY(cpu_sa1100_icache_invalidate_range) +1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB +ENTRY(cpu_sa110_icache_invalidate_page) +ENTRY(cpu_sa1100_icache_invalidate_page) + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mov pc, lr + +/* ================================== TLB ================================= */ /* - * Function: sa110_set_pte(pte_t *ptep, pte_t pte) - * Params : r0 = Address to set - * : r1 = value to set - * Purpose : Set a PTE and flush it out + * cpu_sa110_tlb_invalidate_all() + * + * Invalidate all TLB entries */ - .align 5 -ENTRY(cpu_sa110_set_pte) -ENTRY(cpu_sa1100_set_pte) - str r1, [r0], #-1024 @ linux version - - eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY + .align 5 +ENTRY(cpu_sa110_tlb_invalidate_all) +ENTRY(cpu_sa1100_tlb_invalidate_all) + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr - bic r2, r1, #0xff0 - bic r2, r2, #3 - orr r2, r2, #HPTE_TYPE_SMALL - - tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec? - orrne r2, r2, #HPTE_AP_READ +/* + * cpu_sa110_tlb_invalidate_range(start, end) + * + * invalidate TLB entries covering the specified range + * + * start: range start address + * end: range end address + */ + .align 5 +ENTRY(cpu_sa110_tlb_invalidate_range) +ENTRY(cpu_sa1100_tlb_invalidate_range) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB +1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + add r0, r0, #PAGESIZE + cmp r0, r1 + blt 1b + mcr p15, 0, r3, c8, c5, 0 @ invalidate I TLB + mov pc, lr - tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty? - orreq r2, r2, #HPTE_AP_WRITE +/* + * cpu_sa110_tlb_invalidate_page(page, flags) + * + * invalidate the TLB entries for the specified page. + * + * page: page to invalidate + * flags: non-zero if we include the I TLB + */ + .align 5 +ENTRY(cpu_sa110_tlb_invalidate_page) +ENTRY(cpu_sa1100_tlb_invalidate_page) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + teq r1, #0 + mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + mcrne p15, 0, r3, c8, c5, 0 @ invalidate I TLB + mov pc, lr + +/* =============================== PageTable ============================== */ - tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? - movne r2, #0 +/* + * cpu_sa110_set_pgd(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_sa110_set_pgd) + ldr r3, =Lclean_switch + ldr ip, =FLUSH_BASE + ldr r2, [r3] + ands r2, r2, #1 + eor r2, r2, #1 + str r2, [r3] + addne ip, ip, #FLUSH_OFFSET + flush_110_dcache r3, ip, r1 + mov r1, #0 + mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr - str r2, [r0] @ hardware version - mov r0, r0 - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr +/* + * cpu_sa1100_set_pgd(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_sa1100_set_pgd) + ldr r3, =Lclean_switch + ldr ip, =FLUSH_BASE + ldr r2, [r3] + ands r2, r2, #1 + eor r2, r2, #1 + str r2, [r3] + addne ip, ip, #FLUSH_OFFSET + flush_1100_dcache r3, ip, r1 + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c9, c0, 0 @ invalidate RB + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr /* - * Function: sa110_check_bugs (void) - * : sa110_proc_init (void) - * : sa110_proc_fin (void) - * Notes : This processor does not require these + * cpu_sa110_set_pmd(pmdp, pmd) + * + * Set a level 1 translation table entry, and clean it out of + * any caches such that the MMUs can load it correctly. + * + * pmdp: pointer to PMD entry + * pmd: PMD value to store */ -ENTRY(cpu_sa110_check_bugs) -ENTRY(cpu_sa1100_check_bugs) - mrs ip, cpsr - bic ip, ip, #F_BIT - msr cpsr, ip - mov pc, lr + .align 5 +ENTRY(cpu_sa110_set_pmd) +ENTRY(cpu_sa1100_set_pmd) + str r1, [r0] + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr -ENTRY(cpu_sa110_proc_init) -ENTRY(cpu_sa1100_proc_init) - mov r0, #0 - mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching - mov pc, lr +/* + * cpu_sa110_arm920_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_sa110_set_pte) +ENTRY(cpu_sa1100_set_pte) + str r1, [r0], #-1024 @ linux version -ENTRY(cpu_sa110_proc_fin) - stmfd sp!, {r1, lr} - mov ip, #F_BIT | I_BIT | SVC_MODE - msr cpsr_c, ip - bl cpu_sa110_flush_cache_all @ clean caches -1: mov r0, #0 - mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x1000 @ ...i............ - bic r0, r0, #0x000e @ ............wca. - mcr p15, 0, r0, c1, c0, 0 @ disable caches - ldmfd sp!, {r1, pc} + eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY -ENTRY(cpu_sa1100_proc_fin) - stmfd sp!, {r1, lr} - mov ip, #F_BIT | I_BIT | SVC_MODE - msr cpsr_c, ip - bl cpu_sa1100_flush_cache_all @ clean caches - b 1b + bic r2, r1, #0xff0 + bic r2, r2, #3 + orr r2, r2, #HPTE_TYPE_SMALL + tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec? + orrne r2, r2, #HPTE_AP_READ - .align 5 -idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned - mov r0, r0 @ safety - mov pc, lr -/* - * Function: *_do_idle - * Params : r0 = call type: - * 0 = slow idle - * 1 = fast idle - * 2 = switch to slow processor clock - * 3 = switch to fast processor clock - */ -ENTRY(cpu_sa110_do_idle) -ENTRY(cpu_sa1100_do_idle) - mov ip, #0 - cmp r0, #4 - addcc pc, pc, r0, lsl #2 - mov pc, lr + tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty? + orreq r2, r2, #HPTE_AP_WRITE - b idle - b idle - b slow_clock - b fast_clock + tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? + movne r2, #0 -fast_clock: mcr p15, 0, ip, c15, c1, 2 @ enable clock switching - mov pc, lr + str r2, [r0] @ hardware version + mov r0, r0 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr -slow_clock: mcr p15, 0, ip, c15, c2, 2 @ disable clock switching - ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc - ldr r1, [r1, #0] @ force switch to MCLK - mov pc, lr -/* - * Function: sa110_reset - * Params : r0 = address to jump to - * Notes : This sets up everything for a reset - */ - .align 5 -ENTRY(cpu_sa110_reset) -ENTRY(cpu_sa1100_reset) - mov ip, #0 - mcr p15, 0, ip, c7, c7, 0 @ flush I,D caches - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mcr p15, 0, ip, c8, c7, 0 @ flush I & D tlbs - mrc p15, 0, ip, c1, c0, 0 @ ctrl register - bic ip, ip, #0x000f @ ............wcam - bic ip, ip, #0x1100 @ ...i...s........ - mcr p15, 0, ip, c1, c0, 0 @ ctrl register - mov pc, r0 - - -cpu_manu_name: .asciz "Intel" -cpu_sa110_name: .asciz "StrongARM-110" +cpu_manu_name: + .asciz "Intel" +cpu_sa110_name: + .asciz "StrongARM-110" cpu_sa1100_name: - .asciz "StrongARM-1100" + .asciz "StrongARM-1100" cpu_sa1110_name: - .asciz "StrongARM-1110" - .align + .asciz "StrongARM-1110" + .align - .section ".text.init", #alloc, #execinstr + .section ".text.init", #alloc, #execinstr __sa1100_setup: @ Allow read-buffer operations from userland - mcr p15, 0, r0, c9, c0, 5 - -__sa110_setup: mov r0, #F_BIT | I_BIT | SVC_MODE - msr cpsr_c, r0 - mov r0, #0 - mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4 - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 - mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4 - mcr p15, 0, r4, c2, c0 @ load page table pointer - mov r0, #0x1f @ Domains 0, 1 = client - mcr p15, 0, r0, c3, c0 @ load domain access register - mrc p15, 0, r0, c1, c0 @ get control register v4 - bic r0, r0, #0x0e00 @ ....??r......... - bic r0, r0, #0x0002 @ ..............a. - orr r0, r0, #0x003d @ ..........DPWC.M - orr r0, r0, #0x1100 @ ...I...S........ - mov pc, lr - - .text + mcr p15, 0, r0, c9, c0, 5 + +__sa110_setup: + mov r0, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, r0 + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mcr p15, 0, r4, c2, c0 @ load page table pointer + mov r0, #0x1f @ Domains 0, 1 = client + mcr p15, 0, r0, c3, c0 @ load domain access register + mrc p15, 0, r0, c1, c0 @ get control register v4 + bic r0, r0, #0x0e00 @ ....??r......... + bic r0, r0, #0x0002 @ ..............a. + orr r0, r0, #0x003d @ ..........DPWC.M + orr r0, r0, #0x1100 @ ...I...S........ + mov pc, lr + + .text /* * Purpose : Function pointers used to access above functions - all calls * come through these */ - .type sa110_processor_functions, #object + .type sa110_processor_functions, #object ENTRY(sa110_processor_functions) - .word cpu_sa110_data_abort - .word cpu_sa110_check_bugs - .word cpu_sa110_proc_init - .word cpu_sa110_proc_fin - .word cpu_sa110_flush_cache_all - .word cpu_sa110_flush_cache_area - .word cpu_sa110_flush_cache_entry - .word cpu_sa110_clean_cache_area - .word cpu_sa110_flush_ram_page - .word cpu_sa110_flush_tlb_all - .word cpu_sa110_flush_tlb_area - .word cpu_sa110_set_pgd - .word cpu_sa110_set_pmd - .word cpu_sa110_set_pte - .word cpu_sa110_reset - .word cpu_sa110_flush_icache_area - .word cpu_sa110_cache_wback_area - .word cpu_sa110_cache_purge_area - .word cpu_sa110_flush_tlb_page - .word cpu_sa110_do_idle - .word cpu_sa110_flush_icache_page - .size sa110_processor_functions, . - sa110_processor_functions - - .type cpu_sa110_info, #object + .word cpu_sa110_data_abort + .word cpu_sa110_check_bugs + .word cpu_sa110_proc_init + .word cpu_sa110_proc_fin + .word cpu_sa110_reset + .word cpu_sa110_do_idle + + /* cache */ + .word cpu_sa110_cache_clean_invalidate_all + .word cpu_sa110_cache_clean_invalidate_range + .word cpu_sa110_flush_ram_page + + /* dcache */ + .word cpu_sa110_dcache_invalidate_range + .word cpu_sa110_dcache_clean_range + .word cpu_sa110_dcache_clean_page + .word cpu_sa110_dcache_clean_entry + + /* icache */ + .word cpu_sa110_icache_invalidate_range + .word cpu_sa110_icache_invalidate_page + + /* tlb */ + .word cpu_sa110_tlb_invalidate_all + .word cpu_sa110_tlb_invalidate_range + .word cpu_sa110_tlb_invalidate_page + + /* pgtable */ + .word cpu_sa110_set_pgd + .word cpu_sa110_set_pmd + .word cpu_sa110_set_pte + .size sa110_processor_functions, . - sa110_processor_functions + + .type cpu_sa110_info, #object cpu_sa110_info: - .long cpu_manu_name - .long cpu_sa110_name - .size cpu_sa110_info, . - cpu_sa110_info + .long cpu_manu_name + .long cpu_sa110_name + .size cpu_sa110_info, . - cpu_sa110_info /* * SA1100 and SA1110 share the same function calls */ - .type sa1100_processor_functions, #object + .type sa1100_processor_functions, #object ENTRY(sa1100_processor_functions) - .word cpu_sa1100_data_abort - .word cpu_sa1100_check_bugs - .word cpu_sa1100_proc_init - .word cpu_sa1100_proc_fin - .word cpu_sa1100_flush_cache_all - .word cpu_sa1100_flush_cache_area - .word cpu_sa1100_flush_cache_entry - .word cpu_sa1100_clean_cache_area - .word cpu_sa1100_flush_ram_page - .word cpu_sa1100_flush_tlb_all - .word cpu_sa1100_flush_tlb_area - .word cpu_sa1100_set_pgd - .word cpu_sa1100_set_pmd - .word cpu_sa1100_set_pte - .word cpu_sa1100_reset - .word cpu_sa1100_flush_icache_area - .word cpu_sa1100_cache_wback_area - .word cpu_sa1100_cache_purge_area - .word cpu_sa1100_flush_tlb_page - .word cpu_sa1100_do_idle - .word cpu_sa1100_flush_icache_page - .size sa1100_processor_functions, . - sa1100_processor_functions + .word cpu_sa1100_data_abort + .word cpu_sa1100_check_bugs + .word cpu_sa1100_proc_init + .word cpu_sa1100_proc_fin + .word cpu_sa1100_reset + .word cpu_sa1100_do_idle + + /* cache */ + .word cpu_sa1100_cache_clean_invalidate_all + .word cpu_sa1100_cache_clean_invalidate_range + .word cpu_sa1100_flush_ram_page + + /* dcache */ + .word cpu_sa1100_dcache_invalidate_range + .word cpu_sa1100_dcache_clean_range + .word cpu_sa1100_dcache_clean_page + .word cpu_sa1100_dcache_clean_entry + + /* icache */ + .word cpu_sa1100_icache_invalidate_range + .word cpu_sa1100_icache_invalidate_page + + /* tlb */ + .word cpu_sa1100_tlb_invalidate_all + .word cpu_sa1100_tlb_invalidate_range + .word cpu_sa1100_tlb_invalidate_page + + /* pgtable */ + .word cpu_sa1100_set_pgd + .word cpu_sa1100_set_pmd + .word cpu_sa1100_set_pte + .size sa1100_processor_functions, . - sa1100_processor_functions cpu_sa1100_info: - .long cpu_manu_name - .long cpu_sa1100_name - .size cpu_sa1100_info, . - cpu_sa1100_info + .long cpu_manu_name + .long cpu_sa1100_name + .size cpu_sa1100_info, . - cpu_sa1100_info cpu_sa1110_info: - .long cpu_manu_name - .long cpu_sa1110_name - .size cpu_sa1110_info, . - cpu_sa1110_info + .long cpu_manu_name + .long cpu_sa1110_name + .size cpu_sa1110_info, . - cpu_sa1110_info + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4" + .size cpu_arch_name, . - cpu_arch_name - .type cpu_arch_name, #object -cpu_arch_name: .asciz "armv4" - .size cpu_arch_name, . - cpu_arch_name + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + .align - .type cpu_elf_name, #object -cpu_elf_name: .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - .align + .section ".proc.info", #alloc, #execinstr - .section ".proc.info", #alloc, #execinstr - - .type __sa110_proc_info,#object + .type __sa110_proc_info,#object __sa110_proc_info: - .long 0x4401a100 - .long 0xfffffff0 - .long 0x00000c02 - b __sa110_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT - .long cpu_sa110_info - .long sa110_processor_functions - .size __sa110_proc_info, . - __sa110_proc_info - - .type __sa1100_proc_info,#object + .long 0x4401a100 + .long 0xfffffff0 + .long 0x00000c0e + b __sa110_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_sa110_info + .long sa110_processor_functions + .size __sa110_proc_info, . - __sa110_proc_info + + .type __sa1100_proc_info,#object __sa1100_proc_info: - .long 0x4401a110 - .long 0xfffffff0 - .long 0x00000c02 - b __sa1100_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT - .long cpu_sa1100_info - .long sa1100_processor_functions - .size __sa1100_proc_info, . - __sa1100_proc_info - - .type __sa1110_proc_info,#object + .long 0x4401a110 + .long 0xfffffff0 + .long 0x00000c0e + b __sa1100_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_sa1100_info + .long sa1100_processor_functions + .size __sa1100_proc_info, . - __sa1100_proc_info + + .type __sa1110_proc_info,#object __sa1110_proc_info: - .long 0x6901b110 - .long 0xfffffff0 - .long 0x00000c02 - b __sa1100_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT - .long cpu_sa1110_info - .long sa1100_processor_functions - .size __sa1110_proc_info, . - __sa1110_proc_info - - + .long 0x6901b110 + .long 0xfffffff0 + .long 0x00000c0e + b __sa1100_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_sa1110_info + .long sa1100_processor_functions + .size __sa1110_proc_info, . - __sa1110_proc_info diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c new file mode 100644 index 000000000..07ceac0f9 --- /dev/null +++ b/arch/arm/mm/proc-syms.c @@ -0,0 +1,31 @@ +/* + * linux/arch/arm/mm/proc-syms.c + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <asm/proc-fns.h> + +#ifndef MULTI_CPU +EXPORT_SYMBOL(cpu_cache_clean_invalidate_all); +EXPORT_SYMBOL(cpu_cache_clean_invalidate_range); +EXPORT_SYMBOL(cpu_flush_ram_page); +EXPORT_SYMBOL(cpu_dcache_clean_page); +EXPORT_SYMBOL(cpu_dcache_clean_entry); +EXPORT_SYMBOL(cpu_dcache_clean_range); +EXPORT_SYMBOL(cpu_dcache_invalidate_range); +EXPORT_SYMBOL(cpu_icache_invalidate_range); +EXPORT_SYMBOL(cpu_icache_invalidate_page); +EXPORT_SYMBOL(cpu_tlb_invalidate_all); +EXPORT_SYMBOL(cpu_tlb_invalidate_range); +EXPORT_SYMBOL(cpu_tlb_invalidate_page); +EXPORT_SYMBOL(cpu_set_pgd); +EXPORT_SYMBOL(cpu_set_pmd); +EXPORT_SYMBOL(cpu_set_pte); +#else +EXPORT_SYMBOL(processor); +#endif diff --git a/arch/arm/mm/small_page.c b/arch/arm/mm/small_page.c index 27fb0f663..634cc1ead 100644 --- a/arch/arm/mm/small_page.c +++ b/arch/arm/mm/small_page.c @@ -3,12 +3,15 @@ * * Copyright (C) 1996 Russell King * - * Changelog: - * 26/01/1996 RMK Cleaned up various areas to make little more generic - * 07/02/1999 RMK Support added for 16K and 32K page sizes + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * 26/01/1996 RMK Cleaned up various areas to make little more generic + * 07/02/1999 RMK Support added for 16K and 32K page sizes * containing 8K blocks */ - #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -70,6 +73,8 @@ static struct order orders[] = { #define TEST_AND_CLEAR_USED(pg,off) (test_and_clear_bit(off, &USED_MAP(pg))) #define SET_USED(pg,off) (set_bit(off, &USED_MAP(pg))) +static spinlock_t small_page_lock = SPIN_LOCK_UNLOCKED; + static void add_page_to_queue(struct page *page, struct page **p) { #ifdef PEDANTIC @@ -99,11 +104,10 @@ static unsigned long __get_small_page(int priority, struct order *order) struct page *page; int offset; - save_flags(flags); if (!order->queue) goto need_new_page; - cli(); + spin_lock_irqsave(&small_page_lock, flags); page = order->queue; again: #ifdef PEDANTIC @@ -114,12 +118,14 @@ again: SET_USED(page, offset); if (USED_MAP(page) == order->all_used) remove_page_from_queue(page); - restore_flags(flags); + spin_unlock_irqrestore(&small_page_lock, flags); return (unsigned long) page_address(page) + (offset << order->shift); need_new_page: page = alloc_page(priority); + + spin_lock_irqsave(&small_page_lock, flags); if (!order->queue) { if (!page) goto no_page; @@ -135,7 +141,7 @@ need_new_page: goto again; no_page: - restore_flags(flags); + spin_unlock_irqrestore(&small_page_lock, flags); return 0; } @@ -164,7 +170,7 @@ static void __free_small_page(unsigned long spage, struct order *order) /* * the following must be atomic wrt get_page */ - save_flags_cli(flags); + spin_lock_irqsave(&small_page_lock, flags); if (USED_MAP(page) == order->all_used) add_page_to_queue(page, &order->queue); @@ -175,7 +181,7 @@ static void __free_small_page(unsigned long spage, struct order *order) if (USED_MAP(page) == 0) goto free_page; - restore_flags(flags); + spin_unlock_irqrestore(&small_page_lock, flags); } return; @@ -184,7 +190,7 @@ free_page: * unlink the page from the small page queue and free it */ remove_page_from_queue(page); - restore_flags(flags); + spin_unlock_irqrestore(&small_page_lock, flags); ClearPageReserved(page); __free_page(page); return; diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index b922786e3..f3d1fb0b1 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -37,6 +37,11 @@ graphicsclient SA1100_GRAPHICSCLIENT GRAPHICSCLIENT 29 xp860 SA1100_XP860 XP860 30 cerf SA1100_CERF CERF 31 nanoengine SA1100_NANOENGINE NANOENGINE 32 +fpic SA1100_FPIC FPIC 33 +extenex1 SA1100_EXTENEX1 EXTENEX1 34 +sherman SA1100_SHERMAN SHERMAN 35 +accelent_sa SA1100_ACCELENT ACCELENT_SA 36 +accelent_l7200 ARCH_L7200_ACCELENT ACCELENT_L7200 37 # The following are unallocated empeg SA1100_EMPEG EMPEG diff --git a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in index 656779195..5353e7f8f 100644 --- a/arch/arm/vmlinux-armo.lds.in +++ b/arch/arm/vmlinux-armo.lds.in @@ -79,9 +79,10 @@ SECTIONS .bss : { - __bss_start = .; /* BSS */ + __bss_start = .; /* BSS */ *(.bss) - _end = . ; + *(COMMON) + _end = . ; } /* Stabs debugging sections. */ diff --git a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in index 4ef7377bb..b54f2bd92 100644 --- a/arch/arm/vmlinux-armv.lds.in +++ b/arch/arm/vmlinux-armv.lds.in @@ -42,8 +42,8 @@ SECTIONS *(.text.lock) /* out-of-line lock text */ *(.rodata) *(.kstrtab) - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; + . = ALIGN(16); + __start___ex_table = .; /* Exception table */ *(__ex_table) __stop___ex_table = .; diff --git a/arch/i386/config.in b/arch/i386/config.in index 4f41a46f7..6d1279ed7 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -128,6 +128,7 @@ if [ "$CONFIG_MWINCHIP3D" = "y" ]; then define_bool CONFIG_X86_USE_PPRO_CHECKSUM y define_bool CONFIG_X86_USE_3DNOW y fi +tristate 'Toshiba Laptop support' CONFIG_TOSHIBA tristate '/dev/cpu/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE tristate '/dev/cpu/*/msr - Model-specific register support' CONFIG_X86_MSR @@ -248,6 +249,8 @@ source drivers/pnp/Config.in source drivers/block/Config.in +source drivers/md/Config.in + if [ "$CONFIG_NET" = "y" ]; then source net/Config.in fi diff --git a/arch/i386/defconfig b/arch/i386/defconfig index ce51570da..7dddf3057 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -26,8 +26,8 @@ CONFIG_KMOD=y # CONFIG_M586 is not set # CONFIG_M586TSC is not set # CONFIG_M586MMX is not set -CONFIG_M686=y -# CONFIG_M686FXSR is not set +# CONFIG_M686 is not set +CONFIG_M686FXSR=y # CONFIG_MK6 is not set # CONFIG_MK7 is not set # CONFIG_MCRUSOE is not set @@ -44,13 +44,15 @@ CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_PGE=y CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_X86_FXSR=y +CONFIG_X86_XMM=y +# CONFIG_TOSHIBA is not set # CONFIG_MICROCODE is not set # CONFIG_X86_MSR is not set # CONFIG_X86_CPUID is not set CONFIG_NOHIGHMEM=y # CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set -# CONFIG_MATH_EMULATION is not set # CONFIG_MTRR is not set CONFIG_SMP=y CONFIG_HAVE_DEC_LOCK=y @@ -112,17 +114,24 @@ CONFIG_BLK_DEV_FD=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -224,7 +233,6 @@ CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_VIA82CXXX_TUNING is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set @@ -262,12 +270,12 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_IPS is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -276,11 +284,10 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set CONFIG_SCSI_SYM53C8XX=y @@ -299,6 +306,8 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20 # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_SEAGATE is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set @@ -357,14 +366,18 @@ CONFIG_EEPRO100=y # CONFIG_NE2K_PCI is not set # CONFIG_8139TOO is not set # CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_PPP is not set @@ -501,10 +514,6 @@ CONFIG_PCMCIA_SERIAL=y # # Multimedia devices # - -# -# Video For Linux -# # CONFIG_VIDEO_DEV is not set # @@ -588,12 +597,64 @@ CONFIG_VGA_CONSOLE=y # # Sound # -# CONFIG_SOUND is not set +CONFIG_SOUND=y +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +CONFIG_SOUND_ES1371=y +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support # -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Controllers +# +CONFIG_USB_UHCI_ALT=y +# CONFIG_USB_OHCI is not set + +# +# USB Devices +# +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_DC2XX is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_USS720 is not set +# CONFIG_USB_DABUSB is not set + +# +# USB Human Interface Devices (HID) +# + +# +# Input core support is needed for USB HID +# # # Kernel hacking diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index d1388eec3..a8ea61306 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -18,7 +18,7 @@ export-objs := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ - pci-dma.o i386_ksyms.o i387.o + pci-dma.o i386_ksyms.o i387.o bluesmoke.o ifdef CONFIG_PCI diff --git a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c index 9993d8331..211a6ce50 100644 --- a/arch/i386/kernel/acpi.c +++ b/arch/i386/kernel/acpi.c @@ -21,6 +21,12 @@ /* * See http://www.geocities.com/SiliconValley/Hardware/3165/ * for the user-level ACPI stuff + * + * Changes: + * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/08/31 + * - check copy*user return + * - get rid of check_region + * - get rid of verify_area */ #include <linux/config.h> @@ -135,8 +141,7 @@ static int acpi_do_stat(ctl_table *ctl, *len = 0; return 0; } - copy_to_user(buffer, str, size); - return 0; + return copy_to_user(buffer, str, size) ? -EFAULT : 0; } static void cx_statistics(unsigned int x, unsigned long time) @@ -1283,11 +1288,9 @@ static void acpi_power_off(void) */ static int acpi_claim(unsigned long start, unsigned long size) { - if (start && size) { - if (check_region(start, size)) + if (start && size) + if (!request_region(start, size, "acpi")) return -EBUSY; - request_region(start, size, "acpi"); - } return 0; } @@ -1391,7 +1394,8 @@ static int acpi_do_ulong(ctl_table *ctl, val = *(unsigned long*) ctl->data; size = sprintf(str, "0x%08lx\n", val); if (*len >= size) { - copy_to_user(buffer, str, size); + if (copy_to_user(buffer, str, size)) + return -EFAULT; *len = size; } else @@ -1404,7 +1408,8 @@ static int acpi_do_ulong(ctl_table *ctl, size = sizeof(str) - 1; if (size > *len) size = *len; - copy_from_user(str, buffer, size); + if (copy_from_user(str, buffer, size)) + return -EFAULT; str[size] = '\0'; val = simple_strtoul(str, &strend, 0); if (strend == str) @@ -1423,22 +1428,22 @@ static int acpi_verify_table(void *buffer, size_t size, struct acpi_table_info *info) { + struct acpi_table hdr; + size_t table_size; + if (size < sizeof(struct acpi_table)) return -EINVAL; - else if (verify_area(VERIFY_READ, buffer, size)) + + if (copy_from_user(&hdr, buffer, sizeof(hdr))) return -EFAULT; - else { - struct acpi_table hdr; - size_t table_size; - copy_from_user(&hdr, buffer, sizeof(hdr)); - table_size = (size_t) hdr.length; - if (hdr.signature != info->expected_signature - || table_size < size - || (info->expected_size - && table_size != info->expected_size)) - return -EINVAL; - } + table_size = (size_t) hdr.length; + if (hdr.signature != info->expected_signature + || table_size < size + || (info->expected_size + && table_size != info->expected_size)) + return -EINVAL; + return 0; } @@ -1496,7 +1501,8 @@ static int acpi_do_table(ctl_table *ctl, error = acpi_verify_table(buffer, *len, info); if (error) return error; - copy_from_user(&hdr, buffer, sizeof(hdr)); + if (copy_from_user(&hdr, buffer, sizeof(hdr))) + return -EFAULT; table_size = (size_t) hdr.length; write_lock(&acpi_do_table_lock); @@ -1517,7 +1523,8 @@ static int acpi_do_table(ctl_table *ctl, error = -ENOMEM; } if (data) - copy_from_user(data, buffer, size); + if (copy_from_user(data, buffer, size)) + error = -EFAULT; write_unlock(&acpi_do_table_lock); } @@ -1565,7 +1572,8 @@ static int acpi_do_event_reg(ctl_table *ctl, size = sprintf(str, "0x%08x\n", val); if (*len >= size) { - copy_to_user(buffer, str, size); + if (copy_to_user(buffer, str, size)) + return -EFAULT; *len = size; } else @@ -1580,7 +1588,8 @@ static int acpi_do_event_reg(ctl_table *ctl, size = sizeof(str) - 1; if (size > *len) size = *len; - copy_from_user(str, buffer, size); + if (copy_from_user(str, buffer, size)) + return -EFAULT; str[size] = '\0'; val = (u32) simple_strtoul(str, &strend, 0); if (strend == str) @@ -1682,7 +1691,8 @@ static int acpi_do_event(ctl_table *ctl, pm1_status, gpe_status, event_state); - copy_to_user(buffer, str, size); + if (copy_to_user(buffer, str, size)) + return -EFAULT; *len = size; file->f_pos += size; diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 1626761fb..4e5df4681 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -695,7 +695,7 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs) * [ if a single-CPU system runs an SMP kernel then we call the local * interrupt as well. Thus we cannot inline the local irq ... ] */ -unsigned int apic_timer_irqs [NR_CPUS] = { 0, }; +unsigned int apic_timer_irqs [NR_CPUS]; void smp_apic_timer_interrupt(struct pt_regs * regs) { diff --git a/arch/i386/kernel/bluesmoke.c b/arch/i386/kernel/bluesmoke.c new file mode 100644 index 000000000..0fecf5851 --- /dev/null +++ b/arch/i386/kernel/bluesmoke.c @@ -0,0 +1,109 @@ +/* + * Machine Check Handler For PII/PIII + */ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <asm/processor.h> +#include <asm/msr.h> + +static int banks = 0; + +void mcheck_fault(void) +{ + int recover=1; + u32 alow, ahigh, high, low; + u32 mcgstl, mcgsth; + int i; + + rdmsr(0x17a, mcgstl, mcgsth); + if(mcgstl&(1<<0)) /* Recoverable ? */ + recover=0; + + printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", smp_processor_id(), mcgsth, mcgstl); + + for(i=0;i<banks;i++) + { + rdmsr(0x401+i*4,low, high); + if(high&(1<<31)) + { + if(high&(1<<29)) + recover|=1; + if(high&(1<<25)) + recover|=2; + printk(KERN_EMERG "Bank %d: %08x%08x", i, high, low); + high&=~(1<<31); + if(high&(1<<27)) + { + rdmsr(0x402+i*4, alow, ahigh); + printk("[%08x%08x]", alow, ahigh); + } + if(high&(1<<26)) + { + rdmsr(0x402+i*4, alow, ahigh); + printk(" at %08x%08x", + high, low); + } + /* Clear it */ + wrmsr(0x401+i*4, 0UL, 0UL); + /* Serialize */ + wmb(); + } + } + + if(recover&2) + panic("CPU context corrupt"); + if(recover&1) + panic("Unable to continue"); + printk(KERN_EMERG "Attempting to continue.\n"); + mcgstl&=~(1<<2); + wrmsr(0x17a,mcgstl, mcgsth); +} + + +/* + * This has to be run for each processor + */ + +void mcheck_init(void) +{ + u32 l, h; + int i; + struct cpuinfo_x86 *c; + static int done=0; + + c=cpu_data+smp_processor_id(); + + if(c->x86_vendor!=X86_VENDOR_INTEL) + return; + + if(!(c->x86_capability&X86_FEATURE_MCE)) + return; + + if(!(c->x86_capability&X86_FEATURE_MCA)) + return; + + /* Ok machine check is available */ + + if(done==0) + printk(KERN_INFO "Intel machine check architecture supported.\n"); + rdmsr(0x179, l, h); + if(l&(1<<8)) + wrmsr(0x17b, 0xffffffff, 0xffffffff); + banks = l&0xff; + for(i=1;i<banks;i++) + { + wrmsr(0x400+4*i, 0xffffffff, 0xffffffff); + } + for(i=0;i<banks;i++) + { + wrmsr(0x401+4*i, 0x0, 0x0); + } + __asm__ __volatile__ ( + "movl %%cr4, %%eax\n\t" + "orl $0x40, %%eax\n\t" + "movl %%eax, %%cr4\n\t" : : : "eax"); + printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id()); + done=1; +} diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index fb9b7b2ea..57aada831 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -414,6 +414,11 @@ ENTRY(page_fault) pushl $ SYMBOL_NAME(do_page_fault) jmp error_code +ENTRY(machine_check) + pushl $0 + pushl $ SYMBOL_NAME(mcheck_fault) + jmp error_code + ENTRY(spurious_interrupt_bug) pushl $0 pushl $ SYMBOL_NAME(do_spurious_interrupt_bug) @@ -643,6 +648,7 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_madvise) .long SYMBOL_NAME(sys_getdents64) /* 220 */ .long SYMBOL_NAME(sys_fcntl64) + .long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */ /* * NOTE!! This doesn't have to be exact - we just have diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index e1b00a702..c5aece040 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -38,7 +38,7 @@ static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED; /* * # of IO-APICs and # of IRQ routing registers */ -int nr_ioapics = 0; +int nr_ioapics; int nr_ioapic_registers[MAX_IO_APICS]; /* I/O APIC entries */ @@ -48,7 +48,7 @@ struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; /* MP IRQ source entries */ -int mp_irq_entries = 0; +int mp_irq_entries; #if CONFIG_SMP # define TARGET_CPUS cpu_online_map @@ -172,8 +172,8 @@ static void clear_IO_APIC (void) #define MAX_PIRQS 8 int pirq_entries [MAX_PIRQS]; -int pirqs_enabled = 0; -int skip_ioapic_setup = 0; +int pirqs_enabled; +int skip_ioapic_setup; static int __init ioapic_setup(char *str) { @@ -219,10 +219,10 @@ static int __init find_irq_entry(int apic, int pin, int type) int i; for (i = 0; i < mp_irq_entries; i++) - if ( (mp_irqs[i].mpc_irqtype == type) && - (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid) && - (mp_irqs[i].mpc_dstirq == pin)) - + if (mp_irqs[i].mpc_irqtype == type && + (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid || + mp_irqs[i].mpc_dstapic == MP_APIC_ALL) && + mp_irqs[i].mpc_dstirq == pin) return i; return -1; @@ -262,7 +262,8 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pci_pin) int lbus = mp_irqs[i].mpc_srcbus; for (apic = 0; apic < nr_ioapics; apic++) - if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic) + if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic || + mp_irqs[i].mpc_dstapic == MP_APIC_ALL) break; if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) && @@ -982,7 +983,10 @@ void disable_IO_APIC(void) static void __init setup_ioapic_ids_from_mpc (void) { struct IO_APIC_reg_00 reg_00; + unsigned long phys_id_present_map = phys_cpu_present_map; int apic; + int i; + unsigned char old_id; /* * Set the IOAPIC ID to the value stored in the MPC table. @@ -992,6 +996,8 @@ static void __init setup_ioapic_ids_from_mpc (void) /* Read the register 0 value */ *(int *)®_00 = io_apic_read(apic, 0); + old_id = mp_ioapics[apic].mpc_apicid; + if (mp_ioapics[apic].mpc_apicid >= 0xf) { printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", apic, mp_ioapics[apic].mpc_apicid); @@ -1001,21 +1007,41 @@ static void __init setup_ioapic_ids_from_mpc (void) } /* + * Sanity check, is the ID really free? Every APIC in a + * system must have a unique ID or we get lots of nice + * 'stuck on smp_invalidate_needed IPI wait' messages. + */ + if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) { + printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", + apic, mp_ioapics[apic].mpc_apicid); + for (i = 0; i < 0xf; i++) + if (!(phys_id_present_map & (1 << i))) + break; + if (i >= 0xf) + panic("Max APIC ID exceeded!\n"); + printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", + i); + phys_id_present_map |= 1 << i; + mp_ioapics[apic].mpc_apicid = i; + } + + /* + * We need to adjust the IRQ routing table + * if the ID changed. + */ + if (old_id != mp_ioapics[apic].mpc_apicid) + for (i = 0; i < mp_irq_entries; i++) + if (mp_irqs[i].mpc_dstapic == old_id) + mp_irqs[i].mpc_dstapic + = mp_ioapics[apic].mpc_apicid; + + /* * Read the right value from the MPC table and * write it into the ID register. */ printk(KERN_INFO "...changing IO-APIC physical APIC ID to %d ...", mp_ioapics[apic].mpc_apicid); - /* - * Sanity check, is the ID really free? Every APIC in the - * system must have a unique ID or we get lots of nice - * 'stuck on smp_invalidate_needed IPI wait' messages. - */ - if (phys_cpu_present_map & (1<<mp_ioapics[apic].mpc_apicid)) - panic("APIC ID %d already used", - mp_ioapics[apic].mpc_apicid); - reg_00.ID = mp_ioapics[apic].mpc_apicid; io_apic_write(apic, 0, *(int *)®_00); diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index 1d5b7b3c8..80536a1c4 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c @@ -37,6 +37,13 @@ * Removed ->release(). Removed exclusive open and status bitmap. * Added microcode_rwsem to serialize read()/write()/ioctl(). * Removed global kernel lock usage. + * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com> + * Write 0 to 0x8B msr and then cpuid before reading revision, + * so that it works even if there were no update done by the + * BIOS. Otherwise, reading from 0x8B gives junk (which happened + * to be 0 on my machine which is why it worked even when I + * disabled update by the BIOS) + * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix. */ #include <linux/init.h> @@ -51,7 +58,7 @@ #include <asm/uaccess.h> #include <asm/processor.h> -#define MICROCODE_VERSION "1.06" +#define MICROCODE_VERSION "1.07" MODULE_DESCRIPTION("Intel CPU (P6) microcode update driver"); MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>"); @@ -188,7 +195,8 @@ static void do_update_one(void *unused) microcode[i].ldrver == 1 && microcode[i].hdrver == 1) { found=1; - + wrmsr(0x8B, 0, 0); + __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); rdmsr(0x8B, val[0], rev); if (microcode[i].rev <= rev) { printk(KERN_ERR diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 746bea030..b17c30041 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -28,26 +28,26 @@ #include <asm/pgalloc.h> /* Have we found an MP table */ -int smp_found_config = 0; +int smp_found_config; /* * Various Linux-internal data structures created from the * MP-table. */ int apic_version [MAX_APICS]; -int mp_bus_id_to_type [MAX_MP_BUSSES] = { -1, }; +int mp_bus_id_to_type [MAX_MP_BUSSES]; int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { -1, }; -int mp_current_pci_id = 0; +int mp_current_pci_id; int pic_mode; -unsigned long mp_lapic_addr = 0; +unsigned long mp_lapic_addr; /* Processor that is doing the boot up */ unsigned int boot_cpu_id = -1U; /* Internal processor count */ -static unsigned int num_processors = 0; +static unsigned int num_processors; /* Bitmask of physically existing CPUs */ -unsigned long phys_cpu_present_map = 0; +unsigned long phys_cpu_present_map; /* * Intel MP BIOS table parsing routines: @@ -158,19 +158,18 @@ static void __init MP_bus_info (struct mpc_config_bus *m) str[6] = 0; Dprintk("Bus #%d is %s\n", m->mpc_busid, str); - if (strncmp(str, "ISA", 3) == 0) { + if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; - } else if (strncmp(str, "EISA", 4) == 0) { + } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA; - } else if (strncmp(str, "PCI", 3) == 0) { + } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id; mp_current_pci_id++; - } else if (strncmp(str, "MCA", 3) == 0) { + } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA; } else { - printk("Unknown bustype %s\n", str); - panic("cannot handle bus - mail to linux-smp@vger.kernel.org"); + printk("Unknown bustype %s - ignoring\n", str); } } diff --git a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c index 05b57c93a..abe198315 100644 --- a/arch/i386/kernel/mtrr.c +++ b/arch/i386/kernel/mtrr.c @@ -319,10 +319,10 @@ typedef u8 mtrr_type; #endif #ifdef USERSPACE_INTERFACE -static char *ascii_buffer = NULL; -static unsigned int ascii_buf_bytes = 0; +static char *ascii_buffer; +static unsigned int ascii_buf_bytes; #endif -static unsigned int *usage_table = NULL; +static unsigned int *usage_table; static DECLARE_MUTEX(main_lock); /* Private functions */ @@ -356,7 +356,8 @@ static void set_mtrr_prepare (struct set_mtrr_context *ctxt) if (boot_cpu_data.x86 >= 6) break; /* Athlon and post-Athlon CPUs */ /* else fall through */ case X86_VENDOR_CENTAUR: - return; + if(boot_cpu_data.x86 != 6) + return; /*break;*/ } /* Save value of CR4 and clear Page Global Enable (bit 7) */ @@ -380,6 +381,7 @@ static void set_mtrr_prepare (struct set_mtrr_context *ctxt) { case X86_VENDOR_AMD: case X86_VENDOR_INTEL: + case X86_VENDOR_CENTAUR: /* Disable MTRRs, and set the default type to uncached */ rdmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi); wrmsr (MTRRdefType_MSR, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi); @@ -403,8 +405,11 @@ static void set_mtrr_done (struct set_mtrr_context *ctxt) if (boot_cpu_data.x86 >= 6) break; /* Athlon and post-Athlon CPUs */ /* else fall through */ case X86_VENDOR_CENTAUR: - __restore_flags (ctxt->flags); - return; + if(boot_cpu_data.x86 != 6) + { + __restore_flags (ctxt->flags); + return; + } /*break;*/ } /* Flush caches and TLBs */ @@ -415,6 +420,7 @@ static void set_mtrr_done (struct set_mtrr_context *ctxt) { case X86_VENDOR_AMD: case X86_VENDOR_INTEL: + case X86_VENDOR_CENTAUR: wrmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi); break; case X86_VENDOR_CYRIX: @@ -453,9 +459,17 @@ static unsigned int get_num_var_ranges (void) /*break;*/ case X86_VENDOR_CYRIX: /* Cyrix have 8 ARRs */ + return 8; case X86_VENDOR_CENTAUR: /* and Centaur has 8 MCR's */ - return 8; + if(boot_cpu_data.x86==5) + return 8; + /* the cyrix III has intel compatible MTRR */ + if(boot_cpu_data.x86==6) + { + rdmsr (MTRRcap_MSR, config, dummy); + return (config & 0xff); + } /*break;*/ } return 0; @@ -471,12 +485,15 @@ static int have_wrcomb (void) case X86_VENDOR_AMD: if (boot_cpu_data.x86 < 6) return 1; /* pre-Athlon CPUs */ /* else fall through */ + case X86_VENDOR_CENTAUR: + if (boot_cpu_data.x86 == 5) + return 1; /* C6 */ + /* CyrixIII is Intel like */ case X86_VENDOR_INTEL: rdmsr (MTRRcap_MSR, config, dummy); return (config & (1<<10)); /*break;*/ case X86_VENDOR_CYRIX: - case X86_VENDOR_CENTAUR: return 1; /*break;*/ } @@ -623,7 +640,7 @@ static void centaur_get_mcr (unsigned int reg, unsigned long *base, } /* End Function centaur_get_mcr */ static void (*get_mtrr) (unsigned int reg, unsigned long *base, - unsigned long *size, mtrr_type *type) = NULL; + unsigned long *size, mtrr_type *type); static void intel_set_mtrr_up (unsigned int reg, unsigned long base, unsigned long size, mtrr_type type, int do_safe) @@ -766,7 +783,7 @@ static void centaur_set_mcr_up (unsigned int reg, unsigned long base, static void (*set_mtrr_up) (unsigned int reg, unsigned long base, unsigned long size, mtrr_type type, - int do_safe) = NULL; + int do_safe); #ifdef CONFIG_SMP @@ -1194,7 +1211,7 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc printk ("mtrr: size: %lx base: %lx\n", size, base); return -EINVAL; } - if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR) + if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR && boot_cpu_data.x86 == 5) { if (type != MTRR_TYPE_WRCOMB) { @@ -1779,8 +1796,16 @@ static void __init mtrr_setup(void) get_free_region = cyrix_get_free_region; break; case X86_VENDOR_CENTAUR: - get_mtrr = centaur_get_mcr; - set_mtrr_up = centaur_set_mcr_up; + if(boot_cpu_data.x86 == 5) + { + get_mtrr = centaur_get_mcr; + set_mtrr_up = centaur_set_mcr_up; + } + if(boot_cpu_data.x86 == 6) + { + get_mtrr = intel_get_mtrr; + set_mtrr_up = intel_set_mtrr_up; + } break; } } /* End Function mtrr_setup */ @@ -1804,8 +1829,11 @@ void __init mtrr_init_boot_cpu(void) case X86_VENDOR_CYRIX: cyrix_arr_init (); break; - case X86_VENDOR_CENTAUR: - centaur_mcr_init (); + case X86_VENDOR_CENTAUR: /* C6 and Cyrix III have different ones */ + if(boot_cpu_data.x86 == 5) + centaur_mcr_init (); + if(boot_cpu_data.x86 == 6) + get_mtrr_state(&smp_mtrr_state); break; } } /* End Function mtrr_init_boot_cpu */ @@ -1877,7 +1905,8 @@ int __init mtrr_init(void) cyrix_arr_init (); break; case X86_VENDOR_CENTAUR: - centaur_mcr_init (); + if(boot_cpu_data.x86 == 5) + centaur_mcr_init (); break; } #endif /* !CONFIG_SMP */ diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 83ec9d192..6d3cf4d9a 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -50,17 +50,17 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); -int hlt_counter=0; +int hlt_counter; /* * Powermanagement idle function, if any.. */ -void (*pm_idle)(void) = NULL; +void (*pm_idle)(void); /* * Power off function, if any */ -void (*pm_power_off)(void) = NULL; +void (*pm_power_off)(void); void disable_hlt(void) { @@ -149,9 +149,9 @@ static int __init idle_setup (char *str) __setup("idle=", idle_setup); -static long no_idt[2] = {0, 0}; -static int reboot_mode = 0; -static int reboot_thru_bios = 0; +static long no_idt[2]; +static int reboot_mode; +static int reboot_thru_bios; static int __init reboot_setup(char *str) { @@ -525,6 +525,7 @@ void copy_segments(struct task_struct *p, struct mm_struct *new_mm) asm volatile("movl %%" #seg ",%0":"=m" (*(int *)&(value))) int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, + unsigned long unused, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; @@ -686,7 +687,7 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p) asmlinkage int sys_fork(struct pt_regs regs) { - return do_fork(SIGCHLD, regs.esp, ®s); + return do_fork(SIGCHLD, regs.esp, ®s, 0); } asmlinkage int sys_clone(struct pt_regs regs) @@ -698,7 +699,7 @@ asmlinkage int sys_clone(struct pt_regs regs) newsp = regs.ecx; if (!newsp) newsp = regs.esp; - return do_fork(clone_flags, newsp, ®s); + return do_fork(clone_flags, newsp, ®s, 0); } /* @@ -713,7 +714,7 @@ asmlinkage int sys_clone(struct pt_regs regs) */ asmlinkage int sys_vfork(struct pt_regs regs) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s); + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0); } /* diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 0bafdc7e2..a9b11561d 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -99,6 +99,7 @@ static int putreg(struct task_struct *child, case EFL: value &= FLAG_MASK; value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK; + break; } if (regno > GS*4) regno -= 2*4; diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index e79572f90..e765a0e94 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -95,22 +95,22 @@ * Machine setup.. */ -char ignore_irq13 = 0; /* set if exception 16 works */ +char ignore_irq13; /* set if exception 16 works */ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; -unsigned long mmu_cr4_features = 0; +unsigned long mmu_cr4_features; /* * Bus types .. */ -int EISA_bus = 0; -int MCA_bus = 0; +int EISA_bus; +int MCA_bus; /* for MCA, but anyone else can use it if they want */ -unsigned int machine_id = 0; -unsigned int machine_submodel_id = 0; -unsigned int BIOS_revision = 0; -unsigned int mca_pentium_flag = 0; +unsigned int machine_id; +unsigned int machine_submodel_id; +unsigned int BIOS_revision; +unsigned int mca_pentium_flag; /* * Setup options @@ -123,7 +123,7 @@ struct sys_desc_table_struct { unsigned char table[0]; }; -struct e820map e820 = { 0 }; +struct e820map e820; unsigned char aux_device_present; @@ -135,7 +135,7 @@ extern int rd_image_start; /* starting block # of image */ extern int root_mountflags; extern char _text, _etext, _edata, _end; -extern unsigned long cpu_hz; +extern unsigned long cpu_khz; /* * This is set up by the setup-routine at boot-time @@ -291,7 +291,7 @@ visws_get_board_type_and_rev(void) #endif -static char command_line[COMMAND_LINE_SIZE] = { 0, }; +static char command_line[COMMAND_LINE_SIZE]; char saved_command_line[COMMAND_LINE_SIZE]; struct resource standard_io_resources[] = { @@ -875,7 +875,8 @@ static int __init amd_model(struct cpuinfo_x86 *c) * Set MTRR capability flag if appropriate */ if(boot_cpu_data.x86 == 5) { - if((boot_cpu_data.x86_model == 9) || + if((boot_cpu_data.x86_model == 13) || + (boot_cpu_data.x86_model == 9) || ((boot_cpu_data.x86_model == 8) && (boot_cpu_data.x86_mask >= 8))) c->x86_capability |= X86_FEATURE_MTRR; @@ -916,7 +917,7 @@ static int __init amd_model(struct cpuinfo_x86 *c) } break; } - if (c->x86_model == 8 || c->x86_model == 9) + if (c->x86_model == 8 || c->x86_model == 9 || c->x86_model == 13) { /* The more serious chips .. */ @@ -1650,6 +1651,7 @@ int get_cpuinfo(char * buffer) int i, n; for (n = 0; n < NR_CPUS; n++, c++) { + int fpu_exception; #ifdef CONFIG_SMP if (!(cpu_online_map & (1<<n))) continue; @@ -1672,7 +1674,7 @@ int get_cpuinfo(char * buffer) if (c->x86_capability & X86_FEATURE_TSC) { p += sprintf(p, "cpu MHz\t\t: %lu.%06lu\n", - cpu_hz / 1000000, (cpu_hz % 1000000)); + cpu_khz / 1000, (cpu_khz % 1000)); } /* Cache size */ @@ -1722,7 +1724,9 @@ int get_cpuinfo(char * buffer) (c->x86_capability & X86_FEATURE_SEP) && c->x86_model < 3 && c->x86_mask < 3; - + + /* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */ + fpu_exception = c->hard_math && (ignore_irq13 | (c->x86_capability & X86_FEATURE_FPU)); p += sprintf(p, "fdiv_bug\t: %s\n" "hlt_bug\t\t: %s\n" "sep_bug\t\t: %s\n" @@ -1739,7 +1743,7 @@ int get_cpuinfo(char * buffer) c->f00f_bug ? "yes" : "no", c->coma_bug ? "yes" : "no", c->hard_math ? "yes" : "no", - (c->hard_math && ignore_irq13) ? "yes" : "no", + fpu_exception ? "yes" : "no", c->cpuid_level, c->wp_works_ok ? "yes" : "no"); diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index 116816f1f..2423a8b06 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c @@ -682,7 +682,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); @@ -690,6 +690,13 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) } } + /* Reenable any watchpoints before delivering the + * signal to user space. The processor register will + * have been cleared if the watchpoint triggered + * inside the kernel. + */ + __asm__("movl %0,%%db7" : : "r" (current->thread.debugreg[7])); + /* Whee! Actually deliver the signal. */ handle_signal(signr, ka, &info, oldset, regs); return 1; diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 4a118ab17..6ce9eb61e 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -414,13 +414,15 @@ void smp_send_reschedule(int cpu) */ static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; -static volatile struct call_data_struct { +struct call_data_struct { void (*func) (void *info); void *info; atomic_t started; atomic_t finished; int wait; -} *call_data = NULL; +}; + +static struct call_data_struct * call_data = NULL; /* * this function sends a 'generic call function' IPI to all other CPUs @@ -443,7 +445,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, */ { struct call_data_struct data; - int ret, cpus = smp_num_cpus-1; + int cpus = smp_num_cpus-1; if (!cpus) return 0; @@ -464,7 +466,6 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, while (atomic_read(&data.started) != cpus) barrier(); - ret = 0; if (wait) while (atomic_read(&data.finished) != cpus) barrier(); diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 7629bb3d2..6092aec3b 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -46,7 +46,7 @@ #include <asm/pgalloc.h> /* Set if we find a B stepping CPU */ -static int smp_b_stepping = 0; +static int smp_b_stepping; /* Setup configured maximum number of CPUs to activate */ static int max_cpus = -1; @@ -55,21 +55,21 @@ static int max_cpus = -1; int smp_num_cpus = 1; /* Bitmask of currently online CPUs */ -unsigned long cpu_online_map = 0; +unsigned long cpu_online_map; /* which CPU (physical APIC ID) maps to which logical CPU number */ volatile int x86_apicid_to_cpu[NR_CPUS]; /* which logical CPU number maps to which CPU (physical APIC ID) */ volatile int x86_cpu_to_apicid[NR_CPUS]; -static volatile unsigned long cpu_callin_map = 0; -static volatile unsigned long cpu_callout_map = 0; +static volatile unsigned long cpu_callin_map; +static volatile unsigned long cpu_callout_map; /* Per CPU bogomips and other parameters */ struct cpuinfo_x86 cpu_data[NR_CPUS]; /* Set when the idlers are all forked */ -int smp_threads_ready = 0; +int smp_threads_ready; /* * Setup routine for controlling SMP activation @@ -194,7 +194,7 @@ void __init smp_commence(void) static atomic_t tsc_start_flag = ATOMIC_INIT(0); static atomic_t tsc_count_start = ATOMIC_INIT(0); static atomic_t tsc_count_stop = ATOMIC_INIT(0); -static unsigned long long tsc_values[NR_CPUS] = { 0, }; +static unsigned long long tsc_values[NR_CPUS]; #define NR_LOOPS 5 @@ -438,7 +438,7 @@ void __init smp_callin(void) synchronize_tsc_ap(); } -int cpucount = 0; +int cpucount; extern int cpu_idle(void); @@ -497,7 +497,7 @@ static int __init fork_by_hand(void) * don't care about the eip and regs settings since * we'll never reschedule the forked task. */ - return do_fork(CLONE_VM|CLONE_PID, 0, ®s); + return do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0); } #if APIC_DEBUG @@ -774,7 +774,7 @@ static void __init do_boot_cpu (int apicid) } cycles_t cacheflush_time; -extern unsigned long cpu_hz; +extern unsigned long cpu_khz; static void smp_tune_scheduling (void) { @@ -791,7 +791,7 @@ static void smp_tune_scheduling (void) * the cache size) */ - if (!cpu_hz) { + if (!cpu_khz) { /* * this basically disables processor-affinity * scheduling on SMP without a TSC. @@ -805,12 +805,12 @@ static void smp_tune_scheduling (void) bandwidth = 100; } - cacheflush_time = (cpu_hz>>20) * (cachesize<<10) / bandwidth; + cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth; } printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n", - (long)cacheflush_time/(cpu_hz/1000000), - ((long)cacheflush_time*100/(cpu_hz/1000000)) % 100); + (long)cacheflush_time/(cpu_khz/1000), + ((long)cacheflush_time*100/(cpu_khz/1000)) % 100); } /* diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 4bb184112..3a9df08e7 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -64,7 +64,7 @@ #include <linux/irq.h> -unsigned long cpu_hz; /* Detected as we calibrate the TSC */ +unsigned long cpu_khz; /* Detected as we calibrate the TSC */ /* Number of usecs that the last interrupt was delayed */ static int delay_at_last_interrupt; @@ -504,37 +504,6 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) } -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - /* not static: needed by APM */ unsigned long get_cmos_time(void) { @@ -707,12 +676,12 @@ void __init time_init(void) * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = * clock/second. Our precision is about 100 ppm. */ - { unsigned long eax=0, edx=1000000; + { unsigned long eax=0, edx=1000; __asm__("divl %2" - :"=a" (cpu_hz), "=d" (edx) + :"=a" (cpu_khz), "=d" (edx) :"r" (tsc_quotient), "0" (eax), "1" (edx)); - printk("Detected %ld Hz processor.\n", cpu_hz); + printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); } } } diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 7bd8a04d0..953c23d55 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -95,6 +95,7 @@ asmlinkage void simd_coprocessor_error(void); asmlinkage void reserved(void); asmlinkage void alignment_check(void); asmlinkage void spurious_interrupt_bug(void); +asmlinkage void machine_check(void); int kstack_depth_to_print = 24; @@ -415,8 +416,8 @@ inline void nmi_watchdog_tick(struct pt_regs * regs) * here too!] */ - static unsigned int last_irq_sums [NR_CPUS] = { 0, }, - alert_counter [NR_CPUS] = { 0, }; + static unsigned int last_irq_sums [NR_CPUS], + alert_counter [NR_CPUS]; /* * Since current-> is always on the stack, and we always switch @@ -491,17 +492,26 @@ asmlinkage void do_nmi(struct pt_regs * regs, long error_code) } /* - * Careful - we must not do a lock-kernel until we have checked that the - * debug fault happened in user mode. Getting debug exceptions while - * in the kernel has to be handled without locking, to avoid deadlocks.. + * Our handling of the processor debug registers is non-trivial. + * We do not clear them on entry and exit from the kernel. Therefore + * it is possible to get a watchpoint trap here from inside the kernel. + * However, the code in ./ptrace.c has ensured that the user can + * only set watchpoints on userspace addresses. Therefore the in-kernel + * watchpoint trap can only occur in code which is reading/writing + * from user space. Such code must not hold kernel locks (since it + * can equally take a page fault), therefore it is safe to call + * force_sig_info even though that claims and releases locks. + * + * Code in ./signal.c ensures that the debug control register + * is restored before we deliver any signal, and therefore that + * user code runs with the correct debug control register even though + * we clear it here. * * Being careful here means that we don't have to be as careful in a * lot of more complicated places (task switching can be a bit lazy * about restoring all the debug state, and ptrace doesn't have to * find every occurrence of the TF bit that could be saved away even - * by user code - and we don't have to be careful about what values - * can be written to the debug registers because there are no really - * bad cases). + * by user code) */ asmlinkage void do_debug(struct pt_regs * regs, long error_code) { @@ -520,6 +530,9 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code) if (regs->eflags & VM_MASK) goto debug_vm86; + /* Save debug status register where ptrace can see it */ + tsk->thread.debugreg[6] = condition; + /* Mask out spurious TF errors due to lazy TF clearing */ if (condition & DR_STEP) { /* @@ -535,30 +548,33 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code) goto clear_TF; } - /* If this is a kernel mode trap, we need to reset db7 to allow us to continue sanely */ - if ((regs->xcs & 3) == 0) - goto clear_dr7; - /* Ok, finally something we can handle */ tsk->thread.trap_no = 1; tsk->thread.error_code = error_code; info.si_signo = SIGTRAP; info.si_errno = 0; info.si_code = TRAP_BRKPT; - info.si_addr = (void *)regs->eip; + + /* If this is a kernel mode trap, save the user PC on entry to + * the kernel, that's what the debugger can make sense of. + */ + info.si_addr = ((regs->xcs & 3) == 0) ? (void *)tsk->thread.eip : + (void *)regs->eip; force_sig_info(SIGTRAP, &info, tsk); - return; - -debug_vm86: - handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); - return; + /* Disable additional traps. They'll be re-enabled when + * the signal is delivered. + */ clear_dr7: __asm__("movl %0,%%db7" : /* no output */ : "r" (0)); return; +debug_vm86: + handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); + return; + clear_TF: regs->eflags &= ~TF_MASK; return; @@ -641,7 +657,6 @@ void simd_math_error(void *eip) */ task = current; save_init_fpu(task); - load_mxcsr(0x1f80); task->thread.trap_no = 19; task->thread.error_code = 0; info.si_signo = SIGFPE; @@ -964,6 +979,7 @@ void __init trap_init(void) set_trap_gate(15,&spurious_interrupt_bug); set_trap_gate(16,&coprocessor_error); set_trap_gate(17,&alignment_check); + set_trap_gate(18,&machine_check); set_trap_gate(19,&simd_coprocessor_error); set_system_gate(SYSCALL_VECTOR,&system_call); diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index 9875a3bdb..15b20d695 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c @@ -565,8 +565,8 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) static struct vm86_irqs { struct task_struct *tsk; int sig; -} vm86_irqs[16] = {{0},}; -static int irqbits=0; +} vm86_irqs[16]; +static int irqbits; #define ALLOWED_SIGS ( 1 /* 0 = don't send a signal */ \ | (1 << SIGUSR1) | (1 << SIGUSR2) | (1 << SIGIO) | (1 << SIGURG) \ diff --git a/arch/i386/lib/checksum.S b/arch/i386/lib/checksum.S index 0d66abee0..bfc638953 100644 --- a/arch/i386/lib/checksum.S +++ b/arch/i386/lib/checksum.S @@ -394,26 +394,32 @@ csum_partial_copy_generic: movl ARGBASE+8(%esp),%edi #dst movl ARGBASE+12(%esp),%ecx #len movl ARGBASE+16(%esp),%eax #sum - movl %ecx, %edx +# movl %ecx, %edx movl %ecx, %ebx + movl %esi, %edx shrl $6, %ecx andl $0x3c, %ebx negl %ebx subl %ebx, %esi subl %ebx, %edi + lea -1(%esi),%edx + andl $-32,%edx lea 3f(%ebx,%ebx), %ebx testl %esi, %esi - jmp *%ebx + jmp *%ebx 1: addl $64,%esi addl $64,%edi + SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl) ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52) ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36) ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20) ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4) 3: adcl $0,%eax + addl $64, %edx dec %ecx jge 1b -4: andl $3, %edx +4: movl ARGBASE+12(%esp),%edx #len + andl $3, %edx jz 7f cmpl $2, %edx jb 5f diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index ba5c2e7ba..66f846925 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c @@ -126,7 +126,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag t_addr = __va(phys_addr); t_end = t_addr + (size - 1); - for(page = virt_to_page(t_addr); page < virt_to_page(t_end); page++) + for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++) if(!PageReserved(page)) return NULL; } diff --git a/arch/ia64/config.in b/arch/ia64/config.in index 0fdf86c19..97d622276 100644 --- a/arch/ia64/config.in +++ b/arch/ia64/config.in @@ -99,6 +99,7 @@ source drivers/mtd/Config.in source drivers/pnp/Config.in source drivers/block/Config.in source drivers/i2o/Config.in +source drivers/md/Config.in mainmenu_option next_comment comment 'ATA/IDE/MFM/RLL support' diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index ad963b92f..5fb064a3b 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S @@ -91,8 +91,8 @@ GLOBAL_ENTRY(sys32_fork) UNW(.body) mov out1=0 - mov out2=0 - adds out3=IA64_SWITCH_STACK_SIZE+16,sp + mov out3=0 + adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = ®s br.call.sptk.few rp=do_fork .ret3: mov ar.pfs=loc1 UNW(.restore sp) diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index d55835df6..32d83ae75 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -98,37 +98,6 @@ phys_reset_system (int reset_type, efi_status_t status, efi_call_phys(__va(runtime->reset_system), status, data_size, __pa(data)); } -/* - * Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long -mktime (unsigned int year, unsigned int mon, unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((((unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) - + year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - void efi_gettimeofday (struct timeval *tv) { diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index e37bd0df8..eba75378e 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -68,8 +68,8 @@ GLOBAL_ENTRY(sys_clone2) mov loc1=r16 // save ar.pfs across do_fork UNW(.body) mov out1=in1 - mov out2=in2 - adds out3=IA64_SWITCH_STACK_SIZE+16,sp // out3 = ®s + mov out3=in2 + adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = ®s mov out0=in0 // out0 = clone_flags br.call.sptk.few rp=do_fork .ret1: UNW(.restore sp) @@ -87,8 +87,8 @@ GLOBAL_ENTRY(sys_clone) mov loc1=r16 // save ar.pfs across do_fork UNW(.body) mov out1=in1 - mov out2=0 - adds out3=IA64_SWITCH_STACK_SIZE+16,sp // out3 = ®s + mov out3=0 + adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = ®s mov out0=in0 // out0 = clone_flags br.call.sptk.few rp=do_fork .ret2: UNW(.restore sp) diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index ca0f7a981..12f312672 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -570,7 +570,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/m68k/config.in b/arch/m68k/config.in index 076d9107c..83381857f 100644 --- a/arch/m68k/config.in +++ b/arch/m68k/config.in @@ -149,6 +149,8 @@ source drivers/mtd/Config.in source drivers/block/Config.in +source drivers/md/Config.in + if [ "$CONFIG_NET" = "y" ]; then source net/Config.in fi diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index ef4a49339..6934e4168 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -181,12 +181,12 @@ void flush_thread(void) asmlinkage int m68k_fork(struct pt_regs *regs) { - return do_fork(SIGCHLD, rdusp(), regs); + return do_fork(SIGCHLD, rdusp(), regs, 0); } asmlinkage int m68k_vfork(struct pt_regs *regs) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs); + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0); } asmlinkage int m68k_clone(struct pt_regs *regs) @@ -199,10 +199,11 @@ asmlinkage int m68k_clone(struct pt_regs *regs) newsp = regs->d2; if (!newsp) newsp = rdusp(); - return do_fork(clone_flags, newsp, regs); + return do_fork(clone_flags, newsp, regs, 0); } int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, + unsigned long unused, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index d67617bea..fa13dc390 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -1137,7 +1137,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index 9b98fdb75..c58f4eeeb 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c @@ -102,37 +102,6 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs) #endif /* CONFIG_HEARTBEAT */ } -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - void time_init(void) { unsigned int year, mon, day, hour, min, sec; diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c index a14f25c56..d6065716a 100644 --- a/arch/m68k/mac/misc.c +++ b/arch/m68k/mac/misc.c @@ -11,6 +11,7 @@ #include <linux/delay.h> #include <linux/sched.h> #include <linux/malloc.h> +#include <linux/time.h> #include <linux/kd.h> #include <linux/mm.h> @@ -499,37 +500,6 @@ void mac_reset(void) while(1); } -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - /* * This function translates seconds since 1970 into a proper date. * diff --git a/arch/mips/baget/vacserial.c b/arch/mips/baget/vacserial.c index cd56c6dd3..1c2918e5b 100644 --- a/arch/mips/baget/vacserial.c +++ b/arch/mips/baget/vacserial.c @@ -2843,7 +2843,7 @@ long __init serial_console_init(long kmem_start, long kmem_end) * device more directly. */ -static int initialized = 0; +static int initialized; static int rs_debug_init(struct async_struct *info) { diff --git a/arch/mips/config.in b/arch/mips/config.in index 8515a7900..5a0a0642c 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -197,6 +197,8 @@ source drivers/mtd/Config.in source drivers/block/Config.in +source drivers/md/Config.in + if [ "$CONFIG_NET" = "y" ]; then source net/Config.in fi diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index a71ad234a..4e1ec7ba1 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c @@ -423,37 +423,6 @@ static void ioasic_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) timer_interrupt(irq, dev_id, regs); } -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long) (year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) + - year * 365 - 719499 - ) * 24 + hour /* now have hours */ - ) * 60 + min /* now have minutes */ - ) * 60 + sec; /* finally seconds */ -} - char cyclecounter_available; static inline void init_cycle_counter(void) diff --git a/arch/mips/defconfig b/arch/mips/defconfig index c1538c663..9b3379fb5 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -87,17 +87,24 @@ CONFIG_SYSCTL=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -169,7 +176,7 @@ CONFIG_SCSI_CONSTANTS=y # # SCSI low-level drivers # -CONFIG_SCSI_SGIWD93=y +CONFIG_SGIWD93_SCSI=y # CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AHA152X is not set @@ -192,14 +199,14 @@ CONFIG_SCSI_SGIWD93=y # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_DEBUG is not set diff --git a/arch/mips/defconfig-cobalt b/arch/mips/defconfig-cobalt index 627cc710b..57dd72f33 100644 --- a/arch/mips/defconfig-cobalt +++ b/arch/mips/defconfig-cobalt @@ -86,22 +86,27 @@ CONFIG_SYSCTL=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set -CONFIG_BLK_DEV_MD=y -CONFIG_MD_LINEAR=y -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_BOOT is not set -# CONFIG_AUTODETECT_RAID is not set CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_BLK_DEV_INITRD is not set # +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set + +# # Networking options # # CONFIG_PACKET is not set @@ -202,6 +207,7 @@ CONFIG_AIC7XXX_RESET_DELAY=5 # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -213,8 +219,6 @@ CONFIG_AIC7XXX_RESET_DELAY=5 # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set CONFIG_SCSI_NCR53C8XX=y # CONFIG_SCSI_SYM53C8XX is not set @@ -232,6 +236,8 @@ CONFIG_SCSI_NCR53C8XX_IOMAPPED=y # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set @@ -284,8 +290,9 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -509,7 +516,7 @@ CONFIG_NFS_FS=y CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_SMB_FS=m -CONFIG_SMB_NLS_REMOTE="" +# CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set # CONFIG_NCPFS_IOCTL_LOCKING is not set diff --git a/arch/mips/defconfig-decstation b/arch/mips/defconfig-decstation index b79e4bcb3..882182fff 100644 --- a/arch/mips/defconfig-decstation +++ b/arch/mips/defconfig-decstation @@ -81,17 +81,24 @@ CONFIG_TC=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -173,14 +180,14 @@ CONFIG_SCSI_DECNCR=y # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_DEBUG is not set diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22 index 5ceb991b4..9b3379fb5 100644 --- a/arch/mips/defconfig-ip22 +++ b/arch/mips/defconfig-ip22 @@ -87,17 +87,24 @@ CONFIG_SYSCTL=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -169,7 +176,7 @@ CONFIG_SCSI_CONSTANTS=y # # SCSI low-level drivers # -CONFIG_SCSI_SGIWD93=y +CONFIG_SGIWD93_SCSI=y # CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AHA152X is not set @@ -192,14 +199,14 @@ CONFIG_SCSI_SGIWD93=y # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_DEBUG is not set @@ -220,8 +227,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_SGI_NEWPORT_CONSOLE=y CONFIG_FONT_8x16=y -CONFIG_PSMOUSE=y -CONFIG_MOUSE=y +# CONFIG_PSMOUSE is not set # CONFIG_UNIX98_PTYS is not set # diff --git a/arch/mips/defconfig-orion b/arch/mips/defconfig-orion index 928d48c73..01dc2b78b 100644 --- a/arch/mips/defconfig-orion +++ b/arch/mips/defconfig-orion @@ -82,18 +82,25 @@ CONFIG_NET=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options diff --git a/arch/mips/defconfig-rm200 b/arch/mips/defconfig-rm200 index a418643e2..88c3ab1d5 100644 --- a/arch/mips/defconfig-rm200 +++ b/arch/mips/defconfig-rm200 @@ -90,17 +90,24 @@ CONFIG_BLK_DEV_FD=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c index 2aff468fa..e0986a61a 100644 --- a/arch/mips/kernel/gdb-stub.c +++ b/arch/mips/kernel/gdb-stub.c @@ -115,7 +115,7 @@ void handle_exception(struct gdb_regs *regs); static char input_buffer[BUFMAX]; static char output_buffer[BUFMAX]; -static int initialized = 0; /* !0 means we've been initialized */ +static int initialized; /* !0 means we've been initialized */ static const char hexchars[]="0123456789abcdef"; diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index 3329e5e84..5f63b0910 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -1127,7 +1127,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file) notes[0].datasz = sizeof(prstatus); notes[0].data = &prstatus; prstatus.pr_info.si_signo = prstatus.pr_cursig = signr; - prstatus.pr_sigpend = current->signal.sig[0]; + prstatus.pr_sigpend = current->pending.signal.sig[0]; prstatus.pr_sighold = current->blocked.sig[0]; psinfo.pr_pid = prstatus.pr_pid = current->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid; diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c index 7254ee95d..6f6556da4 100644 --- a/arch/mips/kernel/irixsig.c +++ b/arch/mips/kernel/irixsig.c @@ -264,7 +264,7 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); @@ -429,24 +429,7 @@ irix_sigaction(int sig, const struct sigaction *act, asmlinkage int irix_sigpending(irix_sigset_t *set) { - int err; - - if (verify_area(VERIFY_WRITE, set, sizeof(*set)) < 0) - return -EFAULT; - - /* fill in "set" with signals pending but blocked. */ - spin_lock_irq(¤t->sigmask_lock); - err = __put_user(current->blocked.sig[0] & current->signal.sig[0], - &set->sig[0]); - err |= __put_user(current->blocked.sig[1] & current->signal.sig[1], - &set->sig[1]); - err |= __put_user(current->blocked.sig[2] & current->signal.sig[2], - &set->sig[2]); - err |= __put_user(current->blocked.sig[3] & current->signal.sig[3], - &set->sig[3]); - spin_unlock_irq(¤t->sigmask_lock); - - return err; + return do_sigpending(set, sizeof(*set)); } asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old) @@ -605,7 +588,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, expire = schedule_timeout(expire); for (i=0; i<=4; i++) - tmp |= (current->signal.sig[i] & kset.sig[i]); + tmp |= (current->pending.signal.sig[i] & kset.sig[i]); if (tmp) break; @@ -622,7 +605,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) { if (sigismember (&kset, sig)) continue; - if (sigismember (¤t->signal, sig)) { + if (sigismember (¤t->pending.signal, sig)) { /* XXX need more than this... */ if (info) info->sig = sig; diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index a5a630769..6a1a6c326 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -72,6 +72,7 @@ void flush_thread(void) } int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, + unsigned long unused, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 5a9992141..ad66fcb6c 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -662,7 +662,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 2afb00e0a..a7887b6d0 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -97,7 +97,7 @@ asmlinkage int sys_fork(struct pt_regs regs) int res; save_static(®s); - res = do_fork(SIGCHLD, regs.regs[29], ®s); + res = do_fork(SIGCHLD, regs.regs[29], ®s, 0); return res; } @@ -112,7 +112,7 @@ asmlinkage int sys_clone(struct pt_regs regs) newsp = regs.regs[5]; if (!newsp) newsp = regs.regs[29]; - res = do_fork(clone_flags, newsp, ®s); + res = do_fork(clone_flags, newsp, ®s, 0); return res; } diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 3551fd683..62739e4a6 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -445,37 +445,6 @@ void indy_r4k_timer_interrupt (struct pt_regs *regs) r4k_timer_interrupt (INDY_R4K_TIMER_IRQ, NULL, regs); } -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - char cyclecounter_available; static inline void init_cycle_counter(void) diff --git a/arch/mips/orion/initrd.c b/arch/mips/orion/initrd.c new file mode 100644 index 000000000..06e05d71f --- /dev/null +++ b/arch/mips/orion/initrd.c @@ -0,0 +1,9 @@ +/* +* Miscellaneous data structures: +* WARNING - this file is automatically generated! +*/ + +unsigned long orion_initrd_start[] = { + 0x1F8B0800,0x7109D539,0x02030300,0x00000000, /* 0 */ + 0x00000000,0 }; +unsigned long orion_initrd_size = 0x14; diff --git a/arch/mips64/config.in b/arch/mips64/config.in index 7bfc0b3a3..129c24913 100644 --- a/arch/mips64/config.in +++ b/arch/mips64/config.in @@ -21,7 +21,7 @@ if [ "$CONFIG_SGI_IP27" = "y" ]; then bool ' Mapped kernel support' CONFIG_MAPPED_KERNEL bool ' Kernel text replication support' CONFIG_REPLICATE_KTEXT bool ' Exception handler replication support' CONFIG_REPLICATE_EXHANDLERS - bool ' Multi-Processing support (Experimental)' CONFIG_SMP + bool ' Multi-Processing support' CONFIG_SMP #bool ' IP27 XXL' CONFIG_SGI_SN0_XXL fi endmenu @@ -129,6 +129,8 @@ source drivers/mtd/Config.in source drivers/block/Config.in +source drivers/md/Config.in + if [ "$CONFIG_NET" = "y" ]; then source net/Config.in fi diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig index 9817d35f3..51d2d3c06 100644 --- a/arch/mips64/defconfig +++ b/arch/mips64/defconfig @@ -18,7 +18,7 @@ CONFIG_DISCONTIGMEM=y # CONFIG_MAPPED_KERNEL is not set # CONFIG_REPLICATE_KTEXT is not set # CONFIG_REPLICATE_EXHANDLERS is not set -# CONFIG_SMP is not set +CONFIG_SMP=y CONFIG_BOOT_ELF64=y CONFIG_ARC64=y CONFIG_COHERENT_IO=y @@ -30,7 +30,6 @@ CONFIG_QL_ISP_A64=y # # CPU selection # -# CONFIG_CPU_GENERIC is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_R5000 is not set @@ -73,17 +72,24 @@ CONFIG_PCI_NAMES=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -162,6 +168,7 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -175,8 +182,6 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_PPA is not set # CONFIG_SCSI_IMM is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set # CONFIG_SCSI_SYM53C8XX is not set @@ -188,6 +193,8 @@ CONFIG_SCSI_LOGGING=y CONFIG_SCSI_QLOGIC_ISP=y # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set @@ -235,6 +242,7 @@ CONFIG_SGI_IOC3_ETH=y # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_PLIP is not set diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22 index 64471af14..1e1e020eb 100644 --- a/arch/mips64/defconfig-ip22 +++ b/arch/mips64/defconfig-ip22 @@ -62,17 +62,24 @@ CONFIG_BINFMT_ELF=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -152,6 +159,7 @@ CONFIG_NETDEVICES=y # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_PLIP is not set diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27 index 9817d35f3..51d2d3c06 100644 --- a/arch/mips64/defconfig-ip27 +++ b/arch/mips64/defconfig-ip27 @@ -18,7 +18,7 @@ CONFIG_DISCONTIGMEM=y # CONFIG_MAPPED_KERNEL is not set # CONFIG_REPLICATE_KTEXT is not set # CONFIG_REPLICATE_EXHANDLERS is not set -# CONFIG_SMP is not set +CONFIG_SMP=y CONFIG_BOOT_ELF64=y CONFIG_ARC64=y CONFIG_COHERENT_IO=y @@ -30,7 +30,6 @@ CONFIG_QL_ISP_A64=y # # CPU selection # -# CONFIG_CPU_GENERIC is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_R5000 is not set @@ -73,17 +72,24 @@ CONFIG_PCI_NAMES=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -162,6 +168,7 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -175,8 +182,6 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_PPA is not set # CONFIG_SCSI_IMM is not set # CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set # CONFIG_SCSI_SYM53C8XX is not set @@ -188,6 +193,8 @@ CONFIG_SCSI_LOGGING=y CONFIG_SCSI_QLOGIC_ISP=y # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set @@ -235,6 +242,7 @@ CONFIG_SGI_IOC3_ETH=y # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set # CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_PLIP is not set diff --git a/arch/mips64/kernel/ioctl32.c b/arch/mips64/kernel/ioctl32.c index f177ea94d..a284357a1 100644 --- a/arch/mips64/kernel/ioctl32.c +++ b/arch/mips64/kernel/ioctl32.c @@ -24,6 +24,7 @@ #include <linux/blkdev.h> #include <linux/elevator.h> #include <linux/auto_fs.h> +#include <linux/ext2_fs.h> #include <asm/types.h> #include <asm/uaccess.h> diff --git a/arch/mips64/kernel/process.c b/arch/mips64/kernel/process.c index 924140719..df03ef081 100644 --- a/arch/mips64/kernel/process.c +++ b/arch/mips64/kernel/process.c @@ -69,6 +69,7 @@ void flush_thread(void) } int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, + unsigned long unused, struct task_struct * p, struct pt_regs * regs) { struct pt_regs * childregs; diff --git a/arch/mips64/kernel/signal.c b/arch/mips64/kernel/signal.c index 81daadab8..15b2fc60b 100644 --- a/arch/mips64/kernel/signal.c +++ b/arch/mips64/kernel/signal.c @@ -695,7 +695,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/mips64/kernel/signal32.c b/arch/mips64/kernel/signal32.c index 1988b681c..b3de6d4c9 100644 --- a/arch/mips64/kernel/signal32.c +++ b/arch/mips64/kernel/signal32.c @@ -773,7 +773,7 @@ printk("%s: delivering signal.\n", current->comm); /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); @@ -879,12 +879,12 @@ asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act, if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact))) return -EFAULT; - err |= __put_user((u32)(u64)new_sa.sa.sa_handler, + err |= __put_user((u32)(u64)old_sa.sa.sa_handler, &oact->sa_handler); - err |= __put_user(new_sa.sa.sa_flags, &oact->sa_flags); - err |= __put_user((u32)(u64)new_sa.sa.sa_restorer, + err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags); + err |= __put_user((u32)(u64)old_sa.sa.sa_restorer, &oact->sa_restorer); - err |= put_sigset(&new_sa.sa.sa_mask, &oact->sa_mask); + err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask); if (err) return -EFAULT; } diff --git a/arch/mips64/kernel/syscall.c b/arch/mips64/kernel/syscall.c index daea69e6c..a69558792 100644 --- a/arch/mips64/kernel/syscall.c +++ b/arch/mips64/kernel/syscall.c @@ -77,7 +77,7 @@ asmlinkage int sys_fork(abi64_no_regargs, struct pt_regs regs) int res; save_static(®s); - res = do_fork(SIGCHLD, regs.regs[29], ®s); + res = do_fork(SIGCHLD, regs.regs[29], ®s, 0); return res; } @@ -92,7 +92,7 @@ asmlinkage int sys_clone(abi64_no_regargs, struct pt_regs regs) newsp = regs.regs[5]; if (!newsp) newsp = regs.regs[29]; - res = do_fork(clone_flags, newsp, ®s); + res = do_fork(clone_flags, newsp, ®s, 0); return res; } diff --git a/arch/mips64/sgi-ip22/ip22-timer.c b/arch/mips64/sgi-ip22/ip22-timer.c index 5b8ea05f7..76ed0c214 100644 --- a/arch/mips64/sgi-ip22/ip22-timer.c +++ b/arch/mips64/sgi-ip22/ip22-timer.c @@ -151,37 +151,6 @@ static unsigned long dosample(volatile unsigned char *tcwp, return ct1 - ct0; } -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - static unsigned long __init get_indy_time(void) { struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; diff --git a/arch/mips64/sgi-ip27/ip27-memory.c b/arch/mips64/sgi-ip27/ip27-memory.c index fd47e0103..f858d098f 100644 --- a/arch/mips64/sgi-ip27/ip27-memory.c +++ b/arch/mips64/sgi-ip27/ip27-memory.c @@ -242,7 +242,7 @@ void __init paging_init(void) pfn_t end_pfn = node_getmaxclick(node); zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn; - free_area_init_node(node, NODE_DATA(node), zones_size, + free_area_init_node(node, NODE_DATA(node), 0, zones_size, start_pfn << PAGE_SHIFT, 0); if ((PLAT_NODE_DATA_STARTNR(node) + PLAT_NODE_DATA_SIZE(node)) > pagenr) diff --git a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c index 7b4b8ef78..8cbb943c8 100644 --- a/arch/mips64/sgi-ip27/ip27-timer.c +++ b/arch/mips64/sgi-ip27/ip27-timer.c @@ -205,38 +205,6 @@ void do_settimeofday(struct timeval *tv) #include <asm/sn/sn0/hubio.h> #include <asm/pci/bridge.h> -/* - * Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - static __init unsigned long get_m48t35_time(void) { unsigned int year, month, date, hour, min, sec; diff --git a/arch/ppc/8260_io/Config.in b/arch/ppc/8260_io/Config.in index 8cdd8c615..4db16a068 100644 --- a/arch/ppc/8260_io/Config.in +++ b/arch/ppc/8260_io/Config.in @@ -11,12 +11,15 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then bool 'Ethernet on SCC2' CONFIG_SCC2_ENET fi fi - bool 'FCC Ethernet' CONFIG_FCC_ENET - if [ "$CONFIG_FCC_ENET" = "y" ]; then - bool 'Ethernet on FCC1' CONFIG_FCC1_ENET - if [ "$CONFIG_FCC1_ENET" != "y" ]; then - bool 'Ethernet on FCC2' CONFIG_FCC2_ENET - fi +# +# CONFIG_FEC_ENET is only used to get netdevices to call our init +# function. Any combination of FCC1,2,3 are supported. +# + bool 'FCC Ethernet' CONFIG_FEC_ENET + if [ "$CONFIG_FEC_ENET" = "y" ]; then + bool 'Ethernet on FCC1' CONFIG_FCC1_ENET + bool 'Ethernet on FCC2' CONFIG_FCC2_ENET + bool 'Ethernet on FCC3' CONFIG_FCC3_ENET fi endmenu fi diff --git a/arch/ppc/8260_io/Makefile b/arch/ppc/8260_io/Makefile index 240a85628..8de47b144 100644 --- a/arch/ppc/8260_io/Makefile +++ b/arch/ppc/8260_io/Makefile @@ -10,8 +10,8 @@ O_TARGET := 8260_io.a O_OBJS = commproc.o uart.o -ifdef CONFIG_FCC_ENET -O_OBJS += fcc.o +ifdef CONFIG_FEC_ENET +O_OBJS += fcc_enet.o endif ifdef CONFIG_SCC_ENET O_OBJS += enet.o diff --git a/arch/ppc/8260_io/commproc.c b/arch/ppc/8260_io/commproc.c index 8642fa420..b7c13b167 100644 --- a/arch/ppc/8260_io/commproc.c +++ b/arch/ppc/8260_io/commproc.c @@ -69,17 +69,27 @@ m8260_cpm_reset(void) cpmp = (cpm8260_t *)commproc; } -/* Allocate some memory from the dual ported ram. We may want to - * enforce alignment restrictions, but right now everyone is a good - * citizen. +/* Allocate some memory from the dual ported ram. + * To help protocols with object alignment restrictions, we do that + * if they ask. */ uint -m8260_cpm_dpalloc(uint size) +m8260_cpm_dpalloc(uint size, uint align) { uint retloc; + uint align_mask, off; + uint savebase; - if ((dp_alloc_base + size) >= dp_alloc_top) + align_mask = align - 1; + savebase = dp_alloc_base; + + if ((off = (dp_alloc_base & align_mask)) != 0) + dp_alloc_base += (align - off); + + if ((dp_alloc_base + size) >= dp_alloc_top) { + dp_alloc_base = savebase; return(CPM_DP_NOSPACE); + } retloc = dp_alloc_base; dp_alloc_base += size; @@ -91,12 +101,22 @@ m8260_cpm_dpalloc(uint size) * UART "fifos" and the like. */ uint -m8260_cpm_hostalloc(uint size) +m8260_cpm_hostalloc(uint size, uint align) { uint retloc; + uint align_mask, off; + uint savebase; - if ((host_buffer + size) >= host_end) + align_mask = align - 1; + savebase = host_buffer; + + if ((off = (host_buffer & align_mask)) != 0) + host_buffer += (align - off); + + if ((host_buffer + size) >= host_end) { + host_buffer = savebase; return(0); + } retloc = host_buffer; host_buffer += size; diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c index 4c8c672fd..e1ff3c092 100644 --- a/arch/ppc/8260_io/enet.c +++ b/arch/ppc/8260_io/enet.c @@ -466,8 +466,11 @@ for (;;) { cep->stats.rx_bytes += pkt_len; /* This does 16 byte alignment, much more than we need. - */ - skb = dev_alloc_skb(pkt_len); + * The packet length includes FCS, but we don't want to + * include that when passing upstream as it messes up + * bridging applications. + */ + skb = dev_alloc_skb(pkt_len-4); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); @@ -475,10 +478,10 @@ for (;;) { } else { skb->dev = dev; - skb_put(skb,pkt_len); /* Make room */ + skb_put(skb,pkt_len-4); /* Make room */ eth_copy_and_sum(skb, (unsigned char *)__va(bdp->cbd_bufaddr), - pkt_len, 0); + pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } @@ -549,10 +552,10 @@ static void set_multicast_list(struct net_device *dev) /* Log any net taps. */ printk("%s: Promiscuous mode enabled.\n", dev->name); - cep->sccp->scc_pmsr |= SCC_PMSR_PRO; + cep->sccp->scc_pmsr |= SCC_PSMR_PRO; } else { - cep->sccp->scc_pmsr &= ~SCC_PMSR_PRO; + cep->sccp->scc_pmsr &= ~SCC_PSMR_PRO; if (dev->flags & IFF_ALLMULTI) { /* Catch all multicast addresses, so set the @@ -678,11 +681,11 @@ int __init scc_enet_init(void) * These are relative offsets in the DP ram address space. * Initialize base addresses for the buffer descriptors. */ - i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE); + i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); ep->sen_genscc.scc_rbase = i; cep->rx_bd_base = (cbd_t *)&immap->im_dprambase[i]; - i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE); + i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); ep->sen_genscc.scc_tbase = i; cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i]; @@ -816,7 +819,7 @@ int __init scc_enet_init(void) /* Set processing mode. Use Ethernet CRC, catch broadcast, and * start frame search 22 bit times after RENA. */ - sccp->scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22); + sccp->scc_pmsr = (SCC_PSMR_ENCRC | SCC_PSMR_NIB22); /* It is now OK to enable the Ethernet transmitter. * Unfortunately, there are board implementation differences here. diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c new file mode 100644 index 000000000..da3991ae3 --- /dev/null +++ b/arch/ppc/8260_io/fcc_enet.c @@ -0,0 +1,1601 @@ +/* + * Fast Ethernet Controller (FCC) driver for Motorola MPC8260. + * Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net) + * + * This version of the driver is a combination of the 8xx fec and + * 8260 SCC Ethernet drivers. People seem to be choosing common I/O + * configurations, so this driver will work on the EST8260 boards and + * others yet to be announced. + * + * Right now, I am very watseful with the buffers. I allocate memory + * pages and then divide them into 2K frame buffers. This way I know I + * have buffers large enough to hold one frame within one buffer descriptor. + * Once I get this working, I will use 64 or 128 byte CPM buffers, which + * will be much more memory efficient and will easily handle lots of + * small packets. + * + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/ptrace.h> +#include <linux/errno.h> +#include <linux/ioport.h> +#include <linux/malloc.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#include <linux/spinlock.h> + +#include <asm/immap_8260.h> +#include <asm/pgtable.h> +#include <asm/mpc8260.h> +#include <asm/irq.h> +#include <asm/bitops.h> +#include <asm/uaccess.h> +#include <asm/cpm_8260.h> + +/* The transmitter timeout + */ +#define TX_TIMEOUT (2*HZ) + +/* The number of Tx and Rx buffers. These are allocated from the page + * pool. The code may assume these are power of two, so it it best + * to keep them that size. + * We don't need to allocate pages for the transmitter. We just use + * the skbuffer directly. + */ +#define FCC_ENET_RX_PAGES 16 +#define FCC_ENET_RX_FRSIZE 2048 +#define FCC_ENET_RX_FRPPG (PAGE_SIZE / FCC_ENET_RX_FRSIZE) +#define RX_RING_SIZE (FCC_ENET_RX_FRPPG * FCC_ENET_RX_PAGES) +#define TX_RING_SIZE 16 /* Must be power of two */ +#define TX_RING_MOD_MASK 15 /* for this to work */ + +/* The FCC stores dest/src/type, data, and checksum for receive packets. + */ +#define PKT_MAXBUF_SIZE 1518 +#define PKT_MINBUF_SIZE 64 + +/* Maximum input DMA size. Must be a should(?) be a multiple of 4. +*/ +#define PKT_MAXDMA_SIZE 1520 + +/* Maximum input buffer size. Must be a multiple of 32. +*/ +#define PKT_MAXBLR_SIZE 1536 + +static int fcc_enet_open(struct net_device *dev); +static int fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int fcc_enet_rx(struct net_device *dev); +static void fcc_enet_mii(struct net_device *dev); +static void fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs); +static int fcc_enet_close(struct net_device *dev); +static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); +static void restart_fcc(struct net_device *dev); + +/* These will be configurable for the FCC choice. + * Multiple ports can be configured. There is little choice among the + * I/O pins to the PHY, except the clocks. We will need some board + * dependent clock selection. + * Why in the hell did I put these inside #ifdef's? I dunno, maybe to + * help show what pins are used for each device. + */ + +/* I/O Pin assignment for FCC1. I don't yet know the best way to do this, + * but there is little variation among the choices. + */ +#define PA1_COL ((uint)0x00000001) +#define PA1_CRS ((uint)0x00000002) +#define PA1_TXER ((uint)0x00000004) +#define PA1_TXEN ((uint)0x00000008) +#define PA1_RXDV ((uint)0x00000010) +#define PA1_RXER ((uint)0x00000020) +#define PA1_TXDAT ((uint)0x00003c00) +#define PA1_RXDAT ((uint)0x0003c000) +#define PA1_PSORA0 (PA1_RXDAT | PA1_TXDAT) +#define PA1_PSORA1 (PA1_COL | PA1_CRS | PA1_TXER | PA1_TXEN | \ + PA1_RXDV | PA1_RXER) +#define PA1_DIRA0 (PA1_RXDAT | PA1_CRS | PA1_COL | PA1_RXER | PA1_RXDV) +#define PA1_DIRA1 (PA1_TXDAT | PA1_TXEN | PA1_TXER) + +/* CLK12 is receive, CLK11 is transmit. These are board specific. +*/ +#define PC_F1RXCLK ((uint)0x00000800) +#define PC_F1TXCLK ((uint)0x00000400) +#define CMX1_CLK_ROUTE ((uint)0x3e000000) +#define CMX1_CLK_MASK ((uint)0xff000000) + +/* I/O Pin assignment for FCC2. I don't yet know the best way to do this, + * but there is little variation among the choices. + */ +#define PB2_TXER ((uint)0x00000001) +#define PB2_RXDV ((uint)0x00000002) +#define PB2_TXEN ((uint)0x00000004) +#define PB2_RXER ((uint)0x00000008) +#define PB2_COL ((uint)0x00000010) +#define PB2_CRS ((uint)0x00000020) +#define PB2_TXDAT ((uint)0x000003c0) +#define PB2_RXDAT ((uint)0x00003c00) +#define PB2_PSORB0 (PB2_RXDAT | PB2_TXDAT | PB2_CRS | PB2_COL | \ + PB2_RXER | PB2_RXDV | PB2_TXER) +#define PB2_PSORB1 (PB2_TXEN) +#define PB2_DIRB0 (PB2_RXDAT | PB2_CRS | PB2_COL | PB2_RXER | PB2_RXDV) +#define PB2_DIRB1 (PB2_TXDAT | PB2_TXEN | PB2_TXER) + +/* CLK13 is receive, CLK14 is transmit. These are board dependent. +*/ +#define PC_F2RXCLK ((uint)0x00001000) +#define PC_F2TXCLK ((uint)0x00002000) +#define CMX2_CLK_ROUTE ((uint)0x00250000) +#define CMX2_CLK_MASK ((uint)0x00ff0000) + +/* I/O Pin assignment for FCC3. I don't yet know the best way to do this, + * but there is little variation among the choices. + */ +#define PB3_RXDV ((uint)0x00004000) +#define PB3_RXER ((uint)0x00008000) +#define PB3_TXER ((uint)0x00010000) +#define PB3_TXEN ((uint)0x00020000) +#define PB3_COL ((uint)0x00040000) +#define PB3_CRS ((uint)0x00080000) +#define PB3_TXDAT ((uint)0x0f000000) +#define PB3_RXDAT ((uint)0x00f00000) +#define PB3_PSORB0 (PB3_RXDAT | PB3_TXDAT | PB3_CRS | PB3_COL | \ + PB3_RXER | PB3_RXDV | PB3_TXER | PB3_TXEN) +#define PB3_PSORB1 (0) +#define PB3_DIRB0 (PB3_RXDAT | PB3_CRS | PB3_COL | PB3_RXER | PB3_RXDV) +#define PB3_DIRB1 (PB3_TXDAT | PB3_TXEN | PB3_TXER) + +/* CLK15 is receive, CLK16 is transmit. These are board dependent. +*/ +#define PC_F3RXCLK ((uint)0x00004000) +#define PC_F3TXCLK ((uint)0x00008000) +#define CMX3_CLK_ROUTE ((uint)0x00003700) +#define CMX3_CLK_MASK ((uint)0x0000ff00) + +/* MII status/control serial interface. +*/ +#define PC_MDIO ((uint)0x00400000) +#define PC_MDCK ((uint)0x00200000) + +/* A table of information for supporting FCCs. This does two things. + * First, we know how many FCCs we have and they are always externally + * numbered from zero. Second, it holds control register and I/O + * information that could be different among board designs. + */ +typedef struct fcc_info { + uint fc_fccnum; + uint fc_cpmblock; + uint fc_cpmpage; + uint fc_proff; + uint fc_interrupt; + uint fc_trxclocks; + uint fc_clockroute; + uint fc_clockmask; + uint fc_mdio; + uint fc_mdck; +} fcc_info_t; + +static fcc_info_t fcc_ports[] = { +#ifdef CONFIG_FCC1_ENET + { 0, CPM_CR_FCC1_SBLOCK, CPM_CR_FCC1_PAGE, PROFF_FCC1, SIU_INT_FCC1, + (PC_F1RXCLK | PC_F1TXCLK), CMX1_CLK_ROUTE, CMX1_CLK_MASK, + PC_MDIO, PC_MDCK }, +#endif +#ifdef CONFIG_FCC2_ENET + { 1, CPM_CR_FCC2_SBLOCK, CPM_CR_FCC2_PAGE, PROFF_FCC2, SIU_INT_FCC2, + (PC_F2RXCLK | PC_F2TXCLK), CMX2_CLK_ROUTE, CMX2_CLK_MASK, + PC_MDIO, PC_MDCK }, +#endif +#ifdef CONFIG_FCC3_ENET + { 2, CPM_CR_FCC3_SBLOCK, CPM_CR_FCC3_PAGE, PROFF_FCC3, SIU_INT_FCC3, + (PC_F3RXCLK | PC_F3TXCLK), CMX3_CLK_ROUTE, CMX3_CLK_MASK, + PC_MDIO, PC_MDCK }, +#endif +}; + +/* The FCC buffer descriptors track the ring buffers. The rx_bd_base and + * tx_bd_base always point to the base of the buffer descriptors. The + * cur_rx and cur_tx point to the currently available buffer. + * The dirty_tx tracks the current buffer that is being sent by the + * controller. The cur_tx and dirty_tx are equal under both completely + * empty and completely full conditions. The empty/ready indicator in + * the buffer descriptor determines the actual condition. + */ +struct fcc_enet_private { + /* The saved address of a sent-in-place packet/buffer, for skfree(). */ + struct sk_buff* tx_skbuff[TX_RING_SIZE]; + ushort skb_cur; + ushort skb_dirty; + + /* CPM dual port RAM relative addresses. + */ + cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ + cbd_t *tx_bd_base; + cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ + cbd_t *dirty_tx; /* The ring entries to be free()ed. */ + volatile fcc_t *fccp; + volatile fcc_enet_t *ep; + struct net_device_stats stats; + uint tx_full; + spinlock_t lock; + uint phy_address; + uint phy_type; + uint phy_duplex; + fcc_info_t *fip; +}; + +static void init_fcc_shutdown(fcc_info_t *fip, struct fcc_enet_private *cep, + volatile immap_t *immap); +static void init_fcc_startup(fcc_info_t *fip, struct net_device *dev); +static void init_fcc_ioports(fcc_info_t *fip, volatile iop8260_t *io, + volatile immap_t *immap); +static void init_fcc_param(fcc_info_t *fip, struct net_device *dev, + volatile immap_t *immap); + +/* MII processing. We keep this as simple as possible. Requests are + * placed on the list (if there is room). When the request is finished + * by the MII, an optional function may be called. + */ +typedef struct mii_list { + uint mii_regval; + void (*mii_func)(uint val, struct net_device *dev); + struct mii_list *mii_next; +} mii_list_t; + +#define NMII 20 +mii_list_t mii_cmds[NMII]; +mii_list_t *mii_free; +mii_list_t *mii_head; +mii_list_t *mii_tail; + +static int phyaddr; +static uint phytype; + +static int mii_queue(int request, void (*func)(uint, struct net_device *)); +static void mii_startup_cmds(void); +static uint mii_send_receive(fcc_info_t *fip, uint cmd); + +/* Make MII read/write commands for the FCC. +*/ + +#define mk_mii_phyaddr(ADDR) (0x60020000 | ((ADDR) << 23) | (2 << 18)) + +#define mk_mii_read(REG) (0x60020000 | ((phyaddr << 23) | \ + (REG & 0x1f) << 18)) + +#define mk_mii_write(REG, VAL) (0x50020000 | ((phyaddr << 23) | \ + (REG & 0x1f) << 18) | \ + (VAL & 0xffff)) + + +static int +fcc_enet_open(struct net_device *dev) +{ + netif_start_queue(dev); + return 0; /* Always succeed */ +} + +static int +fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv; + volatile cbd_t *bdp; + + + /* Fill in a Tx ring entry */ + bdp = cep->cur_tx; + +#ifndef final_version + if (bdp->cbd_sc & BD_ENET_TX_READY) { + /* Ooops. All transmit buffers are full. Bail out. + * This should not happen, since cep->tx_full should be set. + */ + printk("%s: tx queue full!.\n", dev->name); + return 1; + } +#endif + + /* Clear all of the status flags. + */ + bdp->cbd_sc &= ~BD_ENET_TX_STATS; + + /* If the frame is short, tell CPM to pad it. + */ + if (skb->len <= ETH_ZLEN) + bdp->cbd_sc |= BD_ENET_TX_PAD; + else + bdp->cbd_sc &= ~BD_ENET_TX_PAD; + + /* Set buffer length and buffer pointer. + */ + bdp->cbd_datlen = skb->len; + bdp->cbd_bufaddr = __pa(skb->data); + + /* Save skb pointer. + */ + cep->tx_skbuff[cep->skb_cur] = skb; + + cep->stats.tx_bytes += skb->len; + cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK; + + spin_lock_irq(&cep->lock); + + /* Send it on its way. Tell CPM its ready, interrupt when done, + * its the last BD of the frame, and to put the CRC on the end. + */ + bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC); + +#if 0 + /* Errata says don't do this. + */ + cep->fccp->fcc_ftodr = 0x8000; +#endif + dev->trans_start = jiffies; + + /* If this was the last BD in the ring, start at the beginning again. + */ + if (bdp->cbd_sc & BD_ENET_TX_WRAP) + bdp = cep->tx_bd_base; + else + bdp++; + + if (bdp->cbd_sc & BD_ENET_TX_READY) { + netif_stop_queue(dev); + cep->tx_full = 1; + } + + cep->cur_tx = (cbd_t *)bdp; + + spin_unlock_irq(&cep->lock); + + return 0; +} + + +static void +fcc_enet_timeout(struct net_device *dev) +{ + struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv; + + printk("%s: transmit timed out.\n", dev->name); + cep->stats.tx_errors++; +#ifndef final_version + { + int i; + cbd_t *bdp; + printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n", + cep->cur_tx, cep->tx_full ? " (full)" : "", + cep->cur_rx); + bdp = cep->tx_bd_base; + printk(" Tx @base %p :\n", bdp); + for (i = 0 ; i < TX_RING_SIZE; i++, bdp++) + printk("%04x %04x %08x\n", + bdp->cbd_sc, + bdp->cbd_datlen, + bdp->cbd_bufaddr); + bdp = cep->rx_bd_base; + printk(" Rx @base %p :\n", bdp); + for (i = 0 ; i < RX_RING_SIZE; i++, bdp++) + printk("%04x %04x %08x\n", + bdp->cbd_sc, + bdp->cbd_datlen, + bdp->cbd_bufaddr); + } +#endif + if (!cep->tx_full) + netif_wake_queue(dev); +} + +/* The interrupt handler. + */ +static void +fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) +{ + struct net_device *dev = dev_id; + volatile struct fcc_enet_private *cep; + volatile cbd_t *bdp; + ushort int_events; + int must_restart; + + cep = (struct fcc_enet_private *)dev->priv; + + /* Get the interrupt events that caused us to be here. + */ + int_events = cep->fccp->fcc_fcce; + cep->fccp->fcc_fcce = int_events; + must_restart = 0; + + /* Handle receive event in its own function. + */ + if (int_events & FCC_ENET_RXF) + fcc_enet_rx(dev_id); + + /* Check for a transmit error. The manual is a little unclear + * about this, so the debug code until I get it figured out. It + * appears that if TXE is set, then TXB is not set. However, + * if carrier sense is lost during frame transmission, the TXE + * bit is set, "and continues the buffer transmission normally." + * I don't know if "normally" implies TXB is set when the buffer + * descriptor is closed.....trial and error :-). + */ + + /* Transmit OK, or non-fatal error. Update the buffer descriptors. + */ + if (int_events & (FCC_ENET_TXE | FCC_ENET_TXB)) { + spin_lock(&cep->lock); + bdp = cep->dirty_tx; + while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) { + if ((bdp==cep->cur_tx) && (cep->tx_full == 0)) + break; + + if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ + cep->stats.tx_heartbeat_errors++; + if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */ + cep->stats.tx_window_errors++; + if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */ + cep->stats.tx_aborted_errors++; + if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */ + cep->stats.tx_fifo_errors++; + if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */ + cep->stats.tx_carrier_errors++; + + + /* No heartbeat or Lost carrier are not really bad errors. + * The others require a restart transmit command. + */ + if (bdp->cbd_sc & + (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) { + must_restart = 1; + cep->stats.tx_errors++; + } + + cep->stats.tx_packets++; + + /* Deferred means some collisions occurred during transmit, + * but we eventually sent the packet OK. + */ + if (bdp->cbd_sc & BD_ENET_TX_DEF) + cep->stats.collisions++; + + /* Free the sk buffer associated with this last transmit. + */ + dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]); + cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK; + + /* Update pointer to next buffer descriptor to be transmitted. + */ + if (bdp->cbd_sc & BD_ENET_TX_WRAP) + bdp = cep->tx_bd_base; + else + bdp++; + + /* I don't know if we can be held off from processing these + * interrupts for more than one frame time. I really hope + * not. In such a case, we would now want to check the + * currently available BD (cur_tx) and determine if any + * buffers between the dirty_tx and cur_tx have also been + * sent. We would want to process anything in between that + * does not have BD_ENET_TX_READY set. + */ + + /* Since we have freed up a buffer, the ring is no longer + * full. + */ + if (cep->tx_full) { + cep->tx_full = 0; + if (netif_queue_stopped(dev)) { + netif_wake_queue(dev); + } + } + + cep->dirty_tx = (cbd_t *)bdp; + } + + if (must_restart) { + volatile cpm8260_t *cp; + + /* Some transmit errors cause the transmitter to shut + * down. We now issue a restart transmit. Since the + * errors close the BD and update the pointers, the restart + * _should_ pick up without having to reset any of our + * pointers either. + */ + + cp = cpmp; + cp->cp_cpcr = + mk_cr_cmd(cep->fip->fc_cpmpage, cep->fip->fc_cpmblock, + 0x0c, CPM_CR_RESTART_TX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + } + spin_unlock(&cep->lock); + } + + /* Check for receive busy, i.e. packets coming but no place to + * put them. + */ + if (int_events & FCC_ENET_BSY) { + cep->stats.rx_dropped++; + } + return; +} + +/* During a receive, the cur_rx points to the current incoming buffer. + * When we update through the ring, if the next incoming buffer has + * not been given to the system, we just set the empty indicator, + * effectively tossing the packet. + */ +static int +fcc_enet_rx(struct net_device *dev) +{ + struct fcc_enet_private *cep; + volatile cbd_t *bdp; + struct sk_buff *skb; + ushort pkt_len; + + cep = (struct fcc_enet_private *)dev->priv; + + /* First, grab all of the stats for the incoming packet. + * These get messed up if we get called due to a busy condition. + */ + bdp = cep->cur_rx; + +for (;;) { + if (bdp->cbd_sc & BD_ENET_RX_EMPTY) + break; + +#ifndef final_version + /* Since we have allocated space to hold a complete frame, both + * the first and last indicators should be set. + */ + if ((bdp->cbd_sc & (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) != + (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) + printk("CPM ENET: rcv is not first+last\n"); +#endif + + /* Frame too long or too short. + */ + if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) + cep->stats.rx_length_errors++; + if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ + cep->stats.rx_frame_errors++; + if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */ + cep->stats.rx_crc_errors++; + if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ + cep->stats.rx_crc_errors++; + + /* Report late collisions as a frame error. + * On this error, the BD is closed, but we don't know what we + * have in the buffer. So, just drop this frame on the floor. + */ + if (bdp->cbd_sc & BD_ENET_RX_CL) { + cep->stats.rx_frame_errors++; + } + else { + + /* Process the incoming frame. + */ + cep->stats.rx_packets++; + pkt_len = bdp->cbd_datlen; + cep->stats.rx_bytes += pkt_len; + + /* This does 16 byte alignment, much more than we need. + * The packet length includes FCS, but we don't want to + * include that when passing upstream as it messes up + * bridging applications. + */ + skb = dev_alloc_skb(pkt_len-4); + + if (skb == NULL) { + printk("%s: Memory squeeze, dropping packet.\n", dev->name); + cep->stats.rx_dropped++; + } + else { + skb->dev = dev; + skb_put(skb,pkt_len-4); /* Make room */ + eth_copy_and_sum(skb, + (unsigned char *)__va(bdp->cbd_bufaddr), + pkt_len-4, 0); + skb->protocol=eth_type_trans(skb,dev); + netif_rx(skb); + } + } + + /* Clear the status flags for this buffer. + */ + bdp->cbd_sc &= ~BD_ENET_RX_STATS; + + /* Mark the buffer empty. + */ + bdp->cbd_sc |= BD_ENET_RX_EMPTY; + + /* Update BD pointer to next entry. + */ + if (bdp->cbd_sc & BD_ENET_RX_WRAP) + bdp = cep->rx_bd_base; + else + bdp++; + + } + cep->cur_rx = (cbd_t *)bdp; + + return 0; +} + +static int +fcc_enet_close(struct net_device *dev) +{ + /* Don't know what to do yet. + */ + netif_stop_queue(dev); + + return 0; +} + +static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev) +{ + struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv; + + return &cep->stats; +} + +/* The MII is simulated from the 8xx FEC implementation. The FCC + * is not responsible for the MII control/status interface. + */ +static void +fcc_enet_mii(struct net_device *dev) +{ + struct fcc_enet_private *fep; + mii_list_t *mip; + uint mii_reg; + + fep = (struct fcc_enet_private *)dev->priv; +#if 0 + ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); + mii_reg = ep->fec_mii_data; +#endif + + if ((mip = mii_head) == NULL) { + printk("MII and no head!\n"); + return; + } + + if (mip->mii_func != NULL) + (*(mip->mii_func))(mii_reg, dev); + + mii_head = mip->mii_next; + mip->mii_next = mii_free; + mii_free = mip; + +#if 0 + if ((mip = mii_head) != NULL) + ep->fec_mii_data = mip->mii_regval; +#endif +} + +static int +mii_queue(int regval, void (*func)(uint, struct net_device *)) +{ + unsigned long flags; + mii_list_t *mip; + int retval; + + retval = 0; + + save_flags(flags); + cli(); + + if ((mip = mii_free) != NULL) { + mii_free = mip->mii_next; + mip->mii_regval = regval; + mip->mii_func = func; + mip->mii_next = NULL; + if (mii_head) { + mii_tail->mii_next = mip; + mii_tail = mip; + } + else { + mii_head = mii_tail = mip; +#if 0 + (&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval; +#endif + } + } + else { + retval = 1; + } + + restore_flags(flags); + + return(retval); +} + +static volatile uint full_duplex; + +static void +mii_status(uint mii_reg, struct net_device *dev) +{ + volatile uint prev_duplex; + + if (((mii_reg >> 18) & 0x1f) == 1) { + /* status register. + */ + printk("fec: "); + if (mii_reg & 0x0004) + printk("link up"); + else + printk("link down"); + + if (mii_reg & 0x0010) + printk(",remote fault"); + if (mii_reg & 0x0020) + printk(",auto complete"); + printk("\n"); + } + if (((mii_reg >> 18) & 0x1f) == 0x14) { + /* Extended chip status register. + */ + prev_duplex = full_duplex; + printk("fec: "); + if (mii_reg & 0x0800) + printk("100 Mbps"); + else + printk("10 Mbps"); + + if (mii_reg & 0x1000) { + printk(", Full-Duplex\n"); + full_duplex = 1; + } + else { + printk(", Half-Duplex\n"); + full_duplex = 0; + } +#if 0 + if (prev_duplex != full_duplex) + restart_fec(dev); +#endif + } + if (((mii_reg >> 18) & 0x1f) == 31) { + /* QS6612 PHY Control/Status. + * OK, now we have it all, so figure out what is going on. + */ + prev_duplex = full_duplex; + printk("fec: "); + + mii_reg = (mii_reg >> 2) & 7; + + if (mii_reg & 1) + printk("10 Mbps"); + else + printk("100 Mbps"); + + if (mii_reg > 4) { + printk(", Full-Duplex\n"); + full_duplex = 1; + } + else { + printk(", Half-Duplex\n"); + full_duplex = 0; + } + +#if 0 + if (prev_duplex != full_duplex) + restart_fec(dev); +#endif + } +} + +static uint phyno; + +static void +mii_discover_phy3(uint mii_reg, struct net_device *dev) +{ + phytype <<= 16; + phytype |= (mii_reg & 0xffff); + printk("fec: Phy @ 0x%x, type 0x%08x\n", phyno, phytype); + mii_startup_cmds(); +} + +static void +mii_discover_phy(uint mii_reg, struct net_device *dev) +{ + if (phyno < 32) { + if ((phytype = (mii_reg & 0xffff)) != 0xffff) { + phyaddr = phyno; + mii_queue(mk_mii_read(3), mii_discover_phy3); + } + else { + phyno++; + mii_queue(mk_mii_phyaddr(phyno), mii_discover_phy); + } + } + else { + printk("FEC: No PHY device found.\n"); + } +} + +static void +mii_discover_phy_poll(fcc_info_t *fip) +{ + uint rv; + int i; + + for (i=0; i<32; i++) { + rv = mii_send_receive(fip, mk_mii_phyaddr(i)); + if ((phytype = (rv & 0xffff)) != 0xffff) { + phyaddr = i; + rv = mii_send_receive(fip, mk_mii_read(3)); + phytype <<= 16; + phytype |= (rv & 0xffff); + printk("fec: Phy @ 0x%x, type 0x%08x\n", phyaddr, phytype); + } + } +} + +static void +mii_startup_cmds(void) +{ + +#if 1 + /* Level One PHY. + */ + + /* Read status registers to clear any pending interrupt. + */ + mii_queue(mk_mii_read(1), mii_status); + mii_queue(mk_mii_read(18), mii_status); + + /* Read extended chip status register. + */ + mii_queue(mk_mii_read(0x14), mii_status); + + /* Set default operation of 100-TX....for some reason + * some of these bits are set on power up, which is wrong. + */ + mii_queue(mk_mii_write(0x13, 0), NULL); + + /* Enable Link status change interrupts. + */ + mii_queue(mk_mii_write(0x11, 0x0002), NULL); + + /* Don't advertize Full duplex. + mii_queue(mk_mii_write(0x04, 0x0021), NULL); + */ +#endif + +} + +/* This supports the mii_link interrupt below. + * We should get called three times. Once for register 1, once for + * register 18, and once for register 20. + */ +static uint mii_saved_reg1; + +static void +mii_relink(uint mii_reg, struct net_device *dev) +{ + volatile uint prev_duplex; + unsigned long flags; + + if (((mii_reg >> 18) & 0x1f) == 1) { + /* Just save the status register and get out. + */ + mii_saved_reg1 = mii_reg; + return; + } + if (((mii_reg >> 18) & 0x1f) == 18) { + /* Not much here, but has to be read to clear the + * interrupt condition. + */ + if ((mii_reg & 0x8000) == 0) + printk("fec: re-link and no IRQ?\n"); + if ((mii_reg & 0x4000) == 0) + printk("fec: no PHY power?\n"); + } + if (((mii_reg >> 18) & 0x1f) == 20) { + /* Extended chip status register. + * OK, now we have it all, so figure out what is going on. + */ + prev_duplex = full_duplex; + printk("fec: "); + if (mii_saved_reg1 & 0x0004) + printk("link up"); + else + printk("link down"); + + if (mii_saved_reg1 & 0x0010) + printk(", remote fault"); + if (mii_saved_reg1 & 0x0020) + printk(", auto complete"); + + if (mii_reg & 0x0800) + printk(", 100 Mbps"); + else + printk(", 10 Mbps"); + + if (mii_reg & 0x1000) { + printk(", Full-Duplex\n"); + full_duplex = 1; + } + else { + printk(", Half-Duplex\n"); + full_duplex = 0; + } + if (prev_duplex != full_duplex) { + save_flags(flags); + cli(); +#if 0 + restart_fec(dev); +#endif + restore_flags(flags); + } + } + if (((mii_reg >> 18) & 0x1f) == 31) { + /* QS6612 PHY Control/Status. + * OK, now we have it all, so figure out what is going on. + */ + prev_duplex = full_duplex; + printk("fec: "); + if (mii_saved_reg1 & 0x0004) + printk("link up"); + else + printk("link down"); + + if (mii_saved_reg1 & 0x0010) + printk(", remote fault"); + if (mii_saved_reg1 & 0x0020) + printk(", auto complete"); + + mii_reg = (mii_reg >> 2) & 7; + + if (mii_reg & 1) + printk(", 10 Mbps"); + else + printk(", 100 Mbps"); + + if (mii_reg > 4) { + printk(", Full-Duplex\n"); + full_duplex = 1; + } + else { + printk(", Half-Duplex\n"); + full_duplex = 0; + } + +#if 0 + if (prev_duplex != full_duplex) { + save_flags(flags); + cli(); + restart_fec(dev); + restore_flags(flags); + } +#endif + } +} + +/* Set or clear the multicast filter for this adaptor. + * Skeleton taken from sunlance driver. + * The CPM Ethernet implementation allows Multicast as well as individual + * MAC address filtering. Some of the drivers check to make sure it is + * a group multicast address, and discard those that are not. I guess I + * will do the same for now, but just remove the test if you want + * individual filtering as well (do the upper net layers want or support + * this kind of feature?). + */ +static void +set_multicast_list(struct net_device *dev) +{ + struct fcc_enet_private *cep; + struct dev_mc_list *dmi; + u_char *mcptr, *tdptr; + volatile fcc_enet_t *ep; + int i, j; + + cep = (struct fcc_enet_private *)dev->priv; + +return; + /* Get pointer to FCC area in parameter RAM. + */ + ep = (fcc_enet_t *)dev->base_addr; + + if (dev->flags&IFF_PROMISC) { + + /* Log any net taps. */ + printk("%s: Promiscuous mode enabled.\n", dev->name); + cep->fccp->fcc_fpsmr |= FCC_PSMR_PRO; + } else { + + cep->fccp->fcc_fpsmr &= ~FCC_PSMR_PRO; + + if (dev->flags & IFF_ALLMULTI) { + /* Catch all multicast addresses, so set the + * filter to all 1's. + */ + ep->fen_gaddrh = 0xffffffff; + ep->fen_gaddrl = 0xffffffff; + } + else { + /* Clear filter and add the addresses in the list. + */ + ep->fen_gaddrh = 0; + ep->fen_gaddrl = 0; + + dmi = dev->mc_list; + + for (i=0; i<dev->mc_count; i++) { + + /* Only support group multicast for now. + */ + if (!(dmi->dmi_addr[0] & 1)) + continue; + + /* The address in dmi_addr is LSB first, + * and taddr is MSB first. We have to + * copy bytes MSB first from dmi_addr. + */ + mcptr = (u_char *)dmi->dmi_addr + 5; + tdptr = (u_char *)&ep->fen_taddrh; + for (j=0; j<6; j++) + *tdptr++ = *mcptr--; + + /* Ask CPM to run CRC and set bit in + * filter mask. + */ + cpmp->cp_cpcr = mk_cr_cmd(cep->fip->fc_cpmpage, + cep->fip->fc_cpmblock, 0x0c, + CPM_CR_SET_GADDR) | CPM_CR_FLG; + udelay(10); + while (cpmp->cp_cpcr & CPM_CR_FLG); + } + } + } +} + +/* Initialize the CPM Ethernet on FCC. + */ +int __init fec_enet_init(void) +{ + struct net_device *dev; + struct fcc_enet_private *cep; + fcc_info_t *fip; + int i, np; + volatile immap_t *immap; + volatile iop8260_t *io; + + immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ + io = &immap->im_ioport; + + np = sizeof(fcc_ports) / sizeof(fcc_info_t); + fip = fcc_ports; + + while (np-- > 0) { + + /* Allocate some private information. + */ + cep = (struct fcc_enet_private *) + kmalloc(sizeof(*cep), GFP_KERNEL); + __clear_user(cep,sizeof(*cep)); + spin_lock_init(&cep->lock); + cep->fip = fip; + + /* Create an Ethernet device instance. + */ + dev = init_etherdev(0, 0); + dev->priv = cep; + + init_fcc_shutdown(fip, cep, immap); + init_fcc_ioports(fip, io, immap); + init_fcc_param(fip, dev, immap); + + dev->base_addr = (unsigned long)(cep->ep); + + /* The CPM Ethernet specific entries in the device + * structure. + */ + dev->open = fcc_enet_open; + dev->hard_start_xmit = fcc_enet_start_xmit; + dev->tx_timeout = fcc_enet_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + dev->stop = fcc_enet_close; + dev->get_stats = fcc_enet_get_stats; + dev->set_multicast_list = set_multicast_list; + + init_fcc_startup(fip, dev); + + printk("%s: FCC ENET Version 0.2, ", dev->name); + for (i=0; i<5; i++) + printk("%02x:", dev->dev_addr[i]); + printk("%02x\n", dev->dev_addr[5]); + + /* This is just a hack for now that works only on the EST + * board, or anything else that has MDIO/CK configured. + * It is mainly to test the MII software clocking. + */ + mii_discover_phy_poll(fip); + + fip++; + } + + return 0; +} + +/* Make sure the device is shut down during initialization. +*/ +static void __init +init_fcc_shutdown(fcc_info_t *fip, struct fcc_enet_private *cep, + volatile immap_t *immap) +{ + volatile fcc_enet_t *ep; + volatile fcc_t *fccp; + + /* Get pointer to FCC area in parameter RAM. + */ + ep = (fcc_enet_t *)(&immap->im_dprambase[fip->fc_proff]); + + /* And another to the FCC register area. + */ + fccp = (volatile fcc_t *)(&immap->im_fcc[fip->fc_fccnum]); + cep->fccp = fccp; /* Keep the pointers handy */ + cep->ep = ep; + + /* Disable receive and transmit in case someone left it running. + */ + fccp->fcc_gfmr &= ~(FCC_GFMR_ENR | FCC_GFMR_ENT); +} + +/* Initialize the I/O pins for the FCC Ethernet. +*/ +static void __init +init_fcc_ioports(fcc_info_t *fip, volatile iop8260_t *io, + volatile immap_t *immap) +{ + + /* FCC1 pins are on port A/C. FCC2/3 are port B/C. + */ + if (fip->fc_proff == PROFF_FCC1) { + /* Configure port A and C pins for FCC1 Ethernet. + */ + io->iop_pdira &= ~PA1_DIRA0; + io->iop_pdira |= PA1_DIRA1; + io->iop_psora &= ~PA1_PSORA0; + io->iop_psora |= PA1_PSORA1; + io->iop_ppara |= (PA1_DIRA0 | PA1_DIRA1); + } + if (fip->fc_proff == PROFF_FCC2) { + /* Configure port B and C pins for FCC Ethernet. + */ + io->iop_pdirb &= ~PB2_DIRB0; + io->iop_pdirb |= PB2_DIRB1; + io->iop_psorb &= ~PB2_PSORB0; + io->iop_psorb |= PB2_PSORB1; + io->iop_pparb |= (PB2_DIRB0 | PB2_DIRB1); + } + if (fip->fc_proff == PROFF_FCC3) { + /* Configure port B and C pins for FCC Ethernet. + */ + io->iop_pdirb &= ~PB3_DIRB0; + io->iop_pdirb |= PB3_DIRB1; + io->iop_psorb &= ~PB3_PSORB0; + io->iop_psorb |= PB3_PSORB1; + io->iop_pparb |= (PB3_DIRB0 | PB3_DIRB1); + } + + /* Port C has clocks...... + */ + io->iop_psorc &= ~(fip->fc_trxclocks); + io->iop_pdirc &= ~(fip->fc_trxclocks); + io->iop_pparc |= fip->fc_trxclocks; + + /* ....and the MII serial clock/data. + */ + io->iop_pdatc |= (fip->fc_mdio | fip->fc_mdck); + io->iop_podrc |= fip->fc_mdio; + io->iop_pdirc |= (fip->fc_mdio | fip->fc_mdck); + io->iop_pparc &= ~(fip->fc_mdio | fip->fc_mdck); + + /* Configure Serial Interface clock routing. + * First, clear all FCC bits to zero, + * then set the ones we want. + */ + immap->im_cpmux.cmx_fcr &= ~(fip->fc_clockmask); + immap->im_cpmux.cmx_fcr |= fip->fc_clockroute; +} + +static void __init +init_fcc_param(fcc_info_t *fip, struct net_device *dev, + volatile immap_t *immap) +{ + unsigned char *eap; + unsigned long mem_addr; + bd_t *bd; + int i, j; + struct fcc_enet_private *cep; + volatile fcc_enet_t *ep; + volatile cbd_t *bdp; + volatile cpm8260_t *cp; + + cep = (struct fcc_enet_private *)(dev->priv); + ep = cep->ep; + cp = cpmp; + + bd = (bd_t *)__res; + + /* Zero the whole thing.....I must have missed some individually. + * It works when I do this. + */ + memset((char *)ep, 0, sizeof(fcc_enet_t)); + + /* Allocate space for the buffer descriptors in the DP ram. + * These are relative offsets in the DP ram address space. + * Initialize base addresses for the buffer descriptors. + */ +#if 0 + /* I really want to do this, but for some reason it doesn't + * work with the data cache enabled, so I allocate from the + * main memory instead. + */ + i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); + ep->fen_genfcc.fcc_rbase = (uint)&immap->im_dprambase[i]; + cep->rx_bd_base = (cbd_t *)&immap->im_dprambase[i]; + + i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); + ep->fen_genfcc.fcc_tbase = (uint)&immap->im_dprambase[i]; + cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i]; +#else + cep->rx_bd_base = (cbd_t *)m8260_cpm_hostalloc(sizeof(cbd_t) * RX_RING_SIZE, 8); + ep->fen_genfcc.fcc_rbase = __pa(cep->rx_bd_base); + cep->tx_bd_base = (cbd_t *)m8260_cpm_hostalloc(sizeof(cbd_t) * TX_RING_SIZE, 8); + ep->fen_genfcc.fcc_tbase = __pa(cep->tx_bd_base); +#endif + + cep->dirty_tx = cep->cur_tx = cep->tx_bd_base; + cep->cur_rx = cep->rx_bd_base; + + ep->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB) << 24; + ep->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB) << 24; + + /* Set maximum bytes per receive buffer. + * It must be a multiple of 32. + */ + ep->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE; + + /* Allocate space in the reserved FCC area of DPRAM for the + * internal buffers. No one uses this space (yet), so we + * can do this. Later, we will add resource management for + * this area. + */ + mem_addr = CPM_FCC_SPECIAL_BASE + (fip->fc_fccnum * 128); + ep->fen_genfcc.fcc_riptr = mem_addr; + ep->fen_genfcc.fcc_tiptr = mem_addr+32; + ep->fen_padptr = mem_addr+64; + memset((char *)(&(immap->im_dprambase[(mem_addr+64)])), 0x88, 32); + + ep->fen_genfcc.fcc_rbptr = 0; + ep->fen_genfcc.fcc_tbptr = 0; + ep->fen_genfcc.fcc_rcrc = 0; + ep->fen_genfcc.fcc_tcrc = 0; + ep->fen_genfcc.fcc_res1 = 0; + ep->fen_genfcc.fcc_res2 = 0; + + ep->fen_camptr = 0; /* CAM isn't used in this driver */ + + /* Set CRC preset and mask. + */ + ep->fen_cmask = 0xdebb20e3; + ep->fen_cpres = 0xffffffff; + + ep->fen_crcec = 0; /* CRC Error counter */ + ep->fen_alec = 0; /* alignment error counter */ + ep->fen_disfc = 0; /* discard frame counter */ + ep->fen_retlim = 15; /* Retry limit threshold */ + ep->fen_pper = 0; /* Normal persistence */ + + /* Clear hash filter tables. + */ + ep->fen_gaddrh = 0; + ep->fen_gaddrl = 0; + ep->fen_iaddrh = 0; + ep->fen_iaddrl = 0; + + /* Clear the Out-of-sequence TxBD. + */ + ep->fen_tfcstat = 0; + ep->fen_tfclen = 0; + ep->fen_tfcptr = 0; + + ep->fen_mflr = PKT_MAXBUF_SIZE; /* maximum frame length register */ + ep->fen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register */ + + /* Set Ethernet station address. + * + * This is supplied in the board information structure, so we + * copy that into the controller. + * So, far we have only been given one Ethernet address. We make + * it unique by setting a few bits in the upper byte of the + * non-static part of the address. + */ + eap = (unsigned char *)&(ep->fen_paddrh); + for (i=5; i>=0; i--) { + if (i == 3) { + dev->dev_addr[i] = bd->bi_enetaddr[i]; + dev->dev_addr[i] |= (1 << (7 - fip->fc_fccnum)); + *eap++ = dev->dev_addr[i]; + } + else { + *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; + } + } + + ep->fen_taddrh = 0; + ep->fen_taddrm = 0; + ep->fen_taddrl = 0; + + ep->fen_maxd1 = PKT_MAXDMA_SIZE; /* maximum DMA1 length */ + ep->fen_maxd2 = PKT_MAXDMA_SIZE; /* maximum DMA2 length */ + + /* Clear stat counters, in case we ever enable RMON. + */ + ep->fen_octc = 0; + ep->fen_colc = 0; + ep->fen_broc = 0; + ep->fen_mulc = 0; + ep->fen_uspc = 0; + ep->fen_frgc = 0; + ep->fen_ospc = 0; + ep->fen_jbrc = 0; + ep->fen_p64c = 0; + ep->fen_p65c = 0; + ep->fen_p128c = 0; + ep->fen_p256c = 0; + ep->fen_p512c = 0; + ep->fen_p1024c = 0; + + ep->fen_rfthr = 0; /* Suggested by manual */ + ep->fen_rfcnt = 0; + ep->fen_cftype = 0; + + /* Now allocate the host memory pages and initialize the + * buffer descriptors. + */ + bdp = cep->tx_bd_base; + for (i=0; i<TX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. + */ + bdp->cbd_sc = 0; + bdp->cbd_datlen = 0; + bdp->cbd_bufaddr = 0; + bdp++; + } + + /* Set the last buffer to wrap. + */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + + bdp = cep->rx_bd_base; + for (i=0; i<FCC_ENET_RX_PAGES; i++) { + + /* Allocate a page. + */ + mem_addr = __get_free_page(GFP_KERNEL); + + /* Initialize the BD for every fragment in the page. + */ + for (j=0; j<FCC_ENET_RX_FRPPG; j++) { + bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR; + bdp->cbd_datlen = 0; + bdp->cbd_bufaddr = __pa(mem_addr); + mem_addr += FCC_ENET_RX_FRSIZE; + bdp++; + } + } + + /* Set the last buffer to wrap. + */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + + /* Let's re-initialize the channel now. We have to do it later + * than the manual describes because we have just now finished + * the BD initialization. + */ + cp->cp_cpcr = mk_cr_cmd(fip->fc_cpmpage, fip->fc_cpmblock, 0x0c, + CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + cep->skb_cur = cep->skb_dirty = 0; +} + +/* Let 'er rip. +*/ +static void __init +init_fcc_startup(fcc_info_t *fip, struct net_device *dev) +{ + volatile fcc_t *fccp; + struct fcc_enet_private *cep; + + cep = (struct fcc_enet_private *)(dev->priv); + fccp = cep->fccp; + + fccp->fcc_fcce = 0xffff; /* Clear any pending events */ + + /* Enable interrupts for transmit error, complete frame + * received, and any transmit buffer we have also set the + * interrupt flag. + */ + fccp->fcc_fccm = (FCC_ENET_TXE | FCC_ENET_RXF | FCC_ENET_TXB); + + /* Install our interrupt handler. + */ + if (request_8xxirq(fip->fc_interrupt, fcc_enet_interrupt, 0, + "fenet", dev) < 0) + printk("Can't get FCC IRQ %d\n", fip->fc_interrupt); + + /* Set GFMR to enable Ethernet operating mode. + */ + fccp->fcc_gfmr = (FCC_GFMR_TCI | FCC_GFMR_MODE_ENET); + + /* Set sync/delimiters. + */ + fccp->fcc_fdsr = 0xd555; + + /* Set protocol specific processing mode for Ethernet. + * This has to be adjusted for Full Duplex operation after we can + * determine how to detect that. + */ + fccp->fcc_fpsmr = FCC_PSMR_ENCRC; + + /* And last, enable the transmit and receive processing. + */ + fccp->fcc_gfmr |= (FCC_GFMR_ENR | FCC_GFMR_ENT); +} + +/* MII command/status interface. + * I'm not going to describe all of the details. You can find the + * protocol definition in many other places, including the data sheet + * of most PHY parts. + * I wonder what "they" were thinking (maybe weren't) when they leave + * the I2C in the CPM but I have to toggle these bits...... + */ +static uint +mii_send_receive(fcc_info_t *fip, uint cmd) +{ + unsigned long flags; + uint retval; + int read_op, i; + volatile immap_t *immap; + volatile iop8260_t *io; + + immap = (immap_t *)IMAP_ADDR; + io = &immap->im_ioport; + + /* When we get here, both clock and data are high, outputs. + * Output is open drain. + * Data transitions on high->low clock, is valid on low->high clock. + * Spec says edge transitions no closer than 160 nSec, minimum clock + * cycle 400 nSec. I could only manage about 500 nSec edges with + * an XOR loop, so I won't worry about delays yet. + * I disable interrupts during bit flipping to ensure atomic + * updates of the registers. I do lots of interrupt disable/enable + * to ensure we don't hang out too long with interrupts disabled. + */ + + /* First, crank out 32 1-bits as preamble. + * This is 64 transitions to clock the bits, with clock/data + * left high. + */ + save_flags(flags); + cli(); + for (i=0; i<64; i++) { + io->iop_pdatc ^= fip->fc_mdck; + udelay(0); + } + restore_flags(flags); + + read_op = ((cmd & 0xf0000000) == 0x60000000); + + /* We return the command word on a write op, or the command portion + * plus the new data on a read op. This is what the 8xx FEC does, + * and it allows the functions to simply look at the returned value + * and know the PHY/register as well. + */ + if (read_op) + retval = cmd; + else + retval = (cmd >> 16); + + /* Clock out the first 16 MS bits of the command. + */ + save_flags(flags); + cli(); + for (i=0; i<16; i++) { + io->iop_pdatc &= ~(fip->fc_mdck); + if (cmd & 0x80000000) + io->iop_pdatc |= fip->fc_mdio; + else + io->iop_pdatc &= ~(fip->fc_mdio); + cmd <<= 1; + io->iop_pdatc |= fip->fc_mdck; + udelay(0); + } + + /* Do the turn-around. If read op, we make the IO and input. + * If write op, do the 1/0 thing. + */ + io->iop_pdatc &= ~(fip->fc_mdck); + if (read_op) + io->iop_pdirc &= ~(fip->fc_mdio); + else + io->iop_pdatc |= fip->fc_mdio; + io->iop_pdatc |= fip->fc_mdck; + + /* I do this mainly to get just a little delay. + */ + restore_flags(flags); + save_flags(flags); + cli(); + io->iop_pdatc &= ~(fip->fc_mdck); + io->iop_pdirc &= ~(fip->fc_mdio); + io->iop_pdatc |= fip->fc_mdck; + + restore_flags(flags); + save_flags(flags); + cli(); + + /* For read, clock in 16 bits. For write, clock out + * rest of command. + */ + if (read_op) { + io->iop_pdatc &= ~(fip->fc_mdck); + udelay(0); + for (i=0; i<16; i++) { + io->iop_pdatc |= fip->fc_mdck; + udelay(0); + retval <<= 1; + if (io->iop_pdatc & fip->fc_mdio) + retval |= 1; + io->iop_pdatc &= ~(fip->fc_mdck); + udelay(0); + } + } + else { + for (i=0; i<16; i++) { + io->iop_pdatc &= ~(fip->fc_mdck); + if (cmd & 0x80000000) + io->iop_pdatc |= fip->fc_mdio; + else + io->iop_pdatc &= ~(fip->fc_mdio); + cmd <<= 1; + io->iop_pdatc |= fip->fc_mdck; + udelay(0); + } + io->iop_pdatc &= ~(fip->fc_mdck); + } + restore_flags(flags); + + /* Some diagrams show two 1 bits for "idle". I don't know if + * this is really necessary or if it was just to indicate nothing + * is going to happen for a while. + * Make the data pin an output, set the data high, and clock it. + */ + save_flags(flags); + cli(); + io->iop_pdatc |= fip->fc_mdio; + io->iop_pdirc |= fip->fc_mdio; + for (i=0; i<3; i++) + io->iop_pdatc ^= fip->fc_mdck; + restore_flags(flags); + + /* We exit with the same conditions as entry. + */ + return(retval); +} diff --git a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c index caa5ca8b0..97c4cb880 100644 --- a/arch/ppc/8260_io/uart.c +++ b/arch/ppc/8260_io/uart.c @@ -977,8 +977,7 @@ static int rs_8xx_write(struct tty_struct * tty, int from_user, } if (from_user) { - if (c != - copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) { + if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) { if (!ret) ret = -EFAULT; break; @@ -2396,10 +2395,10 @@ int __init rs_8xx_init(void) io->iop_pdird &= ~0x00800000; io->iop_psord &= ~0x00c00000; #if USE_SMC2 - io->iop_ppara |= 0x01800000; - io->iop_pdira |= 0x00800000; - io->iop_pdira &= ~0x01000000; - io->iop_psora &= ~0x01800000; + io->iop_ppara |= 0x00c00000; + io->iop_pdira |= 0x00400000; + io->iop_pdira &= ~0x00800000; + io->iop_psora &= ~0x00c00000; #endif /* Configure SCC2 and SCC3. Be careful about the fine print. @@ -2473,11 +2472,11 @@ int __init rs_8xx_init(void) * descriptors from dual port ram, and a character * buffer area from host mem. */ - dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_NUM_FIFO); + dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_NUM_FIFO, 8); /* Allocate space for FIFOs in the host memory. */ - mem_addr = m8260_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE); + mem_addr = m8260_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE, 1); /* Set the physical address of the host memory * buffers in the buffer descriptors, and the @@ -2506,11 +2505,11 @@ int __init rs_8xx_init(void) sup->scc_genscc.scc_rbase = dp_addr; } - dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO); + dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO, 8); /* Allocate space for FIFOs in the host memory. */ - mem_addr = m8260_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE); + mem_addr = m8260_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE, 1); /* Set the physical address of the host memory * buffers in the buffer descriptors, and the @@ -2716,11 +2715,11 @@ static int __init serial_console_setup(struct console *co, char *options) /* Allocate space for two buffer descriptors in the DP ram. */ - dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * 2); + dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * 2, 8); /* Allocate space for two 2 byte FIFOs in the host memory. */ - mem_addr = m8260_cpm_hostalloc(4); + mem_addr = m8260_cpm_hostalloc(4, 1); /* Set the physical address of the host memory buffers in * the buffer descriptors. diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index 730453bbb..b77cf32da 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -484,8 +484,11 @@ for (;;) { cep->stats.rx_bytes += pkt_len; /* This does 16 byte alignment, much more than we need. - */ - skb = dev_alloc_skb(pkt_len); + * The packet length includes FCS, but we don't want to + * include that when passing upstream as it messes up + * bridging applications. + */ + skb = dev_alloc_skb(pkt_len-4); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); @@ -493,10 +496,10 @@ for (;;) { } else { skb->dev = dev; - skb_put(skb,pkt_len); /* Make room */ + skb_put(skb,pkt_len-4); /* Make room */ eth_copy_and_sum(skb, (unsigned char *)__va(bdp->cbd_bufaddr), - pkt_len, 0); + pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index f69d0dfbd..45f10b635 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -669,18 +669,21 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { #endif /* This does 16 byte alignment, exactly what we need. + * The packet length includes FCS, but we don't want to + * include that when passing upstream as it messes up + * bridging applications. */ - skb = dev_alloc_skb(pkt_len); + skb = dev_alloc_skb(pkt_len-4); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); fep->stats.rx_dropped++; } else { skb->dev = dev; - skb_put(skb,pkt_len); /* Make room */ + skb_put(skb,pkt_len-4); /* Make room */ eth_copy_and_sum(skb, (unsigned char *)__va(bdp->cbd_bufaddr), - pkt_len, 0); + pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } diff --git a/arch/ppc/amiga/time.c b/arch/ppc/amiga/time.c index a78f8aa41..0073527a7 100644 --- a/arch/ppc/amiga/time.c +++ b/arch/ppc/amiga/time.c @@ -11,10 +11,6 @@ #include <linux/timex.h> -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec); - unsigned long m68k_get_rtc_time(void) { unsigned int year, mon, day, hour, min, sec; @@ -37,38 +33,6 @@ int m68k_set_rtc_time(unsigned long nowtime) return -1; } -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - - void apus_heartbeat (void) { #ifdef CONFIG_HEARTBEAT diff --git a/arch/ppc/chrpboot/Makefile b/arch/ppc/chrpboot/Makefile index 48750982e..f7ea3a3fa 100644 --- a/arch/ppc/chrpboot/Makefile +++ b/arch/ppc/chrpboot/Makefile @@ -67,11 +67,13 @@ initrd.o: ramdisk.image.gz piggyback zImage: $(OBJS) no_initrd.o addnote $(LD) $(LD_ARGS) -o $@ $(OBJS) no_initrd.o $(LIBS) - ./addnote $@ + cp $@ $@.rs6k + ./addnote $@.rs6k zImage.initrd: $(OBJS) initrd.o addnote $(LD) $(LD_ARGS) -o $@ $(OBJS) initrd.o $(LIBS) - ./addnote $@ + cp $@ $@.rs6k + ./addnote $@.rs6k else znetboot: diff --git a/arch/ppc/chrpboot/addnote.c b/arch/ppc/chrpboot/addnote.c index 5f0934f6e..b2374df7c 100644 --- a/arch/ppc/chrpboot/addnote.c +++ b/arch/ppc/chrpboot/addnote.c @@ -22,12 +22,23 @@ char arch[] = "PowerPC"; #define N_DESCR 6 unsigned int descr[N_DESCR] = { +#if 1 + /* values for IBM RS/6000 machines */ 0xffffffff, /* real-mode = true */ 0x00c00000, /* real-base, i.e. where we expect OF to be */ 0xffffffff, /* real-size */ 0xffffffff, /* virt-base */ 0xffffffff, /* virt-size */ 0x4000, /* load-base */ +#else + /* values for longtrail CHRP */ + 0, /* real-mode = false */ + 0xffffffff, /* real-base */ + 0xffffffff, /* real-size */ + 0xffffffff, /* virt-base */ + 0xffffffff, /* virt-size */ + 0x00600000, /* load-base */ +#endif }; unsigned char buf[512]; @@ -63,7 +74,7 @@ unsigned char buf[512]; unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; -main(int ac, char **av) +int main(int ac, char **av) { int fd, n, i; int ph, ps, np; diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile index 23afda4a8..494026e42 100644 --- a/arch/ppc/coffboot/Makefile +++ b/arch/ppc/coffboot/Makefile @@ -8,7 +8,7 @@ HOSTCFLAGS = -O -I$(TOPDIR)/include CFLAGS = $(CPPFLAGS) -O -fno-builtin 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 +CHRP_LD_ARGS = -Ttext 0x01000000 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 diff --git a/arch/ppc/coffboot/chrpmain.c b/arch/ppc/coffboot/chrpmain.c index 4d994d17e..08b238b16 100644 --- a/arch/ppc/coffboot/chrpmain.c +++ b/arch/ppc/coffboot/chrpmain.c @@ -22,13 +22,18 @@ 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 RAM_END (16 << 20) #define PROG_START 0x00010000 +#define PROG_SIZE 0x003f0000 + +#define SCRATCH_SIZE (128 << 10) char *avail_ram; -char *end_avail; +char *begin_avail, *end_avail; +char *avail_high; +unsigned int heap_use; +unsigned int heap_max; extern char _end[]; extern char image_data[]; @@ -60,29 +65,30 @@ boot(int a1, int a2, void *prom) im = image_data; len = image_len; /* claim 3MB starting at PROG_START */ - claim(PROG_START, 3 << 20, 0); + claim(PROG_START, PROG_SIZE, 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); + /* claim some memory for scratch space */ + avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10); + begin_avail = avail_high = avail_ram; + end_avail = avail_ram + SCRATCH_SIZE; + printf("heap at 0x%x\n", avail_ram); printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); - gunzip(dst, 3 << 20, im, &len); + gunzip(dst, PROG_SIZE, im, &len); printf("done %u bytes\n", len); + printf("%u bytes of heap consumed, max in use %u\n", + avail_high - begin_avail, heap_max); } 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); + (*(void (*)())sa)(a1, a2, prom); printf("returned?\n"); @@ -122,6 +128,7 @@ void make_bi_recs(unsigned long addr) rec = (struct bi_record *)((unsigned long)rec + rec->size); } +#if 0 #define eieio() asm volatile("eieio"); void stop_imac_ethernet(void) @@ -172,14 +179,35 @@ void stop_imac_usb(void) *usb_ctrl = 0x01000000; /* cpu_to_le32(1) */ eieio(); } +#endif + +struct memchunk { + unsigned int size; + struct memchunk *next; +}; + +static struct memchunk *freechunks; void *zalloc(void *x, unsigned items, unsigned size) { - void *p = avail_ram; + void *p; + struct memchunk **mpp, *mp; size *= items; size = (size + 7) & -8; + heap_use += size; + if (heap_use > heap_max) + heap_max = heap_use; + for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { + if (mp->size == size) { + *mpp = mp->next; + return mp; + } + } + p = avail_ram; avail_ram += size; + if (avail_ram > avail_high) + avail_high = avail_ram; if (avail_ram > end_avail) { printf("oops... out of memory\n"); pause(); @@ -189,6 +217,17 @@ void *zalloc(void *x, unsigned items, unsigned size) void zfree(void *x, void *addr, unsigned nb) { + struct memchunk *mp = addr; + + nb = (nb + 7) & -8; + heap_use -= nb; + if (avail_ram == addr + nb) { + avail_ram = addr; + return; + } + mp->size = nb; + mp->next = freechunks; + freechunks = mp; } #define HEAD_CRC 2 diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 950118eb2..0a217d4c9 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -88,11 +88,15 @@ fi if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then bool 'Math emulation' CONFIG_MATH_EMULATION fi + endmenu mainmenu_option next_comment comment 'General setup' +bool 'High memory support (experimental)' CONFIG_HIGHMEM +bool 'Mac-on-Linux support' CONFIG_MOL + define_bool CONFIG_ISA n define_bool CONFIG_SBUS n @@ -140,20 +144,6 @@ if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC fi - bool 'Power management support for PowerBooks' CONFIG_PMAC_PBOOK - bool 'Support for PowerMac floppy' CONFIG_MAC_FLOPPY - tristate 'Support for PowerMac serial ports' CONFIG_MAC_SERIAL - if [ "$CONFIG_MAC_SERIAL" = "y" ]; then - bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE - fi - bool 'Apple Desktop Bus (ADB) support' CONFIG_ADB - if [ "$CONFIG_ADB" = "y" ]; then - bool ' Include CUDA ADB driver' CONFIG_ADB_CUDA - bool ' Include MacIO ADB driver' CONFIG_ADB_MACIO - bool ' Include PMU (Powerbook) ADB driver' CONFIG_ADB_PMU - bool 'Support for ADB keyboard' CONFIG_ADB_KEYBOARD - bool 'Support for ADB mouse' CONFIG_ADBMOUSE - fi tristate 'Support for /dev/rtc' CONFIG_PPC_RTC bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE bool 'Support for early boot text console (BootX only)' CONFIG_BOOTX_TEXT @@ -192,7 +182,7 @@ endmenu source drivers/mtd/Config.in source drivers/pnp/Config.in source drivers/block/Config.in -#source drivers.new/Config.in +source drivers/md/Config.in if [ "$CONFIG_NET" = "y" ]; then source net/Config.in @@ -262,6 +252,43 @@ comment 'Console drivers' source drivers/video/Config.in endmenu +source drivers/input/Config.in + +mainmenu_option next_comment +comment 'Macintosh device drivers' + +if [ "$CONFIG_ALL_PPC" = "y" ]; then + # we want to change this to something like CONFIG_SYSCTRL_CUDA/PMU + bool 'Support for CUDA based PowerMacs' CONFIG_ADB_CUDA + bool 'Support for PMU based PowerMacs' CONFIG_ADB_PMU + if [ "$CONFIG_ADB_PMU" = "y" ]; then + bool ' Power management support for PowerBooks' CONFIG_PMAC_PBOOK + # made a separate option since backlight may end up beeing used + # on non-powerbook machines (but only on PMU based ones AFAIK) + bool ' Backlight control for LCD screens' CONFIG_PMAC_BACKLIGHT + fi + bool 'Support for PowerMac floppy' CONFIG_MAC_FLOPPY + tristate 'Support for PowerMac serial ports' CONFIG_MAC_SERIAL + if [ "$CONFIG_MAC_SERIAL" = "y" ]; then + bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE + fi + bool 'Apple Desktop Bus (ADB) support' CONFIG_ADB + if [ "$CONFIG_ADB" = "y" ]; then + bool ' Include MacIO (CHRP) ADB driver' CONFIG_ADB_MACIO + fi +fi +if [ "$CONFIG_ADB" = "y" ]; then + dep_bool ' Use input layer for ADB devices' CONFIG_INPUT_ADBHID $CONFIG_INPUT + if [ "$CONFIG_INPUT_ADBHID" = "y" ]; then + define_bool CONFIG_MAC_HID y + bool ' Support for ADB raw keycodes' CONFIG_MAC_ADBKEYCODES + bool ' Support for mouse button 2+3 emulation' CONFIG_MAC_EMUMOUSEBTN + else + bool ' Support for ADB keyboard (old driver)' CONFIG_ADB_KEYBOARD + fi +fi +endmenu + source drivers/char/Config.in source drivers/media/Config.in @@ -287,7 +314,6 @@ source arch/ppc/8260_io/Config.in fi source drivers/usb/Config.in -source drivers/input/Config.in mainmenu_option next_comment comment 'Kernel hacking' diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig index 68e49c148..a9ae80db0 100644 --- a/arch/ppc/configs/common_defconfig +++ b/arch/ppc/configs/common_defconfig @@ -1,5 +1,5 @@ # -# Automatically generated by make menuconfig: don't edit +# Automatically generated make config: don't edit # # CONFIG_UID16 is not set @@ -9,12 +9,20 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# # Platform support # CONFIG_PPC=y CONFIG_6xx=y # CONFIG_4xx is not set -# CONFIG_PPC64BRIDGE is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set # CONFIG_8260 is not set # CONFIG_8xx is not set CONFIG_ALL_PPC=y @@ -25,15 +33,9 @@ CONFIG_ALL_PPC=y CONFIG_ALTIVEC=y # -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# # General setup # +# CONFIG_HIGHMEM is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set CONFIG_PCI=y @@ -44,8 +46,8 @@ CONFIG_SYSVIPC=y CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_PCI_NAMES is not set +CONFIG_BINFMT_MISC=m +CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -57,21 +59,18 @@ CONFIG_VGA_CONSOLE=y CONFIG_FB=y CONFIG_FB_COMPAT_XPMAC=y CONFIG_PMAC_PBOOK=y -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_ADB=y -CONFIG_ADB_CUDA=y -CONFIG_ADB_MACIO=y -CONFIG_ADB_PMU=y -CONFIG_ADB_KEYBOARD=y -CONFIG_ADBMOUSE=y +CONFIG_PPC_RTC=y CONFIG_PROC_DEVICETREE=y CONFIG_BOOTX_TEXT=y # CONFIG_MOTOROLA_HOTSWAP is not set # CONFIG_CMDLINE_BOOL is not set # +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# # Plug and Play configuration # # CONFIG_PNP is not set @@ -90,8 +89,11 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_LVM is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set -# CONFIG_MD_STRIPED is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y # @@ -109,22 +111,24 @@ CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_ALIAS=y +# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y -CONFIG_SKB_LARGE=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set + +# +# +# # CONFIG_IPX is not set CONFIG_ATALK=m # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -145,26 +149,42 @@ CONFIG_IDE=y # IDE, ATA and ATAPI Block devices # CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# # CONFIG_BLK_DEV_HD_IDE is not set # CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set # CONFIG_BLK_DEV_IDECS is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set +CONFIG_BLK_DEV_IDEFLOPPY=y CONFIG_BLK_DEV_IDESCSI=y + +# +# IDE chipset support/bugfixes +# # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_IDEPCI_SHARE_IRQ=y CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_OFFBOARD is not set CONFIG_IDEDMA_PCI_AUTO=y CONFIG_BLK_DEV_IDEDMA=y -CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set # CONFIG_BLK_DEV_AEC62XX is not set @@ -173,37 +193,40 @@ CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD7409 is not set # CONFIG_AMD7409_OVERRIDE is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_CMD64X_RAID is not set +CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_HPT366_FIP is not set -# CONFIG_HPT366_MODE3 is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_MASTER is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set # CONFIG_VIA82CXXX_TUNING is not set -# CONFIG_BLK_DEV_SL82C105 is not set +CONFIG_BLK_DEV_SL82C105=y CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_BLK_DEV_IDEDMA_PMAC=y -CONFIG_IDEDMA_PMAC_AUTO=y +CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO=y CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDE_CHIPSETS is not set CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set CONFIG_BLK_DEV_IDE_MODES=y # # SCSI support # CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y @@ -211,6 +234,10 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# # CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_CONSTANTS=y @@ -296,6 +323,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -327,8 +355,9 @@ CONFIG_DE4X5=y # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set # CONFIG_LNE390 is not set -# CONFIG_NE3210 is not set +# CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set # CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set # CONFIG_SIS900 is not set @@ -347,11 +376,13 @@ CONFIG_DE4X5=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_ASYNC is not set +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=y # CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set +CONFIG_PPP_DEFLATE=y # CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set # CONFIG_SLIP is not set # @@ -404,12 +435,13 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_FB_RIVA is not set # CONFIG_FB_CLGEN is not set # CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set CONFIG_FB_OF=y CONFIG_FB_CONTROL=y CONFIG_FB_PLATINUM=y CONFIG_FB_VALKYRIE=y -CONFIG_FB_IMSTT=y CONFIG_FB_CT65550=y +CONFIG_FB_IMSTT=y # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set CONFIG_FB_MATROX=y @@ -420,6 +452,7 @@ CONFIG_FB_MATROX_G100=y CONFIG_FB_ATY=y CONFIG_FB_ATY128=y CONFIG_FB_3DFX=y +# CONFIG_FB_SIS is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB8=y @@ -437,6 +470,32 @@ CONFIG_FONT_SUN12x22=y # CONFIG_FONT_ACORN_8x8 is not set # +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Macintosh device drivers +# +CONFIG_MAC_FLOPPY=y +CONFIG_MAC_SERIAL=y +# CONFIG_SERIAL_CONSOLE is not set +CONFIG_ADB=y +CONFIG_ADB_CUDA=y +CONFIG_ADB_MACIO=y +CONFIG_ADB_PMU=y +CONFIG_INPUT_ADBHID=y +CONFIG_MAC_HID=y +CONFIG_MAC_ADBKEYCODES=y +CONFIG_MAC_EMUMOUSEBTN=y + +# # Character devices # CONFIG_VT=y @@ -459,7 +518,6 @@ CONFIG_BUSMOUSE=y # CONFIG_ATIXL_BUSMOUSE is not set # CONFIG_LOGIBUSMOUSE is not set # CONFIG_MS_BUSMOUSE is not set -CONFIG_ADBMOUSE=y CONFIG_MOUSE=y CONFIG_PSMOUSE=y # CONFIG_82C710_MOUSE is not set @@ -469,19 +527,19 @@ CONFIG_PSMOUSE=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set CONFIG_NVRAM=y # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -490,26 +548,31 @@ CONFIG_NVRAM=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems # # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y -# CONFIG_AUTOFS4_FS is not set +CONFIG_AUTOFS4_FS=y # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=y +# CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y @@ -519,7 +582,8 @@ CONFIG_ISO9660_FS=y # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set +CONFIG_DEVFS_FS=y +# CONFIG_DEVFS_MOUNT is not set # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set @@ -571,12 +635,14 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set CONFIG_NLS=y # # Native Language Support # +CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set @@ -593,6 +659,10 @@ CONFIG_NLS=y # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set # CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set # CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -605,6 +675,7 @@ CONFIG_NLS=y # CONFIG_NLS_ISO8859_14 is not set # CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_UTF8 is not set # # Sound @@ -614,6 +685,7 @@ CONFIG_DMASOUND_AWACS=y CONFIG_DMASOUND=y # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set # CONFIG_SOUND_ES1370 is not set # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set @@ -622,6 +694,7 @@ CONFIG_DMASOUND=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set CONFIG_SOUND_OSS=y # CONFIG_SOUND_TRACEINIT is not set # CONFIG_SOUND_DMAP is not set @@ -647,24 +720,39 @@ CONFIG_SOUND_CS4232=m # CONFIG_SOUND_AWE32_SYNTH is not set # CONFIG_SOUND_WAVEFRONT is not set # CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_VIA82CXXX is not set # CONFIG_SOUND_YM3812 is not set # CONFIG_SOUND_OPL3SA1 is not set # CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMPCI is not set # CONFIG_SOUND_UART6850 is not set # CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support # CONFIG_USB=y CONFIG_USB_DEBUG=y -# CONFIG_USB_DEVICEFS is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Controllers +# # CONFIG_USB_UHCI is not set # CONFIG_USB_UHCI_ALT is not set CONFIG_USB_OHCI=y + +# +# USB Devices +# # CONFIG_USB_PRINTER is not set # CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set # CONFIG_USB_AUDIO is not set # CONFIG_USB_ACM is not set # CONFIG_USB_SERIAL is not set @@ -679,15 +767,13 @@ CONFIG_USB_OHCI=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_DSBR is not set +# CONFIG_USB_BLUETOOTH is not set + +# +# USB Human Interface Devices (HID) +# CONFIG_USB_HID=y # CONFIG_USB_WACOM is not set -# CONFIG_USB_WMFORCE is not set -CONFIG_INPUT_KEYBDEV=y -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set # # Kernel hacking @@ -695,4 +781,3 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set CONFIG_XMON=y - diff --git a/arch/ppc/configs/est8260_defconfig b/arch/ppc/configs/est8260_defconfig index 972820d21..d317c8517 100644 --- a/arch/ppc/configs/est8260_defconfig +++ b/arch/ppc/configs/est8260_defconfig @@ -9,12 +9,18 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Platform support # CONFIG_PPC=y # CONFIG_6xx is not set # CONFIG_4xx is not set -# CONFIG_PPC64BRIDGE is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set CONFIG_8260=y # CONFIG_8xx is not set CONFIG_6xx=y @@ -29,13 +35,9 @@ CONFIG_EST8260=y CONFIG_MACH_SPECIFIC=y # -# Loadable module support -# -# CONFIG_MODULES is not set - -# # General setup # +# CONFIG_HIGHMEM is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set # CONFIG_PCI is not set @@ -56,15 +58,17 @@ CONFIG_KERNEL_ELF=y # CONFIG_PARPORT is not set # CONFIG_VGA_CONSOLE is not set # CONFIG_FB is not set -# CONFIG_PMAC_PBOOK is not set -# CONFIG_MAC_FLOPPY is not set -# CONFIG_MAC_SERIAL is not set -# CONFIG_ADB is not set +# CONFIG_PPC_RTC is not set # CONFIG_PROC_DEVICETREE is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_MOTOROLA_HOTSWAP is not set # +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# # Plug and Play configuration # # CONFIG_PNP is not set @@ -84,8 +88,10 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set -# CONFIG_RAID15_DANGEROUS is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y # @@ -105,17 +111,11 @@ CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_ALIAS=y +# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y - -# -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -126,9 +126,9 @@ CONFIG_SKB_LARGE=y # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -164,6 +164,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -245,6 +246,15 @@ CONFIG_NET_ETHERNET=y # CONFIG_FB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# # Character devices # # CONFIG_VT is not set @@ -269,19 +279,19 @@ CONFIG_UNIX98_PTY_COUNT=256 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -290,9 +300,13 @@ CONFIG_UNIX98_PTY_COUNT=256 # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -310,6 +324,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set @@ -369,6 +384,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_MAC_PARTITION is not set # CONFIG_MSDOS_PARTITION is not set # CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set # CONFIG_NLS is not set @@ -382,7 +398,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SCC_ENET=y CONFIG_SCC1_ENET=y -# CONFIG_FCC_ENET is not set +# CONFIG_FEC_ENET is not set # # USB support diff --git a/arch/ppc/configs/gemini_defconfig b/arch/ppc/configs/gemini_defconfig index e141e8f54..522bd5d5d 100644 --- a/arch/ppc/configs/gemini_defconfig +++ b/arch/ppc/configs/gemini_defconfig @@ -14,14 +14,12 @@ CONFIG_EXPERIMENTAL=y CONFIG_PPC=y CONFIG_6xx=y # CONFIG_4xx is not set -# CONFIG_PPC64BRIDGE is not set -# CONFIG_82xx is not set +# CONFIG_PPC64 is not set +# CONFIG_8260 is not set # CONFIG_8xx is not set -# CONFIG_PMAC is not set -# CONFIG_PREP is not set -# CONFIG_CHRP is not set # CONFIG_ALL_PPC is not set CONFIG_GEMINI=y +# CONFIG_EST8260 is not set # CONFIG_APUS is not set # CONFIG_SMP is not set CONFIG_ALTIVEC=y @@ -37,7 +35,8 @@ CONFIG_KMOD=y # # General setup # -# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_SBUS is not set CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y @@ -47,8 +46,12 @@ CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PCI_NAMES is not set # CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set # CONFIG_VGA_CONSOLE is not set # CONFIG_FB is not set @@ -57,7 +60,6 @@ CONFIG_KERNEL_ELF=y # CONFIG_MAC_SERIAL is not set # CONFIG_ADB is not set # CONFIG_PROC_DEVICETREE is not set -# CONFIG_TOTALMP is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_MOTOROLA_HOTSWAP is not set @@ -70,22 +72,16 @@ CONFIG_KERNEL_ELF=y # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_IDE is not set # -# Please see Documentation/ide.txt for help/info on IDE drives +# Additional Block Devices # -# CONFIG_BLK_DEV_HD_ONLY is not set -# CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set # CONFIG_BLK_DEV_MD is not set +# CONFIG_RAID15_DANGEROUS is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set # # Networking options @@ -138,6 +134,13 @@ CONFIG_SKB_LARGE=y # CONFIG_NET_SCHED is not set # +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# # SCSI support # CONFIG_SCSI=y @@ -148,7 +151,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 # CONFIG_CHR_DEV_ST is not set -CONFIG_ST_EXTRA_DEVS=2 CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 @@ -171,7 +173,6 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_IPS is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set @@ -184,43 +185,22 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_NCR53C8XX is not set -CONFIG_SCSI_SYM53C8XX=y -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=20 -# CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +# CONFIG_SCSI_NCR53C7xx_sync is not set +# CONFIG_SCSI_NCR53C7xx_FAST is not set +# CONFIG_SCSI_NCR53C7xx_DISCONNECT is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_SEAGATE is not set -# CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_ULTRASTOR is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_MESH is not set # CONFIG_SCSI_MAC53C94 is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set # # Network device support @@ -232,6 +212,7 @@ CONFIG_NETDEVICES=y # # CONFIG_ARCNET is not set # CONFIG_DUMMY is not set +# CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -249,12 +230,10 @@ CONFIG_NCR885E=y # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_RTL8139 is not set -# CONFIG_DM9102 is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set # CONFIG_NET_ISA is not set -# CONFIG_NET_EISA is not set +# CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set # @@ -274,7 +253,7 @@ CONFIG_NCR885E=y # CONFIG_NET_RADIO is not set # -# Token Ring driver support +# Token Ring devices # # CONFIG_TR is not set # CONFIG_NET_FC is not set @@ -292,6 +271,11 @@ CONFIG_NCR885E=y # CONFIG_HAMRADIO is not set # +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# # ISDN subsystem # # CONFIG_ISDN is not set @@ -361,12 +345,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_AGP is not set # -# USB support -# -# CONFIG_USB is not set - -# -# Filesystems +# File systems # # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set @@ -378,12 +357,14 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_FAT_FS is not set # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set # CONFIG_ROMFS_FS is not set @@ -397,6 +378,7 @@ CONFIG_EXT2_FS=y # # CONFIG_CODA_FS is not set CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set # CONFIG_NFSD is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y @@ -416,6 +398,11 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SOUND is not set # +# USB support +# +# CONFIG_USB is not set + +# # Kernel hacking # # CONFIG_MAGIC_SYSRQ is not set diff --git a/arch/ppc/configs/rpxcllf_defconfig b/arch/ppc/configs/rpxcllf_defconfig index 9aaa80530..4dda3d93f 100644 --- a/arch/ppc/configs/rpxcllf_defconfig +++ b/arch/ppc/configs/rpxcllf_defconfig @@ -9,18 +9,27 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Platform support # CONFIG_PPC=y # CONFIG_6xx is not set # CONFIG_4xx is not set -# CONFIG_PPC64BRIDGE is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set # CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set CONFIG_RPXCLASSIC=y # CONFIG_BSEIP is not set +# CONFIG_TQM8xxL is not set +# CONFIG_TQM860L is not set +# CONFIG_TQM860 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set # CONFIG_ALL_PPC is not set @@ -29,13 +38,9 @@ CONFIG_MACH_SPECIFIC=y CONFIG_MATH_EMULATION=y # -# Loadable module support -# -# CONFIG_MODULES is not set - -# # General setup # +# CONFIG_HIGHMEM is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set # CONFIG_PCI is not set @@ -56,6 +61,11 @@ CONFIG_KERNEL_ELF=y # CONFIG_PARPORT is not set # +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# # Plug and Play configuration # # CONFIG_PNP is not set @@ -75,8 +85,10 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set -# CONFIG_RAID15_DANGEROUS is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y # @@ -96,17 +108,11 @@ CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_ALIAS=y +# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y - -# -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -117,9 +123,9 @@ CONFIG_SKB_LARGE=y # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -155,6 +161,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -236,6 +243,15 @@ CONFIG_NET_ETHERNET=y # CONFIG_FB is not set # +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# # Character devices # # CONFIG_VT is not set @@ -260,19 +276,19 @@ CONFIG_UNIX98_PTY_COUNT=256 # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -281,9 +297,13 @@ CONFIG_UNIX98_PTY_COUNT=256 # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems @@ -301,6 +321,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set @@ -360,6 +381,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_MAC_PARTITION is not set # CONFIG_MSDOS_PARTITION is not set # CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set # CONFIG_NLS is not set @@ -374,7 +396,9 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_SCC_ENET=y CONFIG_SCC1_ENET=y CONFIG_FEC_ENET=y +CONFIG_ENET_BIG_BUFFERS=y CONFIG_8xxSMC2=y +# CONFIG_8xx_ALTSMC2 is not set CONFIG_8xxSCC=y # diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index e1854fad6..9b3d88212 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -1,5 +1,5 @@ # -# Automatically generated by make menuconfig: don't edit +# Automatically generated make config: don't edit # # CONFIG_UID16 is not set @@ -9,12 +9,20 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# # Platform support # CONFIG_PPC=y CONFIG_6xx=y # CONFIG_4xx is not set -# CONFIG_PPC64BRIDGE is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set # CONFIG_8260 is not set # CONFIG_8xx is not set CONFIG_ALL_PPC=y @@ -25,15 +33,9 @@ CONFIG_ALL_PPC=y CONFIG_ALTIVEC=y # -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# # General setup # +# CONFIG_HIGHMEM is not set # CONFIG_ISA is not set # CONFIG_SBUS is not set CONFIG_PCI=y @@ -44,8 +46,8 @@ CONFIG_SYSVIPC=y CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_PCI_NAMES is not set +CONFIG_BINFMT_MISC=m +CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -57,21 +59,18 @@ CONFIG_VGA_CONSOLE=y CONFIG_FB=y CONFIG_FB_COMPAT_XPMAC=y CONFIG_PMAC_PBOOK=y -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_ADB=y -CONFIG_ADB_CUDA=y -CONFIG_ADB_MACIO=y -CONFIG_ADB_PMU=y -CONFIG_ADB_KEYBOARD=y -CONFIG_ADBMOUSE=y +CONFIG_PPC_RTC=y CONFIG_PROC_DEVICETREE=y CONFIG_BOOTX_TEXT=y # CONFIG_MOTOROLA_HOTSWAP is not set # CONFIG_CMDLINE_BOOL is not set # +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# # Plug and Play configuration # # CONFIG_PNP is not set @@ -90,8 +89,11 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_LVM is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_MD_LINEAR is not set -# CONFIG_MD_STRIPED is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y # @@ -109,22 +111,24 @@ CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_ALIAS=y +# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y -CONFIG_SKB_LARGE=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set + +# +# +# # CONFIG_IPX is not set CONFIG_ATALK=m # CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_BRIDGE is not set # CONFIG_LLC is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -145,26 +149,42 @@ CONFIG_IDE=y # IDE, ATA and ATAPI Block devices # CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# # CONFIG_BLK_DEV_HD_IDE is not set # CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set # CONFIG_BLK_DEV_IDECS is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set +CONFIG_BLK_DEV_IDEFLOPPY=y CONFIG_BLK_DEV_IDESCSI=y + +# +# IDE chipset support/bugfixes +# # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_IDEPCI_SHARE_IRQ=y CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_OFFBOARD is not set CONFIG_IDEDMA_PCI_AUTO=y CONFIG_BLK_DEV_IDEDMA=y -CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set # CONFIG_BLK_DEV_AEC62XX is not set @@ -173,37 +193,40 @@ CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD7409 is not set # CONFIG_AMD7409_OVERRIDE is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_CMD64X_RAID is not set +CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_HPT366_FIP is not set -# CONFIG_HPT366_MODE3 is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_MASTER is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set # CONFIG_VIA82CXXX_TUNING is not set -# CONFIG_BLK_DEV_SL82C105 is not set +CONFIG_BLK_DEV_SL82C105=y CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_BLK_DEV_IDEDMA_PMAC=y -CONFIG_IDEDMA_PMAC_AUTO=y +CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO=y CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDE_CHIPSETS is not set CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set CONFIG_BLK_DEV_IDE_MODES=y # # SCSI support # CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y @@ -211,6 +234,10 @@ CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# # CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_CONSTANTS=y @@ -296,6 +323,7 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set @@ -327,8 +355,9 @@ CONFIG_DE4X5=y # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set # CONFIG_LNE390 is not set -# CONFIG_NE3210 is not set +# CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set # CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set # CONFIG_SIS900 is not set @@ -347,11 +376,13 @@ CONFIG_DE4X5=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_ASYNC is not set +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=y # CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set +CONFIG_PPP_DEFLATE=y # CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set # CONFIG_SLIP is not set # @@ -404,12 +435,13 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_FB_RIVA is not set # CONFIG_FB_CLGEN is not set # CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set CONFIG_FB_OF=y CONFIG_FB_CONTROL=y CONFIG_FB_PLATINUM=y CONFIG_FB_VALKYRIE=y -CONFIG_FB_IMSTT=y CONFIG_FB_CT65550=y +CONFIG_FB_IMSTT=y # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set CONFIG_FB_MATROX=y @@ -420,6 +452,7 @@ CONFIG_FB_MATROX_G100=y CONFIG_FB_ATY=y CONFIG_FB_ATY128=y CONFIG_FB_3DFX=y +# CONFIG_FB_SIS is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB8=y @@ -437,6 +470,32 @@ CONFIG_FONT_SUN12x22=y # CONFIG_FONT_ACORN_8x8 is not set # +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Macintosh device drivers +# +CONFIG_MAC_FLOPPY=y +CONFIG_MAC_SERIAL=y +# CONFIG_SERIAL_CONSOLE is not set +CONFIG_ADB=y +CONFIG_ADB_CUDA=y +CONFIG_ADB_MACIO=y +CONFIG_ADB_PMU=y +CONFIG_INPUT_ADBHID=y +CONFIG_MAC_HID=y +CONFIG_MAC_ADBKEYCODES=y +CONFIG_MAC_EMUMOUSEBTN=y + +# # Character devices # CONFIG_VT=y @@ -459,7 +518,6 @@ CONFIG_BUSMOUSE=y # CONFIG_ATIXL_BUSMOUSE is not set # CONFIG_LOGIBUSMOUSE is not set # CONFIG_MS_BUSMOUSE is not set -CONFIG_ADBMOUSE=y CONFIG_MOUSE=y CONFIG_PSMOUSE=y # CONFIG_82C710_MOUSE is not set @@ -469,19 +527,19 @@ CONFIG_PSMOUSE=y # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set CONFIG_NVRAM=y # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -490,26 +548,31 @@ CONFIG_NVRAM=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_DRM is not set -# CONFIG_DRM_TDFX is not set # CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set # # File systems # # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y -# CONFIG_AUTOFS4_FS is not set +CONFIG_AUTOFS4_FS=y # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=y +# CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y @@ -519,7 +582,7 @@ CONFIG_ISO9660_FS=y # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set +CONFIG_DEVFS_FS=y # CONFIG_DEVFS_MOUNT is not set # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y @@ -572,12 +635,14 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set CONFIG_NLS=y # # Native Language Support # +CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set @@ -594,6 +659,10 @@ CONFIG_NLS=y # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set # CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set # CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -606,6 +675,7 @@ CONFIG_NLS=y # CONFIG_NLS_ISO8859_14 is not set # CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_UTF8 is not set # # Sound @@ -615,6 +685,7 @@ CONFIG_DMASOUND_AWACS=y CONFIG_DMASOUND=y # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set # CONFIG_SOUND_ES1370 is not set # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set @@ -623,6 +694,7 @@ CONFIG_DMASOUND=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set CONFIG_SOUND_OSS=y # CONFIG_SOUND_TRACEINIT is not set # CONFIG_SOUND_DMAP is not set @@ -648,24 +720,39 @@ CONFIG_SOUND_CS4232=m # CONFIG_SOUND_AWE32_SYNTH is not set # CONFIG_SOUND_WAVEFRONT is not set # CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_VIA82CXXX is not set # CONFIG_SOUND_YM3812 is not set # CONFIG_SOUND_OPL3SA1 is not set # CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMPCI is not set # CONFIG_SOUND_UART6850 is not set # CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support # CONFIG_USB=y CONFIG_USB_DEBUG=y -# CONFIG_USB_DEVICEFS is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Controllers +# # CONFIG_USB_UHCI is not set # CONFIG_USB_UHCI_ALT is not set CONFIG_USB_OHCI=y + +# +# USB Devices +# # CONFIG_USB_PRINTER is not set # CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set # CONFIG_USB_AUDIO is not set # CONFIG_USB_ACM is not set # CONFIG_USB_SERIAL is not set @@ -680,15 +767,18 @@ CONFIG_USB_OHCI=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_DSBR is not set +# CONFIG_USB_BLUETOOTH is not set + +# +# USB Human Interface Devices (HID) +# CONFIG_USB_HID=y # CONFIG_USB_WACOM is not set -# CONFIG_USB_WMFORCE is not set -CONFIG_INPUT_KEYBDEV=y -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set + +# +# Mac-on-Linux (MOL) support +# +# CONFIG_MOL is not set # # Kernel hacking diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 0369ad800..a539083bd 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -99,8 +99,10 @@ endif ifeq ($(CONFIG_ALL_PPC),y) O_OBJS += pmac_pic.o pmac_setup.o pmac_time.o feature.o pmac_pci.o prom.o \ chrp_setup.o chrp_time.o chrp_pci.o open_pic.o indirect_pci.o \ - prep_pci.o i8259.o prep_nvram.o prep_time.o residual.o \ - pmac_backlight.o + prep_pci.o i8259.o prep_nvram.o prep_time.o residual.o + ifeq ($(CONFIG_PMAC_BACKLIGHT),y) + O_OBJS += pmac_backlight.o + endif OX_OBJS += prep_setup.o endif ifeq ($(CONFIG_GEMINI),y) diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c index b93bd8193..d75663be5 100644 --- a/arch/ppc/kernel/apus_setup.c +++ b/arch/ppc/kernel/apus_setup.c @@ -304,7 +304,7 @@ __apus void apus_calibrate_decr(void) { #ifdef CONFIG_APUS - int freq, divisor; + unsigned long freq; /* This algorithm for determining the bus speed was contributed by Ralph Schmidt. */ @@ -335,8 +335,8 @@ void apus_calibrate_decr(void) bus_speed = 60; freq = 15000000; } else if ((bus_speed >= 63) && (bus_speed < 69)) { - bus_speed = 66; - freq = 16500000; + bus_speed = 67; + freq = 16666667; } else { printk ("APUS: Unable to determine bus speed (%d). " "Defaulting to 50MHz", bus_speed); @@ -375,12 +375,10 @@ void apus_calibrate_decr(void) } - freq *= 60; /* try to make freq/1e6 an integer */ - divisor = 60; - printk("time_init: decrementer frequency = %d/%d\n", freq, divisor); - decrementer_count = freq / HZ / divisor; - count_period_num = divisor; - count_period_den = freq / 1000000; + printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", + freq/1000000, freq%1000000); + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); __bus_speed = bus_speed; __speed_test_failed = speed_test_failed; diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c index c43296c42..43b678861 100644 --- a/arch/ppc/kernel/chrp_pci.c +++ b/arch/ppc/kernel/chrp_pci.c @@ -284,13 +284,38 @@ hydra_init(void) return 1; } +#ifdef CONFIG_POWER4 +static void +power4_fixup_dev(struct pci_dev *dev) +{ + int i; + unsigned long offset; + + for (i = 0; i < 6; ++i) { + if (dev->resource[i].start == 0) + continue; + offset = pci_address_offset(dev->bus->number, + dev->resource[i].flags); + if (offset) { + dev->resource[i].start += offset; + dev->resource[i].end += offset; + printk("device %x.%x[%d] now [%lx..%lx]\n", + dev->bus->number, dev->devfn, i, + dev->resource[i].start, + dev->resource[i].end); + } + /* zap the 2nd function of the winbond chip */ + if (dev->resource[i].flags & IORESOURCE_IO + && dev->bus->number == 0 && dev->devfn == 0x81) + dev->resource[i].flags &= ~IORESOURCE_IO; + } +} +#endif /* CONFIG_POWER4 */ + void __init chrp_pcibios_fixup(void) { struct pci_dev *dev; -#ifdef CONFIG_POWER4 - int i; -#endif int *brp; struct device_node *np; extern struct pci_ops generic_pci_ops; @@ -316,10 +341,8 @@ chrp_pcibios_fixup(void) /* PCI interrupts are controlled by the OpenPIC */ pci_for_each_dev(dev) { np = find_pci_device_OFnode(dev->bus->number, dev->devfn); - if ( (np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) + if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) dev->irq = np->intrs[0].line; - if ( dev->irq ) - dev->irq = openpic_to_irq( dev->irq ); /* these need to be absolute addrs for OF and Matrox FB -- Cort */ if ( dev->vendor == PCI_VENDOR_ID_MATROX ) { @@ -337,25 +360,7 @@ chrp_pcibios_fixup(void) dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); } #ifdef CONFIG_POWER4 - for (i = 0; i < 6; ++i) { - unsigned long offset; - if (dev->resource[i].start == 0) - continue; - offset = pci_address_offset(dev->bus->number, - dev->resource[i].flags); - if (offset) { - dev->resource[i].start += offset; - dev->resource[i].end += offset; - printk("device %x.%x[%d] now [%lx..%lx]\n", - dev->bus->number, dev->devfn, i, - dev->resource[i].start, - dev->resource[i].end); - } - /* zap the 2nd function of the winbond chip */ - if (dev->resource[i].flags & IORESOURCE_IO - && dev->bus->number == 0 && dev->devfn == 0x81) - dev->resource[i].flags &= ~IORESOURCE_IO; - } + power4_fixup_dev(dev); #else if (dev->bus->number > 0 && python_busnr > 0) dev->resource[0].start += dev->bus->number*0x01000000; @@ -363,6 +368,40 @@ chrp_pcibios_fixup(void) } } +static struct { + /* parent is iomem */ + struct resource ram, pci_mem, isa_mem, pci_io, pci_cfg, rom_exp, flash; + /* parent is isa_mem */ + struct resource nvram; +} gg2_resources = { + ram: { "RAM", 0x00000000, 0xbfffffff, IORESOURCE_MEM }, + pci_mem: { "GG2 PCI mem", 0xc0000000, 0xf6ffffff, IORESOURCE_MEM }, + isa_mem: { "GG2 ISA mem", 0xf7000000, 0xf7ffffff }, + pci_io: { "GG2 PCI I/O", 0xf8000000, 0xf8ffffff }, + pci_cfg: { "GG2 PCI cfg", 0xfec00000, 0xfec7ffff }, + rom_exp: { "ROM exp", 0xff000000, 0xff7fffff, }, + flash: { "Flash ROM", 0xfff80000, 0xffffffff }, + nvram: { "NVRAM", 0xf70e0000, 0xf70e7fff }, +}; + +static void __init gg2_pcibios_fixup(void) +{ + int i; + extern unsigned long *end_of_DRAM; + + chrp_pcibios_fixup(); + gg2_resources.ram.end = (unsigned long)end_of_DRAM-PAGE_OFFSET; + for (i = 0; i < 7; i++) + request_resource(&iomem_resource, + &((struct resource *)&gg2_resources)[i]); + request_resource(&gg2_resources.isa_mem, &gg2_resources.nvram); +} + +static void __init gg2_pcibios_fixup_bus(struct pci_bus *bus) +{ + bus->resource[1] = &gg2_resources.pci_mem; +} + decl_config_access_method(grackle); decl_config_access_method(indirect); decl_config_access_method(rtas); @@ -372,6 +411,7 @@ chrp_setup_pci_ptrs(void) { struct device_node *py; + ppc_md.pcibios_fixup = chrp_pcibios_fixup; #ifdef CONFIG_POWER4 set_config_access_method(rtas); pci_dram_offset = 0; @@ -428,16 +468,17 @@ chrp_setup_pci_ptrs(void) } else { + /* LongTrail */ pci_dram_offset = 0; isa_mem_base = 0xf7000000; isa_io_base = 0xf8000000; set_config_access_method(gg2); + ppc_md.pcibios_fixup = gg2_pcibios_fixup; + ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus; } } } #endif /* CONFIG_POWER4 */ - - ppc_md.pcibios_fixup = chrp_pcibios_fixup; } #ifdef CONFIG_PPC64BRIDGE diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index 8d6649231..ccc6621de 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -62,11 +62,13 @@ extern volatile unsigned char *chrp_int_ack_special; unsigned long chrp_get_rtc_time(void); int chrp_set_rtc_time(unsigned long nowtime); void chrp_calibrate_decr(void); -void chrp_time_init(void); +long chrp_time_init(void); void chrp_setup_pci_ptrs(void); -extern void chrp_progress(char *, unsigned short); void chrp_event_scan(void); +void rtas_display_progress(char *, unsigned short); +void rtas_indicator_progress(char *, unsigned short); +void bootx_text_progress(char *, unsigned short); extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int pckbd_getkeycode(unsigned int scancode); @@ -91,6 +93,8 @@ extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; extern int probingmem; extern unsigned long loops_per_sec; +extern int bootx_text_mapped; +static int max_width; unsigned long empty_zero_page[1024]; @@ -252,13 +256,6 @@ chrp_setup_arch(void) #endif ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ printk("Boot arguments: %s\n", cmd_line); - - request_region(0x20,0x20,"pic1"); - request_region(0xa0,0x20,"pic2"); - request_region(0x00,0x20,"dma1"); - request_region(0x40,0x20,"timer"); - request_region(0x80,0x10,"dma page reg"); - request_region(0xc0,0x20,"dma2"); #ifndef CONFIG_PPC64BRIDGE /* PCI bridge config space access area - @@ -446,11 +443,43 @@ void __init chrp_init_IRQ(void) void __init chrp_init2(void) { +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) + struct device_node *kbd; +#endif #ifdef CONFIG_NVRAM pmac_nvram_init(); #endif + + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); + if (ppc_md.progress) ppc_md.progress(" Have fun! ", 0x7777); + +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) + if (kbd->parent && kbd->parent->type + && strcmp(kbd->parent->type, "adb") == 0) + break; + if (kbd) { + ppc_md.kbd_setkeycode = mackbd_setkeycode; + ppc_md.kbd_getkeycode = mackbd_getkeycode; + ppc_md.kbd_translate = mackbd_translate; + ppc_md.kbd_unexpected_up = mackbd_unexpected_up; + ppc_md.kbd_leds = mackbd_leds; + ppc_md.kbd_init_hw = mackbd_init_hw; +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; + SYSRQ_KEY = 0x69; +#endif /* CONFIG_MAGIC_SYSRQ */ + } +#endif /* CONFIG_VT && CONFIG_ADB_KEYBOARD */ } #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) @@ -598,40 +627,40 @@ void __init ppc_md.calibrate_decr = chrp_calibrate_decr; #ifdef CONFIG_VT -#ifdef CONFIG_MAC_KEYBOARD - if (adb_driver == NULL) - { -#endif /* CONFIG_MAC_KEYBOAD */ - ppc_md.kbd_setkeycode = pckbd_setkeycode; - ppc_md.kbd_getkeycode = pckbd_getkeycode; - ppc_md.kbd_translate = pckbd_translate; - ppc_md.kbd_unexpected_up = pckbd_unexpected_up; - ppc_md.kbd_leds = pckbd_leds; - ppc_md.kbd_init_hw = pckbd_init_hw; -#ifdef CONFIG_MAGIC_SYSRQ - ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; - SYSRQ_KEY = 0x54; -#endif /* CONFIG_MAGIC_SYSRQ */ -#ifdef CONFIG_MAC_KEYBOARD - } - else - { - ppc_md.kbd_setkeycode = mackbd_setkeycode; - ppc_md.kbd_getkeycode = mackbd_getkeycode; - ppc_md.kbd_translate = mackbd_translate; - ppc_md.kbd_unexpected_up = mackbd_unexpected_up; - ppc_md.kbd_leds = mackbd_leds; - ppc_md.kbd_init_hw = mackbd_init_hw; + /* these are adjusted in chrp_init2 if we have an ADB keyboard */ + ppc_md.kbd_setkeycode = pckbd_setkeycode; + ppc_md.kbd_getkeycode = pckbd_getkeycode; + ppc_md.kbd_translate = pckbd_translate; + ppc_md.kbd_unexpected_up = pckbd_unexpected_up; + ppc_md.kbd_leds = pckbd_leds; + ppc_md.kbd_init_hw = pckbd_init_hw; #ifdef CONFIG_MAGIC_SYSRQ - ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; - SYSRQ_KEY = 0x69; + ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; #endif /* CONFIG_MAGIC_SYSRQ */ - } -#endif /* CONFIG_MAC_KEYBOARD */ #endif /* CONFIG_VT */ - if ( rtas_data ) - ppc_md.progress = chrp_progress; - + + if (rtas_data) { + struct device_node *rtas; + unsigned int *p; + + rtas = find_devices("rtas"); + if (rtas != NULL) { + if (get_property(rtas, "display-character", NULL)) { + ppc_md.progress = rtas_display_progress; + p = (unsigned int *) get_property + (rtas, "ibm,display-line-length", NULL); + if (p) + max_width = *p; + } else if (get_property(rtas, "set-indicator", NULL)) + ppc_md.progress = rtas_indicator_progress; + } + } +#ifdef CONFIG_BOOTX_TEXT + if (ppc_md.progress == NULL && bootx_text_mapped) + ppc_md.progress = bootx_text_progress; +#endif + #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.insw = chrp_ide_insw; ppc_ide_md.outsw = chrp_ide_outsw; @@ -653,30 +682,13 @@ void __init } void __chrp -chrp_progress(char *s, unsigned short hex) +rtas_display_progress(char *s, unsigned short hex) { - extern unsigned int rtas_data; - int max_width, width; - struct device_node *root; + int width; char *os = s; - unsigned long *p; - if ( (root = find_path_device("/rtas")) && - (p = (unsigned long *)get_property(root, - "ibm,display-line-length", - NULL)) ) - max_width = *p; - else - max_width = 0x10; - - if ( (_machine != _MACH_chrp) || !rtas_data ) - return; if ( call_rtas( "display-character", 1, 1, NULL, '\r' ) ) - { - /* assume no display-character RTAS method - use hex display */ - call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex); return; - } width = max_width; while ( *os ) @@ -696,3 +708,17 @@ chrp_progress(char *s, unsigned short hex) call_rtas( "display-character", 1, 1, NULL, ' ' ); } +void __chrp +rtas_indicator_progress(char *s, unsigned short hex) +{ + call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex); +} + +#ifdef CONFIG_BOOTX_TEXT +void +bootx_text_progress(char *s, unsigned short hex) +{ + prom_print(s); + prom_print("\n"); +} +#endif /* CONFIG_BOOTX_TEXT */ diff --git a/arch/ppc/kernel/chrp_time.c b/arch/ppc/kernel/chrp_time.c index 54b4a76bb..67325c685 100644 --- a/arch/ppc/kernel/chrp_time.c +++ b/arch/ppc/kernel/chrp_time.c @@ -15,6 +15,7 @@ #include <linux/string.h> #include <linux/mm.h> #include <linux/interrupt.h> +#include <linux/time.h> #include <linux/timex.h> #include <linux/kernel_stat.h> #include <linux/mc146818rtc.h> @@ -32,18 +33,20 @@ static int nvram_as1 = NVRAM_AS1; static int nvram_as0 = NVRAM_AS0; static int nvram_data = NVRAM_DATA; -void __init chrp_time_init(void) +long __init chrp_time_init(void) { struct device_node *rtcs; int base; rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); if (rtcs == NULL || rtcs->addrs == NULL) - return; + return 0; base = rtcs->addrs[0].address; nvram_as1 = 0; nvram_as0 = base; nvram_data = base + 1; + + return 0; } int __chrp chrp_cmos_clock_read(int addr) @@ -115,28 +118,34 @@ int __chrp chrp_set_rtc_time(unsigned long nowtime) unsigned long __chrp chrp_get_rtc_time(void) { unsigned int year, mon, day, hour, min, sec; - int i; + int uip, i; /* The Linux interpretation of the CMOS clock register contents: * When the Update-In-Progress (UIP) flag goes from 1 to 0, the * RTC registers show the second which has precisely just started. * Let's hope other operating systems interpret the RTC the same way. */ - /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (chrp_cmos_clock_read(RTC_FREQ_SELECT) & RTC_UIP) - break; - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(chrp_cmos_clock_read(RTC_FREQ_SELECT) & RTC_UIP)) - break; - do { /* Isn't this overkill ? UIP above should guarantee consistency */ + + /* Since the UIP flag is set for about 2.2 ms and the clock + * is typically written with a precision of 1 jiffy, trying + * to obtain a precision better than a few milliseconds is + * an illusion. Only consistency is interesting, this also + * allows to use the routine for /dev/rtc without a potential + * 1 second kernel busy loop triggered by any reader of /dev/rtc. + */ + + for ( i = 0; i<1000000; i++) { + uip = chrp_cmos_clock_read(RTC_FREQ_SELECT); sec = chrp_cmos_clock_read(RTC_SECONDS); min = chrp_cmos_clock_read(RTC_MINUTES); hour = chrp_cmos_clock_read(RTC_HOURS); day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH); mon = chrp_cmos_clock_read(RTC_MONTH); year = chrp_cmos_clock_read(RTC_YEAR); - } while (sec != chrp_cmos_clock_read(RTC_SECONDS)); + uip |= chrp_cmos_clock_read(RTC_FREQ_SELECT); + if ((uip & RTC_UIP)==0) break; + } + if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BCD_TO_BIN(sec); @@ -155,8 +164,7 @@ unsigned long __chrp chrp_get_rtc_time(void) void __init chrp_calibrate_decr(void) { struct device_node *cpu; - int *fp, divisor; - unsigned long freq; + unsigned int freq, *fp; if (via_calibrate_decr()) return; @@ -168,15 +176,13 @@ void __init chrp_calibrate_decr(void) freq = 16666000; /* hardcoded default */ cpu = find_type_devices("cpu"); if (cpu != 0) { - fp = (int *) get_property(cpu, "timebase-frequency", NULL); + fp = (unsigned int *) + get_property(cpu, "timebase-frequency", NULL); if (fp != 0) freq = *fp; } - freq *= 30; - divisor = 30; - printk("time_init: decrementer frequency = %lu/%d (%ld MHz)\n", freq, - divisor, (freq/divisor)>>20); - decrementer_count = freq / HZ / divisor; - count_period_num = divisor; - count_period_den = freq / 1000000; + printk("time_init: decrementer frequency = %u.%.6u MHz\n", + freq/1000000, freq%1000000); + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); } diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index d40a54cf1..627cd7a2a 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -30,6 +30,7 @@ #include <linux/errno.h> #include <linux/sys.h> #include <linux/config.h> +#include "mol.h" #undef SHOW_SYSCALLS #undef SHOW_SYSCALLS_TASK @@ -85,7 +86,7 @@ _GLOBAL(DoSyscall) beq- 10f cmpi 0,r0,0x6666 /* Special case for 'sys_rt_sigreturn' */ beq- 16f - lwz r10,TASK_FLAGS(r2) + lwz r10,TASK_PTRACE(r2) andi. r10,r10,PT_TRACESYS bne- 50f cmpli 0,r0,NR_syscalls @@ -241,6 +242,13 @@ _GLOBAL(_switch) /* XXX it would be nice to find a SPRGx for this on 6xx,7xx too */ lwz r9,PGDIR(r4) /* cache the page table root */ tophys(r9,r9) /* convert to phys addr */ +#ifdef CONFIG_8xx_CPU6 + lis r6, cpu6_errata_word@h + ori r6, r6, cpu6_errata_word@l + li r5, 0x3980 + stw r5, 8(r6) + lwz r5, 8(r6) +#endif mtspr M_TWB,r9 /* Update MMU base address */ tlbia SYNC @@ -349,21 +357,18 @@ ret_to_user_hook: beq+ restore li r3,0 addi r4,r1,STACK_FRAME_OVERHEAD + MOL_HOOK_MMU(8,r8) bl do_signal .globl do_signal_ret do_signal_ret: -restore: - lwz r3,_CTR(r1) - lwz r0,_LINK(r1) - mtctr r3 - mtlr r0 +restore: lwz r3,_XER(r1) mtspr XER,r3 - REST_10GPRS(3, r1) - REST_10GPRS(13, r1) - REST_8GPRS(23, r1) - REST_GPR(31, r1) - + REST_10GPRS(9,r1) + REST_10GPRS(19,r1) + REST_2GPRS(29,r1) + REST_GPR(31,r1) + /* make sure we hard disable here, even if rtl is active, to protect * SRR[01] and SPRG2 -- Cort */ @@ -376,12 +381,28 @@ restore: lwz r0,_MSR(r1) andi. r0,r0,MSR_PR beq+ 1f +#ifdef CONFIG_ALTIVEC + mfpvr r8 /* check if we are on a G4 */ + srwi r8,r8,16 + cmpwi r8,PVR_7400@h + bne 2f + lwz r0,THREAD+THREAD_VRSAVE(r2) + mtspr SPRN_VRSAVE,r0 /* if so, restore VRSAVE reg */ +2: +#endif /* CONFIG_ALTIVEC */ addi r0,r1,INT_FRAME_SIZE /* size of frame */ stw r0,THREAD+KSP(r2) /* save kernel stack pointer */ - tophys(r2,r1) - CLR_TOP32(r2) - mtspr SPRG2,r2 /* phys exception stack pointer */ + tophys(r8,r1) + CLR_TOP32(r8) + MOL_HOOK_MMU(9, r4) /* mod. r0,r2-r7, lr, ctr */ + mtspr SPRG2,r8 /* phys exception stack pointer */ 1: + lwz r3,_CTR(r1) + lwz r0,_LINK(r1) + mtctr r3 + mtlr r0 + REST_4GPRS(3, r1) + REST_2GPRS(7, r1) lwz r0,_MSR(r1) FIX_SRR1(r0,r2) mtspr SRR1,r0 diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c index 4b63d5dc0..57599917a 100644 --- a/arch/ppc/kernel/feature.c +++ b/arch/ppc/kernel/feature.c @@ -24,6 +24,8 @@ #include <asm/errno.h> #include <asm/ohare.h> #include <asm/heathrow.h> +#include <asm/keylargo.h> +#include <asm/uninorth.h> #include <asm/io.h> #include <asm/prom.h> #include <asm/feature.h> @@ -34,6 +36,20 @@ #define MAX_FEATURE_OFFSET 0x100 #define FREG(c,r) (&(((c)->reg)[(r)>>2])) +/* Keylargo reg. access. */ +#define KL_FCR(r) (keylargo_base + ((r) >> 2)) +#define KL_IN(r) (in_le32(KL_FCR(r))) +#define KL_OUT(r,v) (out_le32(KL_FCR(r), (v))) +#define KL_BIS(r,v) (KL_OUT((r), KL_IN(r) | (v))) +#define KL_BIC(r,v) (KL_OUT((r), KL_IN(r) & ~(v))) + +/* Uni-N reg. access. Note that Uni-N regs are big endian */ +#define UN_REG(r) (uninorth_base + ((r) >> 2)) +#define UN_IN(r) (in_be32(UN_REG(r))) +#define UN_OUT(r,v) (out_be32(UN_REG(r), (v))) +#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) +#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) + typedef struct feature_bit { int reg; /* reg. offset from mac-io base */ unsigned int polarity; /* 0 = normal, 1 = inverse */ @@ -74,11 +90,45 @@ static fbit feature_bits_ohare_pbook[] = { {0x38,0,0}, /* FEATURE_Airport_reset */ }; -/* Those bits are from a PowerBook. It's possible that desktop machines - * based on heathrow need a different definition or some bits removed +/* Those bits concern heathrow-based desktop machines (Beige G3s). We have removed + * the SCC related bits and init them once. They have proven to occasionally cause + * problems with the desktop units. */ static fbit feature_bits_heathrow[] = { {0x38,0,0}, /* FEATURE_null */ + {0x38,0,0}, /* FEATURE_Serial_reset */ + {0x38,0,0}, /* FEATURE_Serial_enable */ + {0x38,0,0}, /* FEATURE_Serial_IO_A */ + {0x38,0,0}, /* FEATURE_Serial_IO_B */ + {0x38,0,HRW_SWIM_ENABLE}, /* FEATURE_SWIM3_enable */ + {0x38,0,HRW_MESH_ENABLE}, /* FEATURE_MESH_enable */ + {0x38,0,HRW_IDE0_ENABLE}, /* FEATURE_IDE0_enable */ + {0x38,1,HRW_IDE0_RESET_N}, /* FEATURE_IDE0_reset */ + {0x38,0,HRW_IOBUS_ENABLE}, /* FEATURE_IOBUS_enable */ + {0x38,1,0}, /* FEATURE_Mediabay_reset */ + {0x38,1,0}, /* FEATURE_Mediabay_power */ + {0x38,0,0}, /* FEATURE_Mediabay_PCI_enable */ + {0x38,0,HRW_BAY_IDE_ENABLE}, /* FEATURE_IDE1_enable */ + {0x38,1,HRW_IDE1_RESET_N}, /* FEATURE_IDE1_reset */ + {0x38,0,0}, /* FEATURE_Mediabay_floppy_enable */ + {0x38,0,HRW_BMAC_RESET}, /* FEATURE_BMac_reset */ + {0x38,0,HRW_BMAC_IO_ENABLE}, /* FEATURE_BMac_IO_enable */ + {0x38,1,0}, /* FEATURE_Modem_power */ + {0x38,0,HRW_SLOW_SCC_PCLK}, /* FEATURE_Slow_SCC_PCLK */ + {0x38,1,0}, /* FEATURE_Sound_Power */ + {0x38,0,0}, /* FEATURE_Sound_CLK_Enable */ + {0x38,0,0}, /* FEATURE_IDE2_enable */ + {0x38,0,0}, /* FEATURE_IDE2_reset */ + {0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */ + {0x38,0,0}, /* FEATURE_Mediabay_content */ + {0x38,0,0}, /* FEATURE_Airport_reset */ +}; + +/* Those bits concern heathrow-based PowerBooks (wallstreet/mainstreet). + * Heathrow-based desktop macs (Beige G3s) are _not_ handled here + */ +static fbit feature_bits_wallstreet[] = { + {0x38,0,0}, /* FEATURE_null */ {0x38,0,HRW_RESET_SCC}, /* FEATURE_Serial_reset */ {0x38,0,HRW_SCC_ENABLE}, /* FEATURE_Serial_enable */ {0x38,0,HRW_SCCA_IO}, /* FEATURE_Serial_IO_A */ @@ -145,32 +195,32 @@ static fbit feature_bits_paddington[] = { */ static fbit feature_bits_keylargo[] = { {0x38,0,0}, /* FEATURE_null */ - {0x38,0,0}, /* FEATURE_Serial_reset */ - {0x38,0,0x00000054}, /* FEATURE_Serial_enable */ - {0x38,0,0}, /* FEATURE_Serial_IO_A */ - {0x38,0,0}, /* FEATURE_Serial_IO_B */ + {0x38,0,KL0_SCC_RESET}, /* FEATURE_Serial_reset */ + {0x38,0,KL0_SERIAL_ENABLE}, /* FEATURE_Serial_enable */ + {0x38,0,KL0_SCC_A_INTF_ENABLE}, /* FEATURE_Serial_IO_A */ + {0x38,0,KL0_SCC_B_INTF_ENABLE}, /* FEATURE_Serial_IO_B */ {0x38,0,0}, /* FEATURE_SWIM3_enable */ {0x38,0,0}, /* FEATURE_MESH_enable */ {0x3c,0,0}, /* FEATURE_IDE0_enable */ - {0x3c,1,0x01000000}, /* FEATURE_IDE0_reset */ + {0x3c,1,KL1_EIDE0_RESET_N}, /* FEATURE_IDE0_reset */ {0x38,0,0}, /* FEATURE_IOBUS_enable */ {0x34,1,0x00000200}, /* FEATURE_Mediabay_reset */ {0x34,1,0x00000400}, /* FEATURE_Mediabay_power */ {0x38,0,0}, /* FEATURE_Mediabay_PCI_enable */ {0x3c,0,0x0}, /* FEATURE_IDE1_enable */ - {0x3c,1,0x08000000}, /* FEATURE_IDE1_reset */ + {0x3c,1,KL1_EIDE1_RESET_N}, /* FEATURE_IDE1_reset */ {0x38,0,0}, /* FEATURE_Mediabay_floppy_enable */ {0x38,0,0}, /* FEATURE_BMac_reset */ {0x38,0,0}, /* FEATURE_BMac_IO_enable */ - {0x40,1,0x02000000}, /* FEATURE_Modem_power */ + {0x40,1,KL2_MODEM_POWER_N}, /* FEATURE_Modem_power */ {0x38,0,0}, /* FEATURE_Slow_SCC_PCLK */ {0x38,0,0}, /* FEATURE_Sound_Power */ {0x38,0,0}, /* FEATURE_Sound_CLK_Enable */ {0x38,0,0}, /* FEATURE_IDE2_enable */ - {0x3c,1,0x40000000}, /* FEATURE_IDE2_reset */ - {0x34,0,0x00001000}, /* FEATURE_Mediabay_IDE_switch */ + {0x3c,1,KL1_UIDE_RESET_N}, /* FEATURE_IDE2_reset */ + {0x34,0,KL_MBCR_MBDEV_ENABLE}, /* FEATURE_Mediabay_IDE_switch */ {0x34,0,0x00000100}, /* FEATURE_Mediabay_content */ - {0x40,1,0x08000000}, /* FEATURE_Airport_reset */ + {0x40,1,KL2_AIRPORT_RESET_N}, /* FEATURE_Airport_reset */ }; /* definition of a feature controller object */ @@ -190,6 +240,8 @@ feature_lookup_controller(struct device_node *device); static void heathrow_prepare_for_sleep(struct feature_controller* ctrler); static void heathrow_wakeup(struct feature_controller* ctrler); +static void keylargo_init(void); +static void uninorth_init(void); static void core99_prepare_for_sleep(struct feature_controller* ctrler); static void core99_wake_up(struct feature_controller* ctrler); @@ -228,8 +280,15 @@ feature_init(void) } } else if (device_is_compatible(np, "paddington")) { feature_add_controller(np, feature_bits_paddington); + } else if (machine_is_compatible("AAPL,PowerBook1998")) { + feature_add_controller(np, feature_bits_wallstreet); } else { - feature_add_controller(np, feature_bits_heathrow); + struct feature_controller* ctrler = + feature_add_controller(np, feature_bits_heathrow); + if (ctrler) + out_le32(FREG(ctrler,HEATHROW_FEATURE_REG), + in_le32(FREG(ctrler,HEATHROW_FEATURE_REG)) | HRW_DEFAULTS); + } np = np->next; } @@ -249,14 +308,17 @@ feature_init(void) np = find_devices("uni-n"); if (np && np->n_addrs > 0) { uninorth_base = ioremap(np->addrs[0].address, 0x1000); - rev = (u32 *)get_property(np, "device-rev", NULL); - if (rev) - uninorth_rev = *rev; + uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); } if (uninorth_base && keylargo_base) printk("Uni-N revision: %d, KeyLargo revision: %d\n", uninorth_rev, keylargo_rev); + if (uninorth_base) + uninorth_init(); + if (keylargo_base) + keylargo_init(); + if (controller_count) printk(KERN_INFO "Registered %d feature controller(s)\n", controller_count); @@ -440,14 +502,21 @@ feature_set_gmac_power(struct device_node* device, int power) if (!uninorth_base) return; if (power) - out_le32(uninorth_base + 0x20/4, - in_le32(uninorth_base + 0x20/4) | 0x02000000); + UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); else - out_le32(uninorth_base + 0x20/4, - in_le32(uninorth_base + 0x20/4) & ~0x02000000); + UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); udelay(20); } +void +feature_set_gmac_phy_reset(struct device_node* device, int reset) +{ + if (!keylargo_base) + return; + out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET), reset); + (void)in_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET)); +} + /* Pass the node of the correct controller, please */ void feature_set_usb_power(struct device_node* device, int power) @@ -460,6 +529,53 @@ feature_set_firewire_power(struct device_node* device, int power) { } +/* Initialize the Core99 UniNorth host bridge and memory controller + */ +static void +uninorth_init(void) +{ + struct device_node* gmac; + unsigned long actrl; + + /* Set the arbitrer QAck delay according to what Apple does + */ + actrl = in_be32(UN_REG(UNI_N_ARB_CTRL)) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; + actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : UNI_N_ARB_CTRL_QACK_DELAY) + << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; + UN_OUT(UNI_N_ARB_CTRL, actrl); + + /* + * Turns OFF the gmac clock. The gmac driver will turn + * it back ON when the interface is enabled. This save + * power on portables. + * + * Note: We could also try to turn OFF the PHY. Since this + * has to be done by both the gmac driver and this code, + * I'll probably end-up moving some of this out of the + * modular gmac driver into a non-modular stub containing + * some basic PHY management and power management stuffs + */ + gmac = find_devices("ethernet"); + + while(gmac) { + if (device_is_compatible(gmac, "gmac")) + break; + gmac = gmac->next; + } + if (gmac) + feature_set_gmac_power(gmac, 0); +} + +/* Initialize the Core99 KeyLargo ASIC. Currently, we just make sure + * OpenPIC is enabled + */ +static void +keylargo_init(void) +{ + KL_BIS(KEYLARGO_FCR2, KL2_MPIC_ENABLE); +} + +#ifdef CONFIG_PMAC_PBOOK void feature_prepare_for_sleep(void) { @@ -506,27 +622,28 @@ feature_wake_up(void) } } -static u32 save_fcr0; -//static u32 save_fcr1; -//static u32 save_fcr2; +static u32 save_fcr[5]; static u32 save_mbcr; static void heathrow_prepare_for_sleep(struct feature_controller* ctrler) { save_mbcr = in_le32(FREG(ctrler, 0x34)); - save_fcr0 = in_le32(FREG(ctrler, 0x38)); + save_fcr[0] = in_le32(FREG(ctrler, 0x38)); + save_fcr[1] = in_le32(FREG(ctrler, 0x3c)); - out_le32(FREG(ctrler, 0x38), save_fcr0 & ~HRW_IOBUS_ENABLE); + out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE); } static void heathrow_wakeup(struct feature_controller* ctrler) { - out_le32(FREG(ctrler, 0x38), save_fcr0); + out_le32(FREG(ctrler, 0x38), save_fcr[0]); + out_le32(FREG(ctrler, 0x3c), save_fcr[1]); out_le32(FREG(ctrler, 0x34), save_mbcr); - - out_le32(FREG(ctrler, 0x38), save_fcr0 | HRW_IOBUS_ENABLE); + mdelay(1); + out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE); + mdelay(1); } static void @@ -540,4 +657,4 @@ core99_wake_up(struct feature_controller* ctrler) { /* Not yet implemented */ } - +#endif /* CONFIG_PMAC_PBOOK */ diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c index 7be4675c2..a01ff9eca 100644 --- a/arch/ppc/kernel/gemini_setup.c +++ b/arch/ppc/kernel/gemini_setup.c @@ -15,6 +15,7 @@ #include <linux/errno.h> #include <linux/reboot.h> #include <linux/pci.h> +#include <linux/time.h> #include <linux/kdev_t.h> #include <linux/types.h> #include <linux/major.h> @@ -335,7 +336,7 @@ void __init gemini_init_IRQ(void) #define gemini_rtc_write(val,x) (writeb((val),(GEMINI_RTC+(x)))) /* ensure that the RTC is up and running */ -void __init gemini_time_init(void) +long __init gemini_time_init(void) { unsigned char reg; @@ -346,6 +347,7 @@ void __init gemini_time_init(void) gemini_rtc_write((reg & ~(M48T35_RTC_STOPPED)), M48T35_RTC_CONTROL); gemini_rtc_write((reg | M48T35_RTC_SET), M48T35_RTC_CONTROL); } + return 0; } #undef DEBUG_RTC diff --git a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S index be86a1503..1129dd40e 100644 --- a/arch/ppc/kernel/hashtable.S +++ b/arch/ppc/kernel/hashtable.S @@ -27,6 +27,7 @@ #include <asm/processor.h> #include <asm/page.h> #include <linux/config.h> +#include "mol.h" /* * Load a PTE into the hash table, if possible. @@ -593,6 +594,11 @@ _GLOBAL(flush_hash_segments) * flush_hash_page(unsigned context, unsigned long va) */ _GLOBAL(flush_hash_page) +#ifdef CONFIG_MOL + mflr r10 + MOL_HOOK_MMU(10, r6) + mtlr r10 +#endif lis r6,Hash@ha lwz r6,Hash@l(r6) /* hash table base */ cmpwi 0,r6,0 /* hash table in use? */ diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 067581f5d..5d26e2917 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -31,6 +31,7 @@ #include <asm/page.h> #include <linux/config.h> #include <asm/mmu.h> +#include "mol.h" #ifdef CONFIG_APUS #include <asm/amigappc.h> @@ -78,7 +79,7 @@ CACHELINE_WORDS = 32 mtspr DBAT##n##L,RB; \ 1: #endif /* CONFIG_PPC64BRIDGE */ - + .text .globl _stext _stext: @@ -162,8 +163,8 @@ __start: /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains * the physical address we are running at, returned by prom_init() */ -__after_prom_start: bl mmu_off +__after_mmu_off: bl clear_bats bl flush_tlbs #endif @@ -202,15 +203,7 @@ __after_prom_start: mr r26,r3 addis r4,r3,KERNELBASE@h /* current address of _start */ cmpwi 0,r4,0 /* are we already running at 0? */ - beq 2f /* assume it's OK if so */ - li r3,0 - mfmsr r0 - andi. r0,r0,MSR_DR /* MMU enabled? */ - beq relocate_kernel - lis r3,KERNELBASE@h /* if so, are we */ - cmpw 0,r4,r3 /* already running at KERNELBASE? */ bne relocate_kernel -2: #endif /* CONFIG_APUS */ /* * we now have the 1st 16M of ram mapped with the bats. @@ -300,6 +293,17 @@ label: \ .long hdlr; \ .long ret_from_except +#define STD_MOL_EXCEPTION(n, label, hdlr, hook) \ + . = n; \ +label: \ + EXCEPTION_PROLOG; \ + MOL_HOOK(hook); \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + li r20,MSR_KERNEL; \ + bl transfer_to_handler; \ + .long hdlr; \ + .long ret_from_except + /* System reset */ #ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */ #ifdef CONFIG_GEMINI @@ -324,6 +328,7 @@ DataAccessCont: DataAccess: EXCEPTION_PROLOG #endif /* CONFIG_PPC64BRIDGE */ + MOL_HOOK(0) mfspr r20,DSISR andis. r0,r20,0xa470 /* weird error? */ bne 1f /* if not, try to put a PTE */ @@ -366,6 +371,7 @@ InstructionAccessCont: InstructionAccess: EXCEPTION_PROLOG #endif /* CONFIG_PPC64BRIDGE */ + MOL_HOOK(1) andis. r0,r23,0x4000 /* no pte found? */ beq 1f /* if so, try to put a PTE */ mr r3,r22 /* into the hash table */ @@ -430,6 +436,7 @@ Alignment: . = 0x700 ProgramCheck: EXCEPTION_PROLOG + MOL_HOOK(2) addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ @@ -441,6 +448,7 @@ ProgramCheck: . = 0x800 FPUnavailable: EXCEPTION_PROLOG + MOL_HOOK_RESTORE(3) bne load_up_fpu /* if from user, just load it up */ li r20,MSR_KERNEL bl transfer_to_handler /* if from kernel, take a trap */ @@ -450,6 +458,7 @@ FPUnavailable: . = 0x900 Decrementer: EXCEPTION_PROLOG + MOL_HOOK(4) addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL bl transfer_to_handler @@ -473,12 +482,9 @@ SystemCall: .long ret_from_except /* Single step - not used on 601 */ - STD_EXCEPTION(0xd00, SingleStep, SingleStepException) - + STD_MOL_EXCEPTION(0xd00, SingleStep, SingleStepException, 5) STD_EXCEPTION(0xe00, Trap_0e, UnknownException) -#ifndef CONFIG_ALTIVEC - STD_EXCEPTION(0xf00, Trap_0f, UnknownException) -#else + /* * The Altivec unavailable trap is at 0x0f20. Foo. * We effectively remap it to 0x3000. @@ -493,15 +499,20 @@ trap_0f_cont: .long ret_from_except . = 0xf20 +#ifdef CONFIG_ALTIVEC b AltiVecUnavailable -#endif /* CONFIG_ALTIVEC */ - +#endif +Trap_0f: + EXCEPTION_PROLOG + b trap_0f_cont + /* * Handle TLB miss for instruction on 603/603e. * Note: we get an alternate set of r0 - r3 to use automatically. */ . = 0x1000 InstructionTLBMiss: + MOL_HOOK_TLBMISS( 14 ) /* * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) @@ -568,6 +579,7 @@ InstructionAddressInvalid: */ . = 0x1100 DataLoadTLBMiss: + MOL_HOOK_TLBMISS( 15 ) /* * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) @@ -633,6 +645,7 @@ DataAddressInvalid: */ . = 0x1200 DataStoreTLBMiss: + MOL_HOOK_TLBMISS( 16 ) /* * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) @@ -674,7 +687,7 @@ DataStoreTLBMiss: mtcrf 0x80,r3 rfi - STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint) + STD_MOL_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, 11) STD_EXCEPTION(0x1400, SMI, SMIException) STD_EXCEPTION(0x1500, Trap_15, UnknownException) STD_EXCEPTION(0x1600, Trap_16, UnknownException) @@ -687,7 +700,7 @@ DataStoreTLBMiss: STD_EXCEPTION(0x1d00, Trap_1d, UnknownException) STD_EXCEPTION(0x1e00, Trap_1e, UnknownException) STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) - STD_EXCEPTION(0x2000, RunMode, RunModeException) + STD_MOL_EXCEPTION(0x2000, RunMode, RunModeException, 5) STD_EXCEPTION(0x2100, Trap_21, UnknownException) STD_EXCEPTION(0x2200, Trap_22, UnknownException) STD_EXCEPTION(0x2300, Trap_23, UnknownException) @@ -709,16 +722,12 @@ DataStoreTLBMiss: #ifdef CONFIG_ALTIVEC AltiVecUnavailable: EXCEPTION_PROLOG + MOL_HOOK_RESTORE(12) bne load_up_altivec /* if from user, just load it up */ li r20,MSR_KERNEL bl transfer_to_handler /* if from kernel, take a trap */ .long KernelAltiVec .long ret_from_except - -/* here are the bits of trap 0xf00 which got displaced */ -Trap_0f: - EXCEPTION_PROLOG - b trap_0f_cont #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_PPC64BRIDGE @@ -753,6 +762,14 @@ transfer_to_handler: beq 2f addi r24,r1,STACK_FRAME_OVERHEAD stw r24,PT_REGS(r23) +#ifdef CONFIG_ALTIVEC + mfpvr r24 /* check if we are on a G4 */ + srwi r24,r24,16 + cmpwi r24,PVR_7400@h + bne 2f + mfspr r22,SPRN_VRSAVE /* if so, save vrsave register value */ + stw r22,THREAD_VRSAVE(r23) +#endif /* CONFIG_ALTIVEC */ 2: addi r2,r23,-THREAD /* set r2 to current */ tovirt(r2,r2) mflr r23 @@ -771,6 +788,7 @@ transfer_to_handler: lwz r24,0(r23) /* virtual address of handler */ lwz r23,4(r23) /* where to go when done */ FIX_SRR1(r20,r22) + MOL_HOOK(6) mtspr SRR0,r24 mtspr SRR1,r20 mtlr r23 @@ -981,6 +999,11 @@ KernelAltiVec: .globl giveup_altivec giveup_altivec: +#ifdef CONFIG_MOL + mflr r4 + MOL_HOOK_MMU(13, r5) + mtlr r4 +#endif mfmsr r5 oris r5,r5,MSR_VEC@h SYNC @@ -1017,6 +1040,11 @@ giveup_altivec: */ .globl giveup_fpu giveup_fpu: +#ifdef CONFIG_MOL + mflr r4 + MOL_HOOK_MMU(7, r5) + mtlr r4 +#endif mfmsr r5 ori r5,r5,MSR_FP SYNC @@ -1048,19 +1076,10 @@ giveup_fpu: * the kernel image to physical address 0. */ relocate_kernel: -#if 0 /* Is this still needed ? I don't think so. It breaks new - * boot-with-mmu-off stuff - */ - lis r9,0x426f /* if booted from BootX, don't */ - addi r9,r9,0x6f58 /* translate source addr */ - cmpw r31,r9 /* (we have to on chrp) */ - beq 7f - rlwinm r4,r4,0,8,31 /* translate source address */ - add r4,r4,r3 /* to region mapped with BATs */ -#endif -7: addis r9,r26,klimit@ha /* fetch klimit */ + addis r9,r26,klimit@ha /* fetch klimit */ lwz r25,klimit@l(r9) addis r25,r25,-KERNELBASE@h + li r3,0 /* Destination base address */ li r6,0 /* Destination offset */ li r5,0x4000 /* # bytes of memory to copy */ bl copy_and_flush /* copy the first 0x4000 bytes */ @@ -1307,7 +1326,7 @@ enable_caches: mfspr r9,PVR rlwinm r9,r9,16,16,31 cmpi 0,r9,1 - beq 4f /* not needed for 601 */ + beq 6f /* not needed for 601 */ mfspr r11,HID0 andi. r0,r11,HID0_DCE ori r11,r11,HID0_ICE|HID0_DCE @@ -1323,26 +1342,33 @@ enable_caches: isync cmpi 0,r9,4 /* check for 604 */ cmpi 1,r9,9 /* or 604e */ - cmpi 2,r9,10 /* or mach5 */ + cmpi 2,r9,10 /* or mach5 / 604r */ cmpi 3,r9,8 /* check for 750 (G3) */ cmpi 4,r9,12 /* or 7400 (G4) */ cror 2,2,6 cror 2,2,10 bne 4f - ori r11,r11,HID0_SIED|HID0_BHTE /* for 604[e], enable */ + ori r11,r11,HID0_SIED|HID0_BHTE /* for 604[e|r], enable */ bne 2,5f - ori r11,r11,HID0_BTCD + ori r11,r11,HID0_BTCD /* superscalar exec & br history tbl */ b 5f 4: cror 14,14,18 bne 3,6f - /* We should add ABE here if we want to use Store Gathering - * and other nifty bridge features + /* for G3/G4: + * enable Store Gathering (SGE), Address Brodcast (ABE), + * Branch History Table (BHTE), Branch Target ICache (BTIC) */ - ori r11,r11,HID0_SGE|HID0_BHTE|HID0_BTIC /* for g3/g4, enable */ + ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC + oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ + li r3,HID0_SPD + andc r11,r11,r3 /* clear SPD: enable speculative */ li r3,0 - mtspr ICTC,r3 -5: mtspr HID0,r11 /* superscalar exec & br history tbl */ + mtspr ICTC,r3 /* Instruction Cache Throttling off */ +5: isync + mtspr HID0,r11 + sync + isync 6: blr /* @@ -1548,12 +1574,11 @@ flush_tlbs: blr mmu_off: - addi r4, r3, __after_prom_start - _start + addi r4, r3, __after_mmu_off - _start mfmsr r3 andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */ beqlr - ori r3,r3,MSR_DR|MSR_IR - xori r3,r3,MSR_DR|MSR_IR + andc r3,r3,r0 mtspr SRR0,r4 mtspr SRR1,r3 sync @@ -1617,23 +1642,19 @@ setup_disp_bat: mflr r8 bl reloc_offset mtlr r8 - lis r8, disp_BATL@h - ori r8, r8, disp_BATL@l - add r8, r3, r8 - lwz r8, 0(r8) - lis r11, disp_BATU@h - ori r11, r11, disp_BATU@l - add r11, r3, r11 - lwz r11, 0(r11) - mtspr IBAT3L,r8 - mtspr IBAT3U,r11 + addis r8,r3,disp_BAT@ha + addi r8,r8,disp_BAT@l + lwz r11,0(r8) + lwz r8,4(r8) mfspr r9,PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ cmpi 0,r9,1 beq 1f mtspr DBAT3L,r8 mtspr DBAT3U,r11 -1: + blr +1: mtspr IBAT3L,r8 + mtspr IBAT3U,r11 blr #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ @@ -1649,18 +1670,43 @@ setup_disp_bat: */ .globl m8260_gorom m8260_gorom: - li r5,MSR_KERNEL & ~(MSR_IR|MSR_DR) - lis r6,2f@h - addis r6,r6,-KERNELBASE@h - ori r6,r6,2f@l - mtspr SRR0,r6 - mtspr SRR1,r5 - rfi + mfmsr r0 + rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ + sync + mtmsr r0 + sync + mfspr r11, HID0 + lis r10, 0 + ori r10,r10,HID0_ICE|HID0_DCE + andc r11, r11, r10 + mtspr HID0, r11 + isync + li r5, MSR_ + lis r6,2f@h + addis r6,r6,-KERNELBASE@h + ori r6,r6,2f@l + mtspr SRR0,r6 + mtspr SRR1,r5 + isync + sync + rfi 2: - mtlr r4 - blr + mtlr r4 + blr +#endif + +#ifdef CONFIG_MOL +/* + * Mac-on-linux hook_table. Don't put this in the data section - + * the base address must be within the first 32KB of RAM. + */ + .globl mol_interface +mol_interface: + .long MOL_INTERFACE_VERSION + .fill 24,4,0 /* space for 24 hooks */ #endif + /* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the data segment, diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index a35f6e2a1..40579ce63 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S @@ -874,6 +874,13 @@ start_here: lis r6, swapper_pg_dir@h tophys(r6,r6) ori r6, r6, swapper_pg_dir@l +#ifdef CONFIG_8xx_CPU6 + lis r4, cpu6_errata_word@h + ori r4, r4, cpu6_errata_word@l + li r3, 0x3980 + stw r3, 12(r4) + lwz r3, 12(r4) +#endif mtspr M_TWB, r6 lis r4,2f@h ori r4,r4,2f@l @@ -940,9 +947,23 @@ start_here: * ASID compare register with the new "context". */ _GLOBAL(set_context) +#ifdef CONFIG_8xx_CPU6 + lis r6, cpu6_errata_word@h + ori r6, r6, cpu6_errata_word@l + tophys (r4, r4) + li r7, 0x3980 + stw r7, 12(r6) + lwz r7, 12(r6) + mtspr M_TWB, r4 /* Update MMU base address */ + li r7, 0x3380 + stw r7, 12(r6) + lwz r7, 12(r6) + mtspr M_CASID, r3 /* Update context */ +#else mtspr M_CASID,r3 /* Update context */ tophys (r4, r4) mtspr M_TWB, r4 /* and pgd */ +#endif tlbia SYNC blr @@ -966,6 +987,24 @@ m8xx_gorom: 2: mtlr r4 blr + +#ifdef CONFIG_8xx_CPU6 +/* It's here because it is unique to the 8xx. + * It is important we get called with interrupts disabled. I used to + * do that, but it appears that all code that calls this already had + * interrupt disabled. + */ + .globl set_dec_cpu6 +set_dec_cpu6: + lis r7, cpu6_errata_word@h + ori r7, r7, cpu6_errata_word@l + li r4, 0x2c00 + stw r4, 8(r7) + lwz r4, 8(r7) + mtspr 22, r3 /* Update Decrementer */ + SYNC + blr +#endif /* * We put a few things here that have to be page-aligned. @@ -991,3 +1030,9 @@ swapper_pg_dir: cmd_line: .space 512 +#ifdef CONFIG_8xx_CPU6 + .globl cpu6_errata_word +cpu6_errata_word: + .space 16 +#endif + diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index d29f7bd20..a363a0e34 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -286,6 +286,7 @@ void power_save(void) case 6: /* 603e */ case 7: /* 603ev */ case 8: /* 750 */ + case 12: /* 7400 */ save_flags(msr); __cli(); if (!current->need_resched) { diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 64ef4b4dc..eef89f352 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -137,17 +137,21 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) if (!handler) { /* Free */ - for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) - { - /* Found it - now free it */ - save_flags(flags); - cli(); - *p = action->next; - restore_flags(flags); - irq_kfree(action); - return 0; - } - return -ENOENT; + p = &irq_desc[irq].action; + while ((action = *p) != NULL && action->dev_id != dev_id) + p = &action->next; + if (action == NULL) + return -ENOENT; + + /* Found it - now free it */ + save_flags(flags); + cli(); + *p = action->next; + if (irq_desc[irq].action == NULL) + disable_irq(irq); + restore_flags(flags); + irq_kfree(action); + return 0; } action = (struct irqaction *) @@ -300,7 +304,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) } } -asmlinkage int do_IRQ(struct pt_regs *regs, int isfake) +int do_IRQ(struct pt_regs *regs, int isfake) { int cpu = smp_processor_id(); int irq; diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c index 891b0ca44..6e006a867 100644 --- a/arch/ppc/kernel/m8260_setup.c +++ b/arch/ppc/kernel/m8260_setup.c @@ -112,11 +112,10 @@ void __init m8260_calibrate_decr(void) bd_t *binfo = (bd_t *)__res; int freq, divisor; - freq = (binfo->bi_intfreq * 1000000); - divisor = 16; - decrementer_count = freq / HZ / divisor; - count_period_num = divisor; - count_period_den = freq / 1000000; + freq = (binfo->bi_busfreq * 1000000); + divisor = 4; + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); } /* The 8260 has an internal 1-second timer update register that @@ -143,8 +142,20 @@ void m8260_restart(char *cmd) { extern void m8260_gorom(bd_t *bi, uint addr); + uint startaddr; - m8260_gorom(NULL, 0xff000100); + /* Most boot roms have a warmstart as the second instruction + * of the reset vector. If that doesn't work for you, change this + * or the reboot program to send a proper address. + */ + startaddr = 0xff000104; + + if (cmd != NULL) { + if (!strncmp(cmd, "startaddr=", 10)) + startaddr = simple_strtoul(&cmd[10], NULL, 0); + } + + m8260_gorom((uint)__pa(__res), startaddr); } void diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c index a00a8c452..7dc408a13 100644 --- a/arch/ppc/kernel/m8xx_setup.c +++ b/arch/ppc/kernel/m8xx_setup.c @@ -135,6 +135,13 @@ abort(void) machine_restart(NULL); } +/* A place holder for time base interrupts, if they are ever enabled. +*/ +void timebase_interrupt(int irq, void * dev, struct pt_regs * regs) +{ + printk("timebase_interrupt()\n"); +} + /* The decrementer counts at the system (internal) clock frequency divided by * sixteen, or external oscillator divided by four. We force the processor * to use system clock divided by sixteen. @@ -160,35 +167,14 @@ void __init m8xx_calibrate_decr(void) freq = fp*60; /* try to make freq/1e6 an integer */ divisor = 60; printk("time_init: decrementer frequency = %d/%d\n", freq, divisor); - decrementer_count = freq / HZ / divisor; - count_period_num = divisor; - count_period_den = freq / 1000000; -} - -/* A place holder for time base interrupts, if they are ever enabled. -*/ -void timebase_interrupt(int irq, void * dev, struct pt_regs * regs) -{ - printk("timebase_interrupt()\n"); -} - -/* The RTC on the MPC8xx is an internal register. - * We want to protect this during power down, so we need to unlock, - * modify, and re-lock. - */ -static int -m8xx_set_rtc_time(unsigned long time) -{ - ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY; - ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time; - ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY; - return(0); -} - -unsigned long __init -m8xx_get_rtc_time(void) -{ - /* First, unlock all of the registers we are going to modify. + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000); + + /* Perform some more timer/timebase initialization. This used + * to be done elsewhere, but other changes caused it to get + * called more than once....that is a bad thing. + * + * First, unlock all of the registers we are going to modify. * To protect them from corruption during power down, registers * that are maintained by keep alive power are "locked". To * modify these registers we have to write the key value to @@ -219,9 +205,27 @@ m8xx_get_rtc_time(void) ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_tbscr = ((mk_int_int_mask(DEC_INTERRUPT) << 8) | (TBSCR_TBF | TBSCR_TBE)); + if (request_8xxirq(DEC_INTERRUPT, timebase_interrupt, 0, "tbint", NULL) != 0) panic("Could not allocate timer IRQ!"); +} +/* The RTC on the MPC8xx is an internal register. + * We want to protect this during power down, so we need to unlock, + * modify, and re-lock. + */ +static int +m8xx_set_rtc_time(unsigned long time) +{ + ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY; + ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time; + ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY; + return(0); +} + +unsigned long __init +m8xx_get_rtc_time(void) +{ /* Get time from the RTC. */ return((unsigned long)(((immap_t *)IMAP_ADDR)->im_sit.sit_rtc)); diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 081dda7f3..e3826293b 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -24,12 +24,15 @@ #if defined(CONFIG_4xx) || defined(CONFIG_8xx) #define CACHE_LINE_SIZE 16 #define LG_CACHE_LINE_SIZE 4 +#define MAX_COPY_PREFETCH 1 #elif !defined(CONFIG_PPC64BRIDGE) #define CACHE_LINE_SIZE 32 #define LG_CACHE_LINE_SIZE 5 +#define MAX_COPY_PREFETCH 4 #else #define CACHE_LINE_SIZE 128 #define LG_CACHE_LINE_SIZE 7 +#define MAX_COPY_PREFETCH 1 #endif /* CONFIG_4xx || CONFIG_8xx */ .text @@ -339,7 +342,15 @@ _GLOBAL(__flush_icache_page) _GLOBAL(clear_page) li r0,4096/CACHE_LINE_SIZE mtctr r0 +#ifdef CONFIG_8xx + li r4, 0 +1: stw r4, 0(r3) + stw r4, 4(r3) + stw r4, 8(r3) + stw r4, 12(r3) +#else 1: dcbz 0,r3 +#endif addi r3,r3,CACHE_LINE_SIZE bdnz 1b blr @@ -361,12 +372,31 @@ _GLOBAL(clear_page) stwu r9,16(r3) _GLOBAL(copy_page) - li r0,4096/CACHE_LINE_SIZE - mtctr r0 addi r3,r3,-4 addi r4,r4,-4 li r5,4 -1: dcbz r5,r3 + +#ifndef CONFIG_8xx +#if MAX_COPY_PREFETCH > 1 + li r0,MAX_COPY_PREFETCH + li r11,4 + mtctr r0 +11: dcbt r11,r4 + addi r11,r11,CACHE_LINE_SIZE + bdnz 11b +#else /* MAX_COPY_PREFETCH == 1 */ + dcbt r5,r4 + li r11,CACHE_LINE_SIZE+4 +#endif /* MAX_COPY_PREFETCH */ +#endif /* CONFIG_8xx */ + + li r0,4096/CACHE_LINE_SIZE + mtctr r0 +1: +#ifndef CONFIG_8xx + dcbt r11,r4 + dcbz r5,r3 +#endif COPY_16_BYTES #if CACHE_LINE_SIZE >= 32 COPY_16_BYTES @@ -484,7 +514,7 @@ _GLOBAL(atomic_dec_and_test) stwcx. r5,0,r3 /* Update with new value */ bne- 10b /* Retry if "reservation" (i.e. lock) lost */ cntlzw r3,r5 - srwi r3,r3,5 + srwi r3,r3,5 blr #endif /* 0 */ _GLOBAL(atomic_clear_mask) @@ -629,48 +659,59 @@ _GLOBAL(_outsl_ns) blr /* - * Extended precision shifts + * Extended precision shifts. + * + * Updated to be valid for shift counts from 0 to 63 inclusive. + * -- Gabriel * * R3/R4 has 64 bit value * R5 has shift count * result in R3/R4 * - * ashrdi3: XXXYYY/ZZZAAA -> SSSXXX/YYYZZZ - * ashldi3: XXXYYY/ZZZAAA -> YYYZZZ/AAA000 - * lshrdi3: XXXYYY/ZZZAAA -> 000XXX/YYYZZZ + * ashrdi3: arithmetic right shift (sign propagation) + * lshrdi3: logical right shift + * ashldi3: left shift */ _GLOBAL(__ashrdi3) - li r6,32 - sub r6,r6,r5 - slw r7,r3,r6 /* isolate YYY */ - srw r4,r4,r5 /* isolate ZZZ */ - or r4,r4,r7 /* YYYZZZ */ - sraw r3,r3,r5 /* SSSXXX */ + subfic r6,r5,32 + srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count + addi r7,r5,32 # could be xori, or addi with -32 + slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count) + rlwinm r8,r7,0,32 # t3 = (count < 32) ? 32 : 0 + sraw r7,r3,r7 # t2 = MSW >> (count-32) + or r4,r4,r6 # LSW |= t1 + slw r7,r7,r8 # t2 = (count < 32) ? 0 : t2 + sraw r3,r3,r5 # MSW = MSW >> count + or r4,r4,r7 # LSW |= t2 blr _GLOBAL(__ashldi3) - li r6,32 - sub r6,r6,r5 - srw r7,r4,r6 /* isolate ZZZ */ - slw r4,r4,r5 /* AAA000 */ - slw r3,r3,r5 /* YYY--- */ - or r3,r3,r7 /* YYYZZZ */ + subfic r6,r5,32 + slw r3,r3,r5 # MSW = count > 31 ? 0 : MSW << count + addi r7,r5,32 # could be xori, or addi with -32 + srw r6,r4,r6 # t1 = count > 31 ? 0 : LSW >> (32-count) + slw r7,r4,r7 # t2 = count < 32 ? 0 : LSW << (count-32) + or r3,r3,r6 # MSW |= t1 + slw r4,r4,r5 # LSW = LSW << count + or r3,r3,r7 # MSW |= t2 blr _GLOBAL(__lshrdi3) - li r6,32 - sub r6,r6,r5 - slw r7,r3,r6 /* isolate YYY */ - srw r4,r4,r5 /* isolate ZZZ */ - or r4,r4,r7 /* YYYZZZ */ - srw r3,r3,r5 /* 000XXX */ + subfic r6,r5,32 + srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count + addi r7,r5,32 # could be xori, or addi with -32 + slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count) + srw r7,r3,r7 # t2 = count < 32 ? 0 : MSW >> (count-32) + or r4,r4,r6 # LSW |= t1 + srw r3,r3,r5 # MSW = MSW >> count + or r4,r4,r7 # LSW |= t2 blr _GLOBAL(abs) - cmpi 0,r3,0 - bge 10f - neg r3,r3 -10: blr + srawi r4,r3,31 + xor r3,r3,r4 + sub r3,r3,r4 + blr _GLOBAL(_get_SP) mr r3,r1 /* Close enough */ @@ -1217,6 +1258,6 @@ _GLOBAL(sys_call_table) .long sys_pciconfig_iobase /* 200 */ .long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */ .long sys_getdents64 /* 202 */ - .rept NR_syscalls-201 + .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall .endr diff --git a/arch/ppc/kernel/mol.h b/arch/ppc/kernel/mol.h new file mode 100644 index 000000000..6105867e1 --- /dev/null +++ b/arch/ppc/kernel/mol.h @@ -0,0 +1,68 @@ +/* + * arch/ppc/kernel/mol.h + * + * <mol.h> + * + * Mac-on-Linux hook macros + * <http://www.maconlinux.org> + * + * Copyright (C) 2000 Samuel Rydh (samuel@ibrium.se) + * + * 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 + * + */ + +#ifndef _PPC_KERNEL_MOL +#define _PPC_KERNEL_MOL + +#include <linux/config.h> + +#ifdef CONFIG_MOL +#define MOL_INTERFACE_VERSION 3 + +#define MOL_HOOK(hook_num) \ + lwz r0,(mol_interface + 4 * hook_num + 4)@l(0); \ + cmpwi cr1,r0,0; \ + beq+ cr1,777f; \ + mtctr r0; \ + bctrl; \ +777: lwz r0,GPR0(r21) + +#define MOL_HOOK_RESTORE(hook_num) \ + mfcr r2; \ + MOL_HOOK(hook_num); \ + mtcrf 0x80,r2; \ + lwz r2,_CTR(r21); \ + mtctr r2; \ + lwz r2,GPR2(r21) + +#define MOL_HOOK_MMU(hook_num, scr) \ + lis scr,(mol_interface + 4 * hook_num + 4)@ha; \ + lwz scr,(mol_interface + 4 * hook_num + 4)@l(scr); \ + cmpwi cr1,scr,0; \ + beq+ cr1,778f; \ + mtctr scr; \ + bctrl; \ +778: + +#define MOL_HOOK_TLBMISS(hook_num) \ + lwz r0,(mol_interface + 4 * hook_num + 4)@l(0); \ + cmpwi r0,0; \ + beq+ 779f; \ + mflr r3; \ + mtlr r0; \ + blrl; \ + mtlr r3; \ +779: + +#else +#define MOL_HOOK(num) +#define MOL_HOOK_RESTORE(num) +#define MOL_HOOK_MMU(num, scr) +#define MOL_HOOK_TLBMISS(num) +#endif + + +#endif /* _PPC_KERNEL_MOL */ diff --git a/arch/ppc/kernel/oak_setup.c b/arch/ppc/kernel/oak_setup.c index 09e6e6e6f..ef5a7a0fe 100644 --- a/arch/ppc/kernel/oak_setup.c +++ b/arch/ppc/kernel/oak_setup.c @@ -231,10 +231,11 @@ oak_halt(void) /* * Document me. */ -void __init +long __init oak_time_init(void) { /* XXX - Implement me */ + return 0; } /* diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c index 416137934..5ca365b1c 100644 --- a/arch/ppc/kernel/open_pic.c +++ b/arch/ppc/kernel/open_pic.c @@ -100,7 +100,7 @@ struct hw_interrupt_type open_pic = { #ifdef CONFIG_SMP void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) { - smp_message_recv(cpl-OPENPIC_VEC_IPI); + smp_message_recv(cpl-OPENPIC_VEC_IPI, regs); } #endif /* CONFIG_SMP */ @@ -262,11 +262,11 @@ void __init openpic_init(int main_pic) int j, pri; pri = strcmp(np->name, "programmer-switch") ? 2 : 7; for (j=0;j<np->n_intrs;j++) { - openpic_initirq( np->intrs[j].line, - pri, - np->intrs[j].line, - 0, - np->intrs[j].sense); + openpic_initirq(np->intrs[j].line, + pri, + np->intrs[j].line, + 0, + np->intrs[j].sense); if (np->intrs[j].sense) irq_desc[np->intrs[j].line].status = IRQ_LEVEL; } diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 6233e5f9b..84faa0e1d 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -25,7 +25,13 @@ #include "pci.h" -static void __init pcibios_claim_resources(struct list_head *); +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif unsigned long isa_io_base = 0; unsigned long isa_mem_base = 0; @@ -70,59 +76,280 @@ struct pci_ops generic_pci_ops = generic_pcibios_write_dword }; -void __init pcibios_init(void) -{ - printk("PCI: Probing PCI hardware\n"); - pci_scan_bus(0, &generic_pci_ops, NULL); - if (ppc_md.pcibios_fixup) - ppc_md.pcibios_fixup(); - pcibios_claim_resources(&pci_root_buses); -} -void __init -pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges) + +void pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) { - 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; + u32 new, check; + int reg; + + new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + if (resource < 6) { + reg = PCI_BASE_ADDRESS_0 + 4*resource; + } else if (resource == PCI_ROM_RESOURCE) { + res->flags |= PCI_ROM_ADDRESS_ENABLE; + reg = dev->rom_base_reg; + } else { + /* Somebody might have asked allocation of a non-standard resource */ + return; + } + + pci_write_config_dword(dev, reg, new); + pci_read_config_dword(dev, reg, &check); + if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { + printk(KERN_ERR "PCI: Error while updating region " + "%s/%d (%08x != %08x)\n", dev->slot_name, resource, + new, check); + } } -unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, - unsigned long start, unsigned long size) +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might have be mirrored at 0x0100-0x03ff.. + */ +void +pcibios_align_resource(void *data, struct resource *res, unsigned long size) { - return start; + struct pci_dev *dev = data; + + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + if (size > 0x100) { + printk(KERN_ERR "PCI: I/O Region %s/%d too large" + " (%ld bytes)\n", dev->slot_name, + dev->resource - res, size); + } + + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } + } } -static void __init pcibios_claim_resources(struct list_head *bus_list) + +/* + * Handle resources of PCI devices. If the world were perfect, we could + * just allocate all the resource regions and do nothing more. It isn't. + * On the other hand, we cannot just re-allocate all devices, as it would + * require us to know lots of host bridge internals. So we attempt to + * keep as much of the original configuration as possible, but tweak it + * when it's found to be wrong. + * + * Known BIOS problems we have to work around: + * - I/O or memory regions not configured + * - regions configured, but not enabled in the command register + * - bogus I/O addresses above 64K used + * - expansion ROMs left enabled (this may sound harmless, but given + * the fact the PCI specs explicitly allow address decoders to be + * shared between expansion ROMs and other resource regions, it's + * at least dangerous) + * + * Our solution: + * (1) Allocate resources for all buses behind PCI-to-PCI bridges. + * This gives us fixed barriers on where we can allocate. + * (2) Allocate resources for all enabled devices. If there is + * a collision, just mark the resource as unallocated. Also + * disable expansion ROMs during this step. + * (3) Try to allocate resources for disabled devices. If the + * resources were assigned correctly, everything goes well, + * if they weren't, they won't disturb allocation of other + * resources. + * (4) Assign new addresses to resources which were either + * not configured at all or misconfigured. If explicitly + * requested by the user, configure expansion ROM address + * as well. + */ + +static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) { - struct list_head *ln, *dn; + struct list_head *ln; struct pci_bus *bus; struct pci_dev *dev; int idx; + struct resource *r, *pr; + /* Depth-First Search on bus tree */ for (ln=bus_list->next; ln != bus_list; ln=ln->next) { bus = pci_bus_b(ln); - for (dn=bus->devices.next; dn != &bus->devices; dn=dn->next) { - dev = pci_dev_b(dn); - for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) - { - struct resource *r = &dev->resource[idx]; - struct resource *pr; + if ((dev = bus->self)) { + for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { + r = &dev->resource[idx]; if (!r->start) continue; pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) - { - printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", idx, dev->name); - /* We probably should disable the region, shouldn't we? */ + printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name); + } + } + pcibios_allocate_bus_resources(&bus->children); + } +} + +static void __init pcibios_allocate_resources(int pass) +{ + struct pci_dev *dev; + int idx, disabled; + u16 command; + struct resource *r, *pr; + + pci_for_each_dev(dev) { + pci_read_config_word(dev, PCI_COMMAND, &command); + for(idx = 0; idx < 6; idx++) { + r = &dev->resource[idx]; + if (r->parent) /* Already allocated */ + continue; + if (!r->start) /* Address not assigned at all */ + continue; + if (r->end == 0xffffffff) { + /* LongTrail OF quirk: unassigned */ + DBG("PCI: Resource %08lx-%08lx was unassigned\n", r->start, r->end); + r->end -= r->start; + r->start = 0; + continue; + } + + if (r->flags & IORESOURCE_IO) + disabled = !(command & PCI_COMMAND_IO); + else + disabled = !(command & PCI_COMMAND_MEMORY); + if (pass == disabled) { + DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n", + r->start, r->end, r->flags, disabled, pass); + pr = pci_find_parent_resource(dev, r); + if (!pr || request_resource(pr, r) < 0) { + printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, dev->slot_name); + /* We'll assign a new address later */ + r->end -= r->start; + r->start = 0; } } } - pcibios_claim_resources(&bus->children); + if (!pass) { + r = &dev->resource[PCI_ROM_RESOURCE]; + if (r->flags & PCI_ROM_ADDRESS_ENABLE) { + /* Turn the ROM off, leave the resource region, but keep it unregistered. */ + u32 reg; + DBG("PCI: Switching off ROM of %s\n", dev->slot_name); + r->flags &= ~PCI_ROM_ADDRESS_ENABLE; + pci_read_config_dword(dev, dev->rom_base_reg, ®); + pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE); + } + } + } +} + +static void __init pcibios_assign_resources(void) +{ + struct pci_dev *dev; + int idx; + struct resource *r; + + pci_for_each_dev(dev) { + int class = dev->class >> 8; + + /* Don't touch classless devices and host bridges */ + if (!class || class == PCI_CLASS_BRIDGE_HOST) + continue; + + for(idx=0; idx<6; idx++) { + r = &dev->resource[idx]; + + /* + * Don't touch IDE controllers and I/O ports of video cards! + */ + if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) || + (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO))) + continue; + + /* + * We shall assign a new address to this resource, either because + * the BIOS forgot to do so or because we have decided the old + * address was unusable for some reason. + */ + if (!r->start && r->end) + pci_assign_resource(dev, idx); + } + + if (0) { /* don't assign ROMs */ + r = &dev->resource[PCI_ROM_RESOURCE]; + r->end -= r->start; + r->start = 0; + if (r->end) + pci_assign_resource(dev, PCI_ROM_RESOURCE); + } } } + +int pcibios_enable_resources(struct pci_dev *dev) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for(idx=0; idx<6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (dev->resource[PCI_ROM_RESOURCE].start) + cmd |= PCI_COMMAND_MEMORY; + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + + + +void __init pcibios_init(void) +{ + printk("PCI: Probing PCI hardware\n"); + pci_scan_bus(0, &generic_pci_ops, NULL); + if (ppc_md.pcibios_fixup) + ppc_md.pcibios_fixup(); + pcibios_allocate_bus_resources(&pci_root_buses); + pcibios_allocate_resources(0); + pcibios_allocate_resources(1); + pcibios_assign_resources(); +} + +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; +} + +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, + unsigned long start, unsigned long size) +{ + return start; +} + void __init pcibios_fixup_bus(struct pci_bus *bus) { if ( ppc_md.pcibios_fixup_bus ) @@ -134,21 +361,7 @@ char __init *pcibios_setup(char *str) return str; } -/* the next two are stolen from the alpha port... */ -void __init -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - unsigned long where, size; - u32 reg; - - where = PCI_BASE_ADDRESS_0 + (resource * 4); - size = res->end - res->start; - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); -} - +/* the next one is stolen from the alpha port... */ void __init pcibios_update_irq(struct pci_dev *dev, int irq) { @@ -156,11 +369,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq) /* XXX FIXME - update OF device tree node interrupt property */ } -void __init -pcibios_align_resource(void *data, struct resource *res, unsigned long size) -{ -} - int pcibios_enable_device(struct pci_dev *dev) { u16 cmd, old_cmd; @@ -188,114 +396,26 @@ int pcibios_enable_device(struct pci_dev *dev) return 0; } -/* - * Those syscalls are derived from the Alpha versions, they - * allow userland apps to retreive the per-device iobase and - * mem-base. They also provide wrapper for userland to do - * config space accesses. - * The "host_number" returns the number of the Uni-N sub bridge - */ - -asmlinkage int -sys_pciconfig_read(unsigned long bus, unsigned long dfn, - unsigned long off, unsigned long len, - unsigned char *buf) -{ - unsigned char ubyte; - unsigned short ushort; - unsigned int uint; - long err = 0; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - if (!pcibios_present()) - return -ENOSYS; - - switch (len) { - case 1: - err = pcibios_read_config_byte(bus, dfn, off, &ubyte); - put_user(ubyte, buf); - break; - case 2: - err = pcibios_read_config_word(bus, dfn, off, &ushort); - put_user(ushort, (unsigned short *)buf); - break; - case 4: - err = pcibios_read_config_dword(bus, dfn, off, &uint); - put_user(uint, (unsigned int *)buf); - break; - default: - err = -EINVAL; - break; - } - return err; -} - -asmlinkage int -sys_pciconfig_write(unsigned long bus, unsigned long dfn, - unsigned long off, unsigned long len, - unsigned char *buf) -{ - unsigned char ubyte; - unsigned short ushort; - unsigned int uint; - long err = 0; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - if (!pcibios_present()) - return -ENOSYS; - - switch (len) { - case 1: - err = get_user(ubyte, buf); - if (err) - break; - err = pcibios_write_config_byte(bus, dfn, off, ubyte); - if (err != PCIBIOS_SUCCESSFUL) { - err = -EFAULT; - } - break; - case 2: - err = get_user(ushort, (unsigned short *)buf); - if (err) - break; - err = pcibios_write_config_word(bus, dfn, off, ushort); - if (err != PCIBIOS_SUCCESSFUL) { - err = -EFAULT; - } - break; - case 4: - err = get_user(uint, (unsigned int *)buf); - if (err) - break; - err = pcibios_write_config_dword(bus, dfn, off, uint); - if (err != PCIBIOS_SUCCESSFUL) { - err = -EFAULT; - } - break; - default: - err = -EINVAL; - break; - } - return err; -} - void * -pci_dev_io_base(unsigned char bus, unsigned char devfn) +pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical) { - /* Defaults to old way */ - if (!ppc_md.pci_dev_io_base) - return pci_io_base(bus); - return ppc_md.pci_dev_io_base(bus, devfn); + if (!ppc_md.pci_dev_io_base) { + /* Please, someone fix this for non-pmac machines, we + * need either the virtual or physical PCI IO base + */ + return 0; + } + return ppc_md.pci_dev_io_base(bus, devfn, physical); } void * pci_dev_mem_base(unsigned char bus, unsigned char devfn) { /* Default memory base is 0 (1:1 mapping) */ - if (!ppc_md.pci_dev_mem_base) + if (!ppc_md.pci_dev_mem_base) { + /* Please, someone fix this for non-pmac machines.*/ return 0; + } return ppc_md.pci_dev_mem_base(bus, devfn); } @@ -318,15 +438,20 @@ pci_dev_root_bridge(unsigned char bus, unsigned char devfn) asmlinkage long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) { + long result = -EOPNOTSUPP; + switch (which) { case IOBASE_BRIDGE_NUMBER: return (long)pci_dev_root_bridge(bus, devfn); case IOBASE_MEMORY: return (long)pci_dev_mem_base(bus, devfn); case IOBASE_IO: - return (long)pci_dev_io_base(bus, devfn); + result = (long)pci_dev_io_base(bus, devfn, 1); + if (result == 0) + result = -EOPNOTSUPP; + break; } - return -EOPNOTSUPP; + return result; } diff --git a/arch/ppc/kernel/pmac_backlight.c b/arch/ppc/kernel/pmac_backlight.c index 8c6244632..30ad5f416 100644 --- a/arch/ppc/kernel/pmac_backlight.c +++ b/arch/ppc/kernel/pmac_backlight.c @@ -41,16 +41,16 @@ register_backlight_controller(struct backlight_controller *ctrler, void *data, c #ifdef CONFIG_ADB_PMU /* Special case for the old PowerBook since I can't test on it */ - if ((machine_is_compatible("AAPL,3400/2400") || machine_is_compatible("AAPL,3500") - || machine_is_compatible("AAPL,PowerBook1998") - || machine_is_compatible("AAPL,PowerBook1999")) - && !strcmp(type, "pmu")) + backlight_autosave = machine_is_compatible("AAPL,3400/2400") + || machine_is_compatible("AAPL,3500"); + if ((backlight_autosave + || machine_is_compatible("AAPL,PowerBook1998") + || machine_is_compatible("PowerBook1,1")) + && !strcmp(type, "pmu")) valid = 1; - else #endif - { - if (bk_node) - prop = get_property(bk_node, "backlight-control", NULL); + if (bk_node) { + prop = get_property(bk_node, "backlight-control", NULL); if (prop && !strncmp(prop, type, strlen(type))) valid = 1; } @@ -70,8 +70,6 @@ register_backlight_controller(struct backlight_controller *ctrler, void *data, c } #ifdef CONFIG_ADB_PMU - backlight_autosave = machine_is_compatible("AAPL,3400/2400") - || machine_is_compatible("AAPL,3500"); if (backlight_autosave) { struct adb_request req; pmu_request(&req, NULL, 2, 0xd9, 0); diff --git a/arch/ppc/kernel/pmac_nvram.c b/arch/ppc/kernel/pmac_nvram.c index d8de113ec..1c4c1eea1 100644 --- a/arch/ppc/kernel/pmac_nvram.c +++ b/arch/ppc/kernel/pmac_nvram.c @@ -312,17 +312,18 @@ pmac_nvram_update(void) __openfirmware unsigned char nvram_read_byte(int addr) { - struct adb_request req; - switch (nvram_naddrs) { #ifdef CONFIG_ADB_PMU - case -1: + case -1: { + struct adb_request req; + if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM, (addr >> 8) & 0xff, addr & 0xff)) break; while (!req.complete) pmu_poll(); return req.reply[1]; + } #endif case 1: if (is_core_99) @@ -339,17 +340,18 @@ unsigned char nvram_read_byte(int addr) __openfirmware void nvram_write_byte(unsigned char val, int addr) { - struct adb_request req; - switch (nvram_naddrs) { #ifdef CONFIG_ADB_PMU - case -1: + case -1: { + struct adb_request req; + if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM, (addr >> 8) & 0xff, addr & 0xff, val)) break; while (!req.complete) pmu_poll(); break; + } #endif case 1: if (is_core_99) { diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c index ced029722..8f7b3d7c2 100644 --- a/arch/ppc/kernel/pmac_pci.c +++ b/arch/ppc/kernel/pmac_pci.c @@ -35,6 +35,7 @@ struct uninorth_data { volatile unsigned int* cfg_addr; volatile unsigned int* cfg_data; void* iobase; + unsigned long iobase_phys; }; static struct uninorth_data uninorth_bridges[3]; @@ -133,15 +134,20 @@ pmac_pci_dev_root_bridge(unsigned char bus, unsigned char dev_fn) __pmac void * -pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn) +pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical) { - int bridge; - if (uninorth_count == 0) - return pci_io_base(bus); - bridge = pmac_pci_dev_root_bridge(bus, devfn); - if (bridge == -1) - return pci_io_base(bus); - return uninorth_bridges[bridge].iobase; + int bridge = -1; + if (uninorth_count != 0) + bridge = pmac_pci_dev_root_bridge(bus, devfn); + if (bridge == -1) { + struct bridge_data *bp; + + if (bus > max_bus || (bp = bridges[bus]) == 0) + return 0; + return physical ? (void *) bp->io_base_phys : bp->io_base; + } + return physical ? (void *) uninorth_bridges[bridge].iobase_phys + : uninorth_bridges[bridge].iobase; } __pmac @@ -649,7 +655,9 @@ static void __init add_bridges(struct device_node *dev) uninorth_bridges[i].cfg_addr = ioremap(addr->address + 0x800000, 0x1000); uninorth_bridges[i].cfg_data = ioremap(addr->address + 0xc00000, 0x1000); uninorth_bridges[i].node = dev; - uninorth_bridges[i].iobase = (void *)addr->address; + uninorth_bridges[i].iobase_phys = addr->address; + /* is 0x10000 enough for io space ? */ + uninorth_bridges[i].iobase = (void *)ioremap(addr->address, 0x10000); /* XXX This is the bridge with the PCI expansion bus. This is also the * address of the bus that will receive type 1 config accesses and io * accesses. Appears to be correct for iMac DV and G4 Sawtooth too. @@ -667,14 +675,15 @@ static void __init add_bridges(struct device_node *dev) if (device_is_compatible(dev, "uni-north")) { bp->cfg_addr = 0; bp->cfg_data = 0; - /* is 0x10000 enough for io space ? */ - bp->io_base = (void *)ioremap(addr->address, 0x10000); + bp->io_base = uninorth_bridges[uninorth_count-1].iobase; + bp->io_base_phys = uninorth_bridges[uninorth_count-1].iobase_phys; } else if (strcmp(dev->name, "pci") == 0) { /* XXX assume this is a mpc106 (grackle) */ bp->cfg_addr = (volatile unsigned int *) ioremap(0xfec00000, 0x1000); bp->cfg_data = (volatile unsigned char *) ioremap(0xfee00000, 0x1000); + bp->io_base_phys = 0xfe000000; bp->io_base = (void *) ioremap(0xfe000000, 0x20000); if (machine_is_compatible("AAPL,PowerBook1998")) grackle_set_loop_snoop(bp, 1); @@ -687,6 +696,7 @@ static void __init add_bridges(struct device_node *dev) ioremap(addr->address + 0x800000, 0x1000); bp->cfg_data = (volatile unsigned char *) ioremap(addr->address + 0xc00000, 0x1000); + bp->io_base_phys = addr->address; bp->io_base = (void *) ioremap(addr->address, 0x10000); } if (isa_io_base == 0) diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c index e0e654305..efd767482 100644 --- a/arch/ppc/kernel/pmac_pic.c +++ b/arch/ppc/kernel/pmac_pic.c @@ -204,17 +204,12 @@ pmac_get_irq(struct pt_regs *regs) unsigned long bits = 0; #ifdef CONFIG_SMP - void pmac_smp_message_recv(void); + void pmac_smp_message_recv(struct pt_regs *); /* IPI's are a hack on the powersurge -- Cort */ if ( smp_processor_id() != 0 ) { -#ifdef CONFIG_XMON - static int xmon_2nd; - if (xmon_2nd) - xmon(regs); -#endif - pmac_smp_message_recv(); + pmac_smp_message_recv(regs); return -2; /* ignore, already handled */ } #endif /* CONFIG_SMP */ diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c index 658d7c226..b5bf03abc 100644 --- a/arch/ppc/kernel/pmac_setup.c +++ b/arch/ppc/kernel/pmac_setup.c @@ -68,7 +68,7 @@ #undef SHOW_GATWICK_IRQS -extern void pmac_time_init(void); +extern long pmac_time_init(void); extern unsigned long pmac_get_rtc_time(void); extern int pmac_set_rtc_time(unsigned long nowtime); extern void pmac_read_rtc_time(void); @@ -77,24 +77,29 @@ extern void pmac_setup_pci_ptrs(void); extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int mackbd_getkeycode(unsigned int scancode); -extern int mackbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode); -extern char mackbd_unexpected_up(unsigned char keycode); +extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep, + char raw_mode); +extern int mackbd_unexpected_up(unsigned char keycode); extern void mackbd_leds(unsigned char leds); -extern void mackbd_init_hw(void); +extern void __init mackbd_init_hw(void); +extern int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char mac_hid_kbd_unexpected_up(unsigned char keycode); +extern void mac_hid_init_hw(void); #ifdef CONFIG_MAGIC_SYSRQ -unsigned char mackbd_sysrq_xlate[128]; +extern unsigned char mac_hid_kbd_sysrq_xlate[128]; +extern unsigned char pckbd_sysrq_xlate[128]; +extern unsigned char mackbd_sysrq_xlate[128]; #endif /* CONFIG_MAGIC_SYSRQ */ extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int pckbd_getkeycode(unsigned int scancode); extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode); extern char pckbd_unexpected_up(unsigned char keycode); -extern void pckbd_leds(unsigned char leds); -extern void pckbd_init_hw(void); +extern int keyboard_sends_linux_keycodes; extern void pmac_nvram_update(void); -extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn); +extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical); extern void *pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn); extern int pmac_pci_dev_root_bridge(unsigned char bus, unsigned char devfn); @@ -115,7 +120,6 @@ extern int pmac_newworld; extern void zs_kgdb_hook(int tty_num); static void ohare_init(void); static void init_p2pbridge(void); -static void init_uninorth(void); #ifdef CONFIG_BOOTX_TEXT void pmac_progress(char *s, unsigned short hex); #endif @@ -276,7 +280,6 @@ pmac_setup_arch(void) pmac_find_bridges(); init_p2pbridge(); - init_uninorth(); /* Checks "l2cr-value" property in the registry */ if ( (_get_PVR() >> 16) == 8 || (_get_PVR() >> 16) == 12 ) { @@ -372,31 +375,6 @@ static void __init ohare_init(void) } } -static void __init -init_uninorth(void) -{ - /* - * Turns OFF the gmac clock. The gmac driver will turn - * it back ON when the interface is enabled. This save - * power on portables. - * - * Note: We could also try to turn OFF the PHY. Since this - * has to be done by both the gmac driver and this code, - * I'll probably end-up moving some of this out of the - * modular gmac driver into a non-modular stub containing - * some basic PHY management and power management stuffs - */ - struct device_node* gmac = find_devices("ethernet"); - - while(gmac) { - if (device_is_compatible(gmac, "gmac")) - break; - gmac = gmac->next; - } - if (gmac) - feature_set_gmac_power(gmac, 0); -} - extern char *bootpath; extern char *bootdevice; void *boot_host; @@ -404,14 +382,15 @@ int boot_target; int boot_part; kdev_t boot_dev; -extern void via_pmu_start(void); - void __init pmac_init2(void) { #ifdef CONFIG_ADB_PMU via_pmu_start(); #endif +#ifdef CONFIG_ADB_CUDA + via_cuda_start(); +#endif #ifdef CONFIG_PMAC_PBOOK media_bay_init(); #endif @@ -683,7 +662,26 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.pci_dev_mem_base = pmac_pci_dev_mem_base; ppc_md.pci_dev_root_bridge = pmac_pci_dev_root_bridge; -#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) +#ifdef CONFIG_VT +#ifdef CONFIG_INPUT_ADBHID + ppc_md.kbd_init_hw = mac_hid_init_hw; + ppc_md.kbd_translate = mac_hid_kbd_translate; + ppc_md.kbd_unexpected_up = mac_hid_kbd_unexpected_up; + ppc_md.kbd_setkeycode = 0; + ppc_md.kbd_getkeycode = 0; +#ifdef CONFIG_MAGIC_SYSRQ +#ifdef CONFIG_MAC_ADBKEYCODES + if (!keyboard_sends_linux_keycodes) { + ppc_md.ppc_kbd_sysrq_xlate = mac_hid_kbd_sysrq_xlate; + SYSRQ_KEY = 0x69; + } else +#endif /* CONFIG_MAC_ADBKEYCODES */ + { + ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; + } +#endif /* CONFIG_MAGIC_SYSRQ */ +#elif defined(CONFIG_ADB_KEYBOARD) ppc_md.kbd_setkeycode = mackbd_setkeycode; ppc_md.kbd_getkeycode = mackbd_getkeycode; ppc_md.kbd_translate = mackbd_translate; @@ -691,10 +689,11 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.kbd_leds = mackbd_leds; ppc_md.kbd_init_hw = mackbd_init_hw; #ifdef CONFIG_MAGIC_SYSRQ - ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; + ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; SYSRQ_KEY = 0x69; -#endif -#endif +#endif /* CONFIG_MAGIC_SYSRQ */ +#endif /* CONFIG_INPUT_ADBHID/CONFIG_ADB_KEYBOARD */ +#endif /* CONFIG_VT */ #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) ppc_ide_md.insw = pmac_ide_insw; diff --git a/arch/ppc/kernel/pmac_time.c b/arch/ppc/kernel/pmac_time.c index 9eb326bf9..00b6302a7 100644 --- a/arch/ppc/kernel/pmac_time.c +++ b/arch/ppc/kernel/pmac_time.c @@ -25,7 +25,7 @@ #include <asm/io.h> #include <asm/pgtable.h> #include <asm/machdep.h> - +#include <asm/hardirq.h> #include <asm/time.h> #include <asm/nvram.h> @@ -58,7 +58,7 @@ extern rwlock_t xtime_lock; extern struct timezone sys_tz; __init -void pmac_time_init(void) +long pmac_time_init(void) { #ifdef CONFIG_NVRAM s32 delta = 0; @@ -72,17 +72,18 @@ void pmac_time_init(void) dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0); printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60, dst ? "on" : "off"); - sys_tz.tz_minuteswest = -delta/60; - /* I _suppose_ this is 0:off, 1:on */ - sys_tz.tz_dsttime = dst; + return delta; +#else + return 0; #endif } __pmac unsigned long pmac_get_rtc_time(void) { -#ifdef CONFIG_ADB +#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) struct adb_request req; + unsigned long now; #endif /* Get the time from the RTC */ @@ -96,8 +97,9 @@ unsigned long pmac_get_rtc_time(void) if (req.reply_len != 7) printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", req.reply_len); - return (req.reply[3] << 24) + (req.reply[4] << 16) - + (req.reply[5] << 8) + req.reply[6] - RTC_OFFSET; + now = (req.reply[3] << 24) + (req.reply[4] << 16) + + (req.reply[5] << 8) + req.reply[6]; + return now - RTC_OFFSET; #endif /* CONFIG_ADB_CUDA */ #ifdef CONFIG_ADB_PMU case SYS_CTRLER_PMU: @@ -108,21 +110,25 @@ unsigned long pmac_get_rtc_time(void) if (req.reply_len != 5) printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", req.reply_len); - return (req.reply[1] << 24) + (req.reply[2] << 16) - + (req.reply[3] << 8) + req.reply[4] - RTC_OFFSET; + now = (req.reply[1] << 24) + (req.reply[2] << 16) + + (req.reply[3] << 8) + req.reply[4]; + return now - RTC_OFFSET; #endif /* CONFIG_ADB_PMU */ default: - return 0; } + return 0; } int pmac_set_rtc_time(unsigned long nowtime) { +#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) struct adb_request req; +#endif - nowtime += RTC_OFFSET - sys_tz.tz_minuteswest * 60; + nowtime += RTC_OFFSET; switch (sys_ctrler) { +#ifdef CONFIG_ADB_CUDA case SYS_CTRLER_CUDA: if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) @@ -133,16 +139,19 @@ int pmac_set_rtc_time(unsigned long nowtime) printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", req.reply_len); return 1; +#endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_ADB_PMU case SYS_CTRLER_PMU: if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) return 0; while (!req.complete) pmu_poll(); - if (req.reply_len != 5) + if (req.reply_len != 0) printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", req.reply_len); return 1; +#endif /* CONFIG_ADB_PMU */ default: return 0; } @@ -186,12 +195,11 @@ int __init via_calibrate_decr(void) ; dend = get_dec(); - decrementer_count = (dstart - dend) / 6; - count_period_num = 60; - count_period_den = decrementer_count * 6 * HZ / 100000; + tb_ticks_per_jiffy = (dstart - dend) / 6; + tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); - printk(KERN_INFO "via_calibrate_decr: decrementer_count = %u (%u ticks)\n", - decrementer_count, dstart - dend); + printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", + tb_ticks_per_jiffy, dstart - dend); return 1; } @@ -214,8 +222,11 @@ static int time_sleep_notify(struct pmu_sleep_notifier *self, int when) case PBOOK_WAKE: write_lock_irqsave(&xtime_lock, flags); xtime.tv_sec = pmac_get_rtc_time() + time_diff; + set_dec(tb_ticks_per_jiffy); + /* No currently-supported powerbook has a 601, + so use get_tbl, not native */ + last_jiffy_stamp(0) = tb_last_stamp = get_tbl(); xtime.tv_usec = 0; - set_dec(decrementer_count); last_rtc_update = xtime.tv_sec; write_unlock_irqrestore(&xtime_lock, flags); break; @@ -236,7 +247,7 @@ static struct pmu_sleep_notifier time_sleep_notifier = { void __init pmac_calibrate_decr(void) { struct device_node *cpu; - int freq, *fp, divisor; + unsigned int freq, *fp; #ifdef CONFIG_PMAC_PBOOK pmu_register_sleep_notifier(&time_sleep_notifier); @@ -252,15 +263,13 @@ void __init pmac_calibrate_decr(void) cpu = find_type_devices("cpu"); if (cpu == 0) panic("can't find cpu node in time_init"); - fp = (int *) get_property(cpu, "timebase-frequency", NULL); + fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL); if (fp == 0) panic("can't get cpu timebase frequency"); - freq = *fp * 60; /* try to make freq/1e6 an integer */ - divisor = 60; - printk("time_init: decrementer frequency = %d/%d\n", - freq, divisor); - decrementer_count = freq / HZ / divisor; - count_period_num = divisor; - count_period_den = freq / 1000000; + freq = *fp; + printk("time_init: decrementer frequency = %u.%.6u MHz\n", + freq/1000000, freq%1000000); + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); } diff --git a/arch/ppc/kernel/ppc-stub.c b/arch/ppc/kernel/ppc-stub.c index 7a673fb70..1b865ef96 100644 --- a/arch/ppc/kernel/ppc-stub.c +++ b/arch/ppc/kernel/ppc-stub.c @@ -122,9 +122,9 @@ void breakinst(void); static char remcomInBuffer[BUFMAX]; static char remcomOutBuffer[BUFMAX]; -static int initialized = 0; -static int kgdb_active = 0; -static int kgdb_started = 0; +static int initialized; +static int kgdb_active; +static int kgdb_started; static u_int fault_jmp_buf[100]; static int kdebug; diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 1317359e7..9240431e6 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -37,6 +37,7 @@ #include <asm/hw_irq.h> #include <asm/nvram.h> #include <asm/mmu_context.h> +#include <asm/backlight.h> #ifdef CONFIG_SMP #include <asm/smplock.h> #endif /* CONFIG_SMP */ @@ -184,6 +185,10 @@ EXPORT_SYMBOL(giveup_fpu); EXPORT_SYMBOL(enable_kernel_fp); EXPORT_SYMBOL(flush_icache_range); EXPORT_SYMBOL(xchg_u32); +#ifdef CONFIG_ALTIVEC +EXPORT_SYMBOL(last_task_used_altivec); +EXPORT_SYMBOL(giveup_altivec); +#endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_SMP EXPORT_SYMBOL(__global_cli); EXPORT_SYMBOL(__global_sti); @@ -204,26 +209,34 @@ EXPORT_SYMBOL(_machine); EXPORT_SYMBOL(ppc_md); #ifdef CONFIG_ADB -/* - * This could be more fine-grained, but for now assume if we have - * ADB we have it all -- Cort - */ EXPORT_SYMBOL(adb_request); EXPORT_SYMBOL(adb_register); +EXPORT_SYMBOL(adb_unregister); +EXPORT_SYMBOL(adb_poll); +EXPORT_SYMBOL(adb_try_handler_change); +#endif /* CONFIG_ADB */ +#ifdef CONFIG_ADB_CUDA EXPORT_SYMBOL(cuda_request); EXPORT_SYMBOL(cuda_poll); +#endif /* CONFIG_ADB_CUDA */ #ifdef CONFIG_ADB_PMU EXPORT_SYMBOL(pmu_request); EXPORT_SYMBOL(pmu_poll); #endif /* CONFIG_ADB_PMU */ -#endif /* CONFIG_ADB */ #ifdef CONFIG_PMAC_PBOOK EXPORT_SYMBOL(pmu_register_sleep_notifier); EXPORT_SYMBOL(pmu_unregister_sleep_notifier); EXPORT_SYMBOL(pmu_enable_irled); -#endif CONFIG_PMAC_PBOOK +#endif /* CONFIG_PMAC_PBOOK */ +#ifdef CONFIG_PMAC_BACKLIGHT +EXPORT_SYMBOL(get_backlight_level); +EXPORT_SYMBOL(set_backlight_level); +#endif /* CONFIG_PMAC_BACKLIGHT */ #if defined(CONFIG_ALL_PPC) EXPORT_SYMBOL_NOVERS(sys_ctrler); +#ifndef CONFIG_MACH_SPECIFIC +EXPORT_SYMBOL_NOVERS(have_of); +#endif /* CONFIG_MACH_SPECIFIC */ EXPORT_SYMBOL(find_devices); EXPORT_SYMBOL(find_type_devices); EXPORT_SYMBOL(find_compatible_devices); @@ -253,10 +266,7 @@ EXPORT_SYMBOL(nvram_write_byte); EXPORT_SYMBOL(pmac_xpram_read); EXPORT_SYMBOL(pmac_xpram_write); #endif /* CONFIG_NVRAM */ -#ifdef CONFIG_PPC_RTC -EXPORT_SYMBOL(mktime); EXPORT_SYMBOL(to_tm); -#endif EXPORT_SYMBOL_NOVERS(__ashrdi3); EXPORT_SYMBOL_NOVERS(__ashldi3); @@ -280,7 +290,7 @@ EXPORT_SYMBOL(do_IRQ_intercept); EXPORT_SYMBOL(irq_desc); void ppc_irq_dispatch_handler(struct pt_regs *, int); EXPORT_SYMBOL(ppc_irq_dispatch_handler); -EXPORT_SYMBOL(decrementer_count); +EXPORT_SYMBOL(tb_ticks_per_jiffy); EXPORT_SYMBOL(get_wchan); EXPORT_SYMBOL(console_drivers); EXPORT_SYMBOL(console_lock); @@ -310,3 +320,17 @@ EXPORT_SYMBOL(do_softirq); EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); EXPORT_SYMBOL(mmu_context_overflow); + +#ifdef CONFIG_MOL +extern ulong mol_interface[]; +extern PTE *Hash; +extern unsigned long Hash_mask; +extern void (*ret_from_except)(void); +extern struct task_struct *last_task_used_altivec; +EXPORT_SYMBOL_NOVERS(mol_interface); +EXPORT_SYMBOL(Hash); +EXPORT_SYMBOL(Hash_mask); +EXPORT_SYMBOL(handle_mm_fault); +EXPORT_SYMBOL(last_task_used_math); +EXPORT_SYMBOL(ret_from_except); +#endif /* CONFIG_MOL */ diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index a09b4cf81..d72e74735 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -365,14 +365,13 @@ prep_setup_arch(void) */ void __init prep_res_calibrate_decr(void) { - int freq, divisor; + unsigned long freq, divisor=4; freq = res->VitalProductData.ProcessorBusHz; - divisor = 4; - printk("time_init: decrementer frequency = %d/%d\n", freq, divisor); - decrementer_count = freq / HZ / divisor; - count_period_num = divisor; - count_period_den = freq / 1000000; + printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", + (freq/divisor)/1000000, (freq/divisor)%1000000); + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); } /* @@ -381,32 +380,30 @@ void __init prep_res_calibrate_decr(void) * but on prep we have to figure it out. * -- Cort */ -int calibrate_done = 0; -volatile int *done_ptr = &calibrate_done; +/* Done with 3 interrupts: the first one primes the cache and the + * 2 following ones measure the interval. The precision of the method + * is still doubtful due to the short interval sampled. + */ +static __initdata volatile int calibrate_steps = 3; +static __initdata unsigned tbstamp; void __init prep_calibrate_decr_handler(int irq, void *dev, struct pt_regs *regs) { - unsigned long freq, divisor; - static unsigned long t1 = 0, t2 = 0; - - if ( !t1 ) - t1 = get_dec(); - else if (!t2) - { - t2 = get_dec(); - t2 = t1-t2; /* decr's in 1/HZ */ - t2 = t2*HZ; /* # decrs in 1s - thus in Hz */ - freq = t2 * 60; /* try to make freq/1e6 an integer */ - divisor = 60; - printk("time_init: decrementer frequency = %lu/%lu (%luMHz)\n", - freq, divisor,t2>>20); - decrementer_count = freq / HZ / divisor; - count_period_num = divisor; - count_period_den = freq / 1000000; - *done_ptr = 1; + unsigned long t, freq; + int step=--calibrate_steps; + + t = get_tbl(); + if (step > 0) { + tbstamp = t; + } else { + freq = (t - tbstamp)*HZ; + printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", + freq/1000000, freq%1000000); + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); } } @@ -428,17 +425,43 @@ void __init prep_calibrate_decr(void) if (request_irq(0, prep_calibrate_decr_handler, 0, "timer", NULL) != 0) panic("Could not allocate timer IRQ!"); __sti(); - while ( ! *done_ptr ) /* nothing */; /* wait for calibrate */ + while ( calibrate_steps ) /* nothing */; /* wait for calibrate */ restore_flags(flags); free_irq( 0, NULL); } -/* We use the NVRAM RTC to time a second to calibrate the decrementer. */ +static long __init mk48t59_init(void) { + unsigned char tmp; + + tmp = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB); + if (tmp & MK48T59_RTC_CB_STOP) { + printk("Warning: RTC was stopped, date will be wrong.\n"); + ppc_md.nvram_write_val(MK48T59_RTC_CONTROLB, + tmp & ~MK48T59_RTC_CB_STOP); + /* Low frequency crystal oscillators may take a very long + * time to startup and stabilize. For now just ignore the + * the issue, but attempting to calibrate the decrementer + * from the RTC just after this wakeup is likely to be very + * inaccurate. Firmware should not allow to load + * the OS with the clock stopped anyway... + */ + } + /* Ensure that the clock registers are updated */ + tmp = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA); + tmp &= ~(MK48T59_RTC_CA_READ | MK48T59_RTC_CA_WRITE); + ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, tmp); + return 0; +} + +/* We use the NVRAM RTC to time a second to calibrate the decrementer, + * the RTC registers have just been set up in the right state by the + * preceding routine. + */ void __init mk48t59_calibrate_decr(void) { - unsigned long freq, divisor; - unsigned long t1, t2; + unsigned long freq; + unsigned long t1; unsigned char save_control; long i; unsigned char sec; @@ -458,29 +481,31 @@ void __init mk48t59_calibrate_decr(void) /* Read the seconds value to see when it changes. */ sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS); + /* Actually this is bad for precision, we should have a loop in + * which we only read the seconds counter. nvram_read_val writes + * the address bytes on every call and this takes a lot of time. + * Perhaps an nvram_wait_change method returning a time + * stamp with a loop count as parameter would be the solution. + */ for (i = 0 ; i < 1000000 ; i++) { /* may take up to 1 second... */ + t1 = get_tbl(); if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) { break; } } - t1 = get_dec(); sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS); for (i = 0 ; i < 1000000 ; i++) { /* Should take up 1 second... */ + freq = get_tbl()-t1; if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) { break; } } - t2 = t1 - get_dec(); - - freq = t2 * 60; /* try to make freq/1e6 an integer */ - divisor = 60; - printk("time_init: decrementer frequency = %lu/%lu (%luMHz)\n", - freq, divisor,t2>>20); - decrementer_count = freq / HZ / divisor; - count_period_num = divisor; - count_period_den = freq / 1000000; + printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", + freq/1000000, freq%1000000); + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); } void __prep @@ -788,6 +813,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, { ppc_md.set_rtc_time = mk48t59_set_rtc_time; ppc_md.get_rtc_time = mk48t59_get_rtc_time; + ppc_md.time_init = mk48t59_init; } else { @@ -808,6 +834,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.set_rtc_time = mk48t59_set_rtc_time; ppc_md.get_rtc_time = mk48t59_get_rtc_time; ppc_md.calibrate_decr = mk48t59_calibrate_decr; + ppc_md.time_init = mk48t59_init; } #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) diff --git a/arch/ppc/kernel/prep_time.c b/arch/ppc/kernel/prep_time.c index 7274dfd0b..78634c6e2 100644 --- a/arch/ppc/kernel/prep_time.c +++ b/arch/ppc/kernel/prep_time.c @@ -15,6 +15,7 @@ #include <linux/string.h> #include <linux/mm.h> #include <linux/interrupt.h> +#include <linux/time.h> #include <linux/timex.h> #include <linux/kernel_stat.h> #include <linux/init.h> @@ -99,28 +100,34 @@ __prep unsigned long mc146818_get_rtc_time(void) { unsigned int year, mon, day, hour, min, sec; - int i; + int uip, i; /* The Linux interpretation of the CMOS clock register contents: * When the Update-In-Progress (UIP) flag goes from 1 to 0, the * RTC registers show the second which has precisely just started. * Let's hope other operating systems interpret the RTC the same way. */ - /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - do { /* Isn't this overkill ? UIP above should guarantee consistency */ + + /* Since the UIP flag is set for about 2.2 ms and the clock + * is typically written with a precision of 1 jiffy, trying + * to obtain a precision better than a few milliseconds is + * an illusion. Only consistency is interesting, this also + * allows to use the routine for /dev/rtc without a potential + * 1 second kernel busy loop triggered by any reader of /dev/rtc. + */ + + for ( i = 0; i<1000000; i++) { + uip = CMOS_READ(RTC_FREQ_SELECT); sec = CMOS_READ(RTC_SECONDS); min = CMOS_READ(RTC_MINUTES); hour = CMOS_READ(RTC_HOURS); day = CMOS_READ(RTC_DAY_OF_MONTH); mon = CMOS_READ(RTC_MONTH); year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); + uip |= CMOS_READ(RTC_FREQ_SELECT); + if ((uip & RTC_UIP)==0) break; + } + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { @@ -177,29 +184,12 @@ unsigned long mk48t59_get_rtc_time(void) { unsigned char save_control; unsigned int year, mon, day, hour, min, sec; - int i; - /* Make sure the time is not stopped. */ - save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB); - - ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, - (save_control & (~MK48T59_RTC_CB_STOP))); - - /* Now make sure the read bit is off so the value will change. */ + /* Simple: freeze the clock, read it and allow updates again */ save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA); save_control &= ~MK48T59_RTC_CA_READ; ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control); - /* Read the seconds value to see when it changes. */ - sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS); - - /* Wait until the seconds value changes, then read the value. */ - for (i = 0 ; i < 1000000 ; i++) { /* may take up to 1 second... */ - if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) { - break; - } - } - /* Set the register to read the value. */ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, (save_control | MK48T59_RTC_CA_READ)); diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 7bc5cb82f..27adc9958 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -234,7 +234,6 @@ _switch_to(struct task_struct *prev, struct task_struct *new, prev->thread.vrsave ) giveup_altivec(prev); #endif /* CONFIG_ALTIVEC */ - prev->last_processor = prev->processor; current_set[smp_processor_id()] = new; #endif /* CONFIG_SMP */ /* Avoid the trap. On smp this this never happens since @@ -266,7 +265,7 @@ void show_regs(struct pt_regs * regs) last_task_used_altivec); #ifdef CONFIG_SMP - printk(" CPU: %d last CPU: %d", current->processor,current->last_processor); + printk(" CPU: %d", current->processor); #endif /* CONFIG_SMP */ printk("\n"); @@ -315,6 +314,7 @@ release_thread(struct task_struct *t) */ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, + unsigned long unused, struct task_struct * p, struct pt_regs * regs) { unsigned long msr; @@ -378,9 +378,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, childregs->msr &= ~MSR_VEC; #endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_SMP - p->last_processor = NO_PROC_ID; -#endif /* CONFIG_SMP */ return 0; } @@ -440,13 +437,13 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) current->thread.fpscr = 0; } -asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6, - struct pt_regs *regs) +int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6, + struct pt_regs *regs) { unsigned long clone_flags = p1; int res; lock_kernel(); - res = do_fork(clone_flags, regs->gpr[1], regs); + res = do_fork(clone_flags, regs->gpr[1], regs, 0); #ifdef CONFIG_SMP /* When we clone the idle task we keep the same pid but * the return value of 0 for both causes problems. @@ -459,13 +456,13 @@ asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6, return res; } -asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, - struct pt_regs *regs) +int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, + struct pt_regs *regs) { int res; - res = do_fork(SIGCHLD, regs->gpr[1], regs); + res = do_fork(SIGCHLD, regs->gpr[1], regs, 0); #ifdef CONFIG_SMP /* When we clone the idle task we keep the same pid but * the return value of 0 for both causes problems. @@ -477,15 +474,15 @@ asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, return res; } -asmlinkage int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6, - struct pt_regs *regs) +int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6, + struct pt_regs *regs) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs); + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0); } -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) +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) { int error; char * filename; diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c index 1d661fa71..5494f2f52 100644 --- a/arch/ppc/kernel/prom.c +++ b/arch/ppc/kernel/prom.c @@ -140,8 +140,7 @@ static long g_loc_Y = 0; static long g_max_loc_X = 0; static long g_max_loc_Y = 0; -unsigned long disp_BATL = 0; -unsigned long disp_BATU = 0; +unsigned long disp_BAT[2] = {0, 0}; #define cmapsz (16*256) @@ -276,8 +275,7 @@ prom_print(const char *msg) prom_drawstring(msg); #endif return; - } - + } for (p = msg; *p != 0; p = q) { for (q = p; *q != 0 && *q != '\n'; ++q) @@ -362,7 +360,7 @@ prom_hold_cpus(unsigned long mem) /* copy the holding pattern code to someplace safe (0) */ /* the holding pattern is now within the first 0x100 bytes of the kernel image -- paulus */ - memcpy((void *)0, KERNELBASE + offset, 0x100); + memcpy((void *)0, (void *)(KERNELBASE + offset), 0x100); flush_icache_range(0, 0x100); /* look for cpus */ @@ -556,6 +554,54 @@ prom_alloc_htab(void) } #endif /* CONFIG_PPC64BRIDGE */ +static __init void +prom_instantiate_rtas(void) +{ + ihandle prom_rtas; + unsigned int i; + struct prom_args prom_args; + unsigned long offset = reloc_offset(); + + prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas")); + if (prom_rtas == (void *) -1) + return; + + RELOC(rtas_size) = 0; + call_prom(RELOC("getprop"), 4, 1, prom_rtas, + RELOC("rtas-size"), &RELOC(rtas_size), sizeof(rtas_size)); + prom_print(RELOC("instantiating rtas")); + if (RELOC(rtas_size) == 0) { + RELOC(rtas_data) = 0; + } else { + /* + * Ask OF for some space for RTAS. + * Actually OF has bugs so we just arbitrarily + * use memory at the 6MB point. + */ + RELOC(rtas_data) = 6 << 20; + prom_print(RELOC(" at ")); + prom_print_hex(RELOC(rtas_data)); + } + + prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas")); + prom_print(RELOC("...")); + prom_args.service = RELOC("call-method"); + prom_args.nargs = 3; + prom_args.nret = 2; + prom_args.args[0] = RELOC("instantiate-rtas"); + prom_args.args[1] = prom_rtas; + prom_args.args[2] = (void *) RELOC(rtas_data); + RELOC(prom)(&prom_args); + i = 0; + if (prom_args.args[3] == 0) + i = (unsigned int)prom_args.args[4]; + RELOC(rtas_entry) = i; + if ((RELOC(rtas_entry) == -1) || (RELOC(rtas_entry) == 0)) + prom_print(RELOC(" failed\n")); + else + prom_print(RELOC(" done\n")); +} + /* * We enter here early on, when the Open Firmware prom is still * handling exceptions and the MMU hash table for us. @@ -566,7 +612,7 @@ prom_init(int r3, int r4, prom_entry pp) { int chrp = 0; unsigned long mem; - ihandle prom_rtas, prom_mmu, prom_op; + ihandle prom_mmu, prom_op; unsigned long offset = reloc_offset(); int l; char *p, *d; @@ -650,47 +696,7 @@ prom_init(int r3, int r4, prom_entry pp) mem = ALIGN(mem + strlen(d) + 1); } - prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas")); - if (prom_rtas != (void *) -1) { - int i, nargs; - struct prom_args prom_args; - - RELOC(rtas_size) = 0; - call_prom(RELOC("getprop"), 4, 1, prom_rtas, - RELOC("rtas-size"), &RELOC(rtas_size), sizeof(rtas_size)); - prom_print(RELOC("instantiating rtas")); - if (RELOC(rtas_size) == 0) { - RELOC(rtas_data) = 0; - } else { - /* - * Ask OF for some space for RTAS. - * Actually OF has bugs so we just arbitrarily - * use memory at the 6MB point. - */ - RELOC(rtas_data) = 6 << 20; - prom_print(RELOC(" at ")); - prom_print_hex(RELOC(rtas_data)); - } - prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas")); - prom_print(RELOC("...")); - nargs = 3; - prom_args.service = RELOC("call-method"); - prom_args.nargs = nargs; - prom_args.nret = 2; - prom_args.args[0] = RELOC("instantiate-rtas"); - prom_args.args[1] = prom_rtas; - prom_args.args[2] = (void *) RELOC(rtas_data); - RELOC(prom)(&prom_args); - if (prom_args.args[nargs] != 0) - i = 0; - else - i = (int)prom_args.args[nargs+1]; - RELOC(rtas_entry) = i; - if ((RELOC(rtas_entry) == -1) || (RELOC(rtas_entry) == 0)) - prom_print(RELOC(" failed\n")); - else - prom_print(RELOC(" done\n")); - } + prom_instantiate_rtas(); #ifdef CONFIG_PPC64BRIDGE /* @@ -737,7 +743,7 @@ prom_init(int r3, int r4, prom_entry pp) /* We assume the phys. address size is 3 cells */ if (prom_args.args[nargs] != 0) - prom_print(RELOC(" (translate failed) ")); + prom_print(RELOC(" (translate failed)\n")); else phys = (unsigned long)prom_args.args[nargs+3]; } @@ -752,8 +758,6 @@ prom_init(int r3, int r4, prom_entry pp) if (prom_version >= 3) { prom_print(RELOC("Calling quiesce ...\n")); call_prom(RELOC("quiesce"), 0, 0); - offset = reloc_offset(); - phys = offset + KERNELBASE; } #ifdef CONFIG_BOOTX_TEXT @@ -769,7 +773,9 @@ prom_init(int r3, int r4, prom_entry pp) } #endif - prom_print(RELOC("returning from prom_init\n")); + prom_print(RELOC("returning ")); + prom_print_hex(phys); + prom_print(RELOC(" from prom_init\n")); RELOC(prom_stdout) = 0; return phys; } @@ -836,9 +842,8 @@ prom_welcome(boot_infos_t* bi, unsigned long phys) } /* Calc BAT values for mapping the display and store them - * in disp_BATH and disp_BATL. Those values are then used - * from head.S to map the display during identify_machine() - * and MMU_Init() + * in disp_BAT. Those values are then used from head.S to map + * the display during identify_machine() and MMU_Init() * * For now, the display is mapped in place (1:1). This should * be changed if the display physical address overlaps @@ -862,13 +867,13 @@ prepare_disp_BAT(void) if ((_get_PVR() >> 16) != 1) { /* 603, 604, G3, G4, ... */ addr &= 0xFF000000UL; - RELOC(disp_BATU) = addr | (BL_16M<<2) | 2; - RELOC(disp_BATL) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); + RELOC(disp_BAT[0]) = addr | (BL_16M<<2) | 2; + RELOC(disp_BAT[1]) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); } else { /* 601 */ addr &= 0xFF800000UL; - RELOC(disp_BATU) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4; - RELOC(disp_BATL) = addr | BL_8M | 0x40; + RELOC(disp_BAT[0]) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4; + RELOC(disp_BAT[1]) = addr | BL_8M | 0x40; } bi->logicalDisplayBase = bi->dispDeviceBase; } @@ -1003,34 +1008,52 @@ setup_disp_fake_bi(ihandle dp) unsigned address; boot_infos_t* bi; unsigned long offset = reloc_offset(); - - prom_print(RELOC("Initializing fake screen\n")); - - call_prom(RELOC("getprop"), 4, 1, dp, RELOC("width"), - &width, sizeof(width)); - call_prom(RELOC("getprop"), 4, 1, dp, RELOC("height"), - &height, sizeof(height)); - call_prom(RELOC("getprop"), 4, 1, dp, RELOC("depth"), - &depth, sizeof(depth)); + struct pci_reg_property addrs[8]; + int i, naddrs; + char name[32]; + char *getprop = RELOC("getprop"); + + prom_print(RELOC("Initializing fake screen: ")); + + memset(name, 0, sizeof(name)); + call_prom(getprop, 4, 1, dp, RELOC("name"), name, sizeof(name)); + name[sizeof(name)-1] = 0; + prom_print(name); + prom_print(RELOC("\n")); + call_prom(getprop, 4, 1, dp, RELOC("width"), &width, sizeof(width)); + call_prom(getprop, 4, 1, dp, RELOC("height"), &height, sizeof(height)); + call_prom(getprop, 4, 1, dp, RELOC("depth"), &depth, sizeof(depth)); pitch = width * ((depth + 7) / 8); - call_prom(RELOC("getprop"), 4, 1, dp, RELOC("linebytes"), + call_prom(getprop, 4, 1, dp, RELOC("linebytes"), &pitch, sizeof(pitch)); - address = 0; - if (pitch == 1) { - address = 0xfa000000; + if (pitch == 1) pitch = 0x1000; /* for strange IBM display */ - } - call_prom(RELOC("getprop"), 4, 1, dp, RELOC("address"), + address = 0; + call_prom(getprop, 4, 1, dp, RELOC("address"), &address, sizeof(address)); if (address == 0) { - prom_print(RELOC("Failed to get address\n")); - return; + /* look for an assigned address with a size of >= 1MB */ + naddrs = (int) call_prom(getprop, 4, 1, dp, + RELOC("assigned-addresses"), + addrs, sizeof(addrs)); + naddrs /= sizeof(struct pci_reg_property); + for (i = 0; i < naddrs; ++i) { + if (addrs[i].size_lo >= (1 << 20)) { + address = addrs[i].addr.a_lo; + /* use the BE aperture if possible */ + if (addrs[i].size_lo >= (16 << 20)) + address += (8 << 20); + break; + } + } + if (address == 0) { + prom_print(RELOC("Failed to get address\n")); + return; + } } -#if 0 /* kludge for valkyrie */ - if (strcmp(dp->name, "valkyrie") == 0) - address += 0x1000; -#endif + if (strcmp(name, RELOC("valkyrie")) == 0) + address += 0x1000; RELOC(disp_bi) = &fake_bi; bi = PTRRELOC((&fake_bi)); @@ -1334,11 +1357,19 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start) */ if (get_property(node, "interrupt-controller", &l)) { int i,j; + int cvt_irq; + + /* XXX on chrp, offset interrupt numbers for the + 8259 by 0, those for the openpic by 16 */ + cvt_irq = _machine == _MACH_chrp + && get_property(node, "interrupt-parent", NULL) == 0; np->intrs = (struct interrupt_info *) mem_start; np->n_intrs = ipsize / isize; mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *interrupts++; + if (cvt_irq) + np->intrs[i].line = openpic_to_irq(np->intrs[i].line); np->intrs[i].sense = 0; if (isize > 1) np->intrs[i].sense = *interrupts++; @@ -2072,7 +2103,6 @@ abort() * changes. */ -__init void map_bootx_text(void) { @@ -2083,7 +2113,10 @@ map_bootx_text(void) offset = ((unsigned long) disp_bi->dispDeviceBase) - base; size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset + disp_bi->dispDeviceRect[0]; - disp_bi->logicalDisplayBase = ioremap(base, size) + offset; + disp_bi->logicalDisplayBase = ioremap(base, size); + if (disp_bi->logicalDisplayBase == 0) + return; + disp_bi->logicalDisplayBase += offset; bootx_text_mapped = 1; } @@ -2102,6 +2135,35 @@ calc_base(boot_infos_t *bi, int x, int y) return base; } +/* Adjust the display to a new resolution */ +void +bootx_update_display(unsigned long phys, int width, int height, + int depth, int pitch) +{ + if (disp_bi == 0) + return; + /* check it's the same frame buffer (within 16MB) */ + if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xff000000) + return; + + disp_bi->dispDeviceBase = (__u8 *) phys; + disp_bi->dispDeviceRect[0] = 0; + disp_bi->dispDeviceRect[1] = 0; + disp_bi->dispDeviceRect[2] = width; + disp_bi->dispDeviceRect[3] = height; + disp_bi->dispDeviceDepth = depth; + disp_bi->dispDeviceRowBytes = pitch; + if (bootx_text_mapped) { + iounmap(disp_bi->logicalDisplayBase); + bootx_text_mapped = 0; + } + map_bootx_text(); + g_loc_X = 0; + g_loc_Y = 0; + g_max_loc_X = width / 8; + g_max_loc_Y = height / 16; +} + __pmac static void clearscreen(void) @@ -2162,6 +2224,9 @@ scrollscreen(void) (bi->dispDeviceDepth >> 3)) >> 2; int i,j; +#ifdef CONFIG_ADB_PMU + pmu_suspend(); /* PMU will not shut us down ! */ +#endif for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1] - 16); i++) { unsigned long *src_ptr = src; @@ -2178,6 +2243,9 @@ scrollscreen(void) *(dst_ptr++) = 0; dst += (bi->dispDeviceRowBytes >> 2); } +#ifdef CONFIG_ADB_PMU + pmu_resume(); /* PMU will not shut us down ! */ +#endif } #endif /* ndef NO_SCROLL */ diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 67387cca0..6bafa57c1 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -35,6 +35,8 @@ #include <asm/bootx.h> #include <asm/machdep.h> #include <asm/feature.h> +#include <asm/uaccess.h> + #ifdef CONFIG_OAK #include "oak_setup.h" #endif /* CONFIG_OAK */ @@ -655,16 +657,18 @@ int parse_bootinfo(void) } /* Checks "l2cr=xxxx" command-line option */ -void ppc_setup_l2cr(char *str, int *ints) +int ppc_setup_l2cr(char *str) { if ( ((_get_PVR() >> 16) == 8) || ((_get_PVR() >> 16) == 12) ) { unsigned long val = simple_strtoul(str, NULL, 0); printk(KERN_INFO "l2cr set to %lx\n", val); - _set_L2CR(0); - _set_L2CR(val); + _set_L2CR(0); /* force invalidate by disable cache */ + _set_L2CR(val); /* and enable it */ } + return 1; } +__setup("l2cr=", ppc_setup_l2cr); void __init ppc_init(void) { @@ -683,6 +687,9 @@ void __init setup_arch(char **cmdline_p) extern char *klimit; extern void do_init_bootmem(void); + /* so udelay does something sensible, assume <= 1000 bogomips */ + loops_per_sec = 500000000; + #ifdef CONFIG_ALL_PPC feature_init(); #endif @@ -737,6 +744,7 @@ void __init setup_arch(char **cmdline_p) if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); paging_init(); + sort_exception_table(); } void ppc_generic_ide_fix_driveid(struct hd_driveid *id) diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index 79847fa0d..dd3d1ae1b 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c @@ -154,7 +154,7 @@ sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6, } -asmlinkage int +int sys_sigaltstack(const stack_t *uss, stack_t *uoss) { struct pt_regs *regs = (struct pt_regs *) &uss; @@ -232,7 +232,7 @@ struct rt_sigframe * Each of these things must be a multiple of 16 bytes in size. * */ -asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) +int sys_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe *rt_sf; struct sigcontext_struct sigctx; @@ -301,7 +301,6 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) return ret; badframe: - lock_kernel(); do_exit(SIGSEGV); } @@ -351,7 +350,6 @@ badframe: printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp); #endif - lock_kernel(); do_exit(SIGSEGV); } @@ -418,7 +416,6 @@ int sys_sigreturn(struct pt_regs *regs) return ret; badframe: - lock_kernel(); do_exit(SIGSEGV); } @@ -460,7 +457,6 @@ badframe: printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp); #endif - lock_kernel(); do_exit(SIGSEGV); } @@ -541,7 +537,6 @@ badframe: regs, frame, *newspp); printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset); #endif - lock_kernel(); do_exit(SIGSEGV); } @@ -645,8 +640,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - lock_kernel(); - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); @@ -663,6 +657,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) /* Whee! Actually deliver the signal. */ handle_signal(signr, ka, &info, oldset, regs, &newsp, frame); + break; } if (regs->trap == 0x0C00 /* System Call! */ && diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index 8cb68c6b2..0a66d6c6b 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -62,72 +62,62 @@ volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; int start_secondary(void *); extern int cpu_idle(void *unused); u_int openpic_read(volatile u_int *addr); +void smp_call_function_interrupt(void); +void smp_message_pass(int target, int msg, unsigned long data, int wait); +/* register for interrupting the primary processor on the powersurge */ +/* N.B. this is actually the ethernet ROM! */ +#define PSURGE_PRI_INTR 0xf3019000 /* register for interrupting the secondary processor on the powersurge */ -#define PSURGE_INTR ((volatile unsigned *)0xf80000c0) +#define PSURGE_SEC_INTR 0xf80000c0 +/* register for storing the start address for the secondary processor */ +#define PSURGE_START 0xf2800000 +/* virtual addresses for the above */ +volatile u32 *psurge_pri_intr; +volatile u32 *psurge_sec_intr; +volatile u32 *psurge_start; + +/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. */ +#define PPC_MSG_CALL_FUNCTION 0 +#define PPC_MSG_RESCHEDULE 1 +#define PPC_MSG_INVALIDATE_TLB 2 +#define PPC_MSG_XMON_BREAK 3 + +static inline void set_tb(unsigned int upper, unsigned int lower) +{ + mtspr(SPRN_TBWU, upper); + mtspr(SPRN_TBWL, lower); +} void smp_local_timer_interrupt(struct pt_regs * regs) { int cpu = smp_processor_id(); - extern void update_one_process(struct task_struct *,unsigned long, - unsigned long,unsigned long,int); - if (!--prof_counter[cpu]) { - int user=0,system=0; - struct task_struct * p = current; - - /* - * After doing the above, we need to make like - * a normal interrupt - otherwise timer interrupts - * ignore the global interrupt lock, which is the - * WrongThing (tm) to do. - */ - - if (user_mode(regs)) - user=1; - else - system=1; - - if (p->pid) { - update_one_process(p, 1, user, system, cpu); - - p->counter -= 1; - if (p->counter <= 0) { - p->counter = 0; - current->need_resched = 1; - } - if (p->nice > 0) { - kstat.cpu_nice += user; - kstat.per_cpu_nice[cpu] += user; - } else { - kstat.cpu_user += user; - kstat.per_cpu_user[cpu] += user; - } - kstat.cpu_system += system; - kstat.per_cpu_system[cpu] += system; - - } + if (!--prof_counter[cpu]) { + update_process_times(user_mode(regs)); prof_counter[cpu]=prof_multiplier[cpu]; } } -void smp_message_recv(int msg) +void smp_message_recv(int msg, struct pt_regs *regs) { ipi_count++; - switch( msg ) - { - case MSG_STOP_CPU: - __cli(); - while (1) ; + switch( msg ) { + case PPC_MSG_CALL_FUNCTION: + smp_call_function_interrupt(); break; - case MSG_RESCHEDULE: + case PPC_MSG_RESCHEDULE: current->need_resched = 1; break; - case MSG_INVALIDATE_TLB: + case PPC_MSG_INVALIDATE_TLB: _tlbia(); - case 0xf0f0: /* pmac syncing time bases - just return */ break; +#ifdef CONFIG_XMON + case PPC_MSG_XMON_BREAK: + xmon(regs); + break; +#endif /* CONFIG_XMON */ default: printk("SMP %d: smp_message_recv(): unknown msg %d\n", smp_processor_id(), msg); @@ -142,25 +132,38 @@ void smp_message_recv(int msg) * smp_message[]. * * This is because don't have several IPI's on the PowerSurge even though - * we do on the chrp. It would be nice to use actual IPI's such as with openpic - * rather than this. + * we do on the chrp. It would be nice to use actual IPI's such as with + * openpic rather than this. * -- Cort */ int pmac_smp_message[NR_CPUS]; -void pmac_smp_message_recv(void) +void pmac_smp_message_recv(struct pt_regs *regs) { - int msg = pmac_smp_message[smp_processor_id()]; - + int cpu = smp_processor_id(); + int msg; + /* clear interrupt */ - out_be32(PSURGE_INTR, ~0); - - /* make sure msg is for us */ - if ( msg == -1 ) return; + if (cpu == 1) + out_be32(psurge_sec_intr, ~0); + + if (smp_num_cpus < 2) + return; + + /* make sure there is a message there */ + msg = pmac_smp_message[cpu]; + if (msg == 0) + return; - smp_message_recv(msg); - /* reset message */ - pmac_smp_message[smp_processor_id()] = -1; + pmac_smp_message[cpu] = 0; + + smp_message_recv(msg - 1, regs); +} + +void +pmac_primary_intr(int irq, void *d, struct pt_regs *regs) +{ + pmac_smp_message_recv(regs); } /* @@ -171,7 +174,7 @@ void pmac_smp_message_recv(void) void smp_send_tlb_invalidate(int cpu) { if ( (_get_PVR()>>16) == 8 ) - smp_message_pass(MSG_ALL_BUT_SELF, MSG_INVALIDATE_TLB, 0, 0); + smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB, 0, 0); } void smp_send_reschedule(int cpu) @@ -187,18 +190,135 @@ void smp_send_reschedule(int cpu) */ /* 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, PPC_MSG_RESCHEDULE, 0, 0); +} + +#ifdef CONFIG_XMON +void smp_send_xmon_break(int cpu) +{ + smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0); +} +#endif /* CONFIG_XMON */ + +static void stop_this_cpu(void *dummy) +{ + __cli(); + while (1) + ; } void smp_send_stop(void) { - smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0); + smp_call_function(stop_this_cpu, NULL, 1, 0); + smp_num_cpus = 1; +} + +/* + * Structure and data for smp_call_function(). This is designed to minimise + * static memory requirements. It also looks cleaner. + * Stolen from the i386 version. + */ +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; + +static volatile struct call_data_struct { + void (*func) (void *info); + void *info; + atomic_t started; + atomic_t finished; + int wait; +} *call_data = NULL; + +/* + * this function sends a 'generic call function' IPI to all other CPUs + * in the system. + */ + +int smp_call_function (void (*func) (void *info), void *info, int nonatomic, + int wait) +/* + * [SUMMARY] Run a function on all other CPUs. + * <func> The function to run. This must be fast and non-blocking. + * <info> An arbitrary pointer to pass to the function. + * <nonatomic> currently unused. + * <wait> If true, wait (atomically) until function has completed on other CPUs. + * [RETURNS] 0 on success, else a negative status code. Does not return until + * remote CPUs are nearly ready to execute <<func>> or are or have executed. + * + * You must not call this function with disabled interrupts or from a + * hardware interrupt handler, you may call it from a bottom half handler. + */ +{ + struct call_data_struct data; + int ret = -1, cpus = smp_num_cpus-1; + int timeout; + + if (!cpus) + return 0; + + data.func = func; + data.info = info; + atomic_set(&data.started, 0); + data.wait = wait; + if (wait) + atomic_set(&data.finished, 0); + + spin_lock_bh(&call_lock); + call_data = &data; + /* Send a message to all other CPUs and wait for them to respond */ + smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION, 0, 0); + + /* Wait for response */ + timeout = 1000000; + while (atomic_read(&data.started) != cpus) { + if (--timeout == 0) { + printk("smp_call_function on cpu %d: other cpus not responding (%d)\n", + smp_processor_id(), atomic_read(&data.started)); + goto out; + } + barrier(); + udelay(1); + } + + if (wait) { + timeout = 1000000; + while (atomic_read(&data.finished) != cpus) { + if (--timeout == 0) { + printk("smp_call_function on cpu %d: other cpus not finishing (%d/%d)\n", + smp_processor_id(), atomic_read(&data.finished), atomic_read(&data.started)); + goto out; + } + barrier(); + udelay(1); + } + } + ret = 0; + + out: + spin_unlock_bh(&call_lock); + return ret; +} + +void smp_call_function_interrupt(void) +{ + void (*func) (void *info) = call_data->func; + void *info = call_data->info; + int wait = call_data->wait; + + /* + * Notify initiating CPU that I've grabbed the data and am + * about to execute the function + */ + atomic_inc(&call_data->started); + /* + * At this point the info structure may be out of scope unless wait==1 + */ + (*func)(info); + if (wait) + atomic_inc(&call_data->finished); } void smp_message_pass(int target, int msg, unsigned long data, int wait) { - int i; - if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) ) return; @@ -212,31 +332,29 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait) * the recipient won't know the message was destined * for it. -- Cort */ - for ( i = 0; i <= smp_num_cpus ; i++ ) - pmac_smp_message[i] = -1; - switch( target ) - { - case MSG_ALL: - pmac_smp_message[smp_processor_id()] = msg; - /* fall through */ - case MSG_ALL_BUT_SELF: - for ( i = 0 ; i < smp_num_cpus ; i++ ) - if ( i != smp_processor_id () ) - pmac_smp_message[i] = msg; - break; - default: - pmac_smp_message[target] = msg; - break; + if (smp_processor_id() == 0) { + /* primary cpu */ + if (target == 1 || target == MSG_ALL_BUT_SELF + || target == MSG_ALL) { + pmac_smp_message[1] = msg + 1; + /* interrupt secondary processor */ + out_be32(psurge_sec_intr, ~0); + out_be32(psurge_sec_intr, 0); + } + } else { + /* secondary cpu */ + if (target == 0 || target == MSG_ALL_BUT_SELF + || target == MSG_ALL) { + pmac_smp_message[0] = msg + 1; + /* interrupt primary processor */ + in_be32(psurge_pri_intr); + } + } + if (target == smp_processor_id() || target == MSG_ALL) { + /* sending a message to ourself */ + /* XXX maybe we shouldn't do this if ints are off */ + smp_message_recv(msg, NULL); } - /* interrupt secondary processor */ - out_be32(PSURGE_INTR, ~0); - out_be32(PSURGE_INTR, 0); - /* - * Assume for now that the secondary doesn't send - * IPI's -- Cort - */ - /* interrupt primary */ - /**(volatile unsigned long *)(0xf3019000);*/ break; case _MACH_chrp: case _MACH_prep: @@ -261,7 +379,7 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait) #else /* CONFIG_POWER4 */ /* for now, only do reschedule messages since we only have one IPI */ - if (msg != MSG_RESCHEDULE) + if (msg != PPC_MSG_RESCHEDULE) break; for (i = 0; i < smp_num_cpus; ++i) { if (target == MSG_ALL || target == i @@ -319,7 +437,10 @@ void __init smp_boot_cpus(void) { case _MACH_Pmac: /* assume powersurge board - 2 processors -- Cort */ - cpu_nr = 2; + cpu_nr = 2; + psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); + psurge_sec_intr = ioremap(PSURGE_SEC_INTR, 4); + psurge_start = ioremap(PSURGE_START, 4); break; case _MACH_chrp: if (OpenPIC) @@ -347,7 +468,7 @@ void __init smp_boot_cpus(void) /* create a process for the processor */ /* we don't care about the values in regs since we'll never reschedule the forked task. */ - if (do_fork(CLONE_VM|CLONE_PID, 0, ®s) < 0) + if (do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0) < 0) panic("failed fork for CPU %d", i); p = init_task.prev_task; if (!p) @@ -370,13 +491,11 @@ void __init smp_boot_cpus(void) { case _MACH_Pmac: /* setup entry point of secondary processor */ - *(volatile unsigned long *)(0xf2800000) = - (unsigned long)__secondary_start_psurge-KERNELBASE; - eieio(); + out_be32(psurge_start, __pa(__secondary_start_psurge)); /* interrupt secondary to begin executing code */ - out_be32(PSURGE_INTR, ~0); + out_be32(psurge_sec_intr, ~0); udelay(1); - out_be32(PSURGE_INTR, 0); + out_be32(psurge_sec_intr, 0); break; case _MACH_chrp: *(unsigned long *)KERNELBASE = i; @@ -399,9 +518,6 @@ void __init smp_boot_cpus(void) if ( cpu_callin_map[i] ) { printk("Processor %d found.\n", i); - /* this sync's the decr's -- Cort */ - if ( _machine == _MACH_Pmac ) - set_dec(decrementer_count); smp_num_cpus++; } else { printk("Processor %d is stuck.\n", i); @@ -415,9 +531,25 @@ void __init smp_boot_cpus(void) { /* reset the entry point so if we get another intr we won't * try to startup again */ - *(volatile unsigned long *)(0xf2800000) = 0x100; - /* send interrupt to other processors to start decr's on all cpus */ - smp_message_pass(1,0xf0f0, 0, 0); + out_be32(psurge_start, 0x100); + if (request_irq(30, pmac_primary_intr, 0, "primary IPI", 0)) + printk(KERN_ERR "Couldn't get primary IPI interrupt"); + /* + * The decrementers of both cpus are frozen at this point + * until we give the secondary cpu another interrupt. + * We set them both to decrementer_count and then send + * the interrupt. This should get the decrementers + * synchronized. + * -- paulus. + */ + set_dec(tb_ticks_per_jiffy); + if ((_get_PVR() >> 16) != 1) { + set_tb(0, 0); /* set timebase if not 601 */ + last_jiffy_stamp(0) = 0; + } + out_be32(psurge_sec_intr, ~0); + udelay(1); + out_be32(psurge_sec_intr, 0); } } @@ -447,8 +579,11 @@ int __init start_secondary(void *unused) void __init smp_callin(void) { smp_store_cpu_info(current->processor); - set_dec(decrementer_count); - + set_dec(tb_ticks_per_jiffy); + if (_machine == _MACH_Pmac && (_get_PVR() >> 16) != 1) { + set_tb(0, 0); /* set timebase if not 601 */ + last_jiffy_stamp(current->processor) = 0; + } init_idle(); cpu_callin_map[current->processor] = 1; diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c index 314c1240c..d0fee4344 100644 --- a/arch/ppc/kernel/syscalls.c +++ b/arch/ppc/kernel/syscalls.c @@ -45,7 +45,7 @@ check_bugs(void) { } -asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on) +int sys_ioperm(unsigned long from, unsigned long num, int on) { printk(KERN_ERR "sys_ioperm()\n"); return -EIO; @@ -74,7 +74,7 @@ int sys_modify_ldt(int a1, int a2, int a3, int a4) * * This is really horribly ugly. */ -asmlinkage int +int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) { int version, ret; @@ -172,7 +172,7 @@ sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way unix traditionally does this, though. */ -asmlinkage int sys_pipe(int *fildes) +int sys_pipe(int *fildes) { int fd[2]; int error; @@ -185,19 +185,19 @@ asmlinkage int sys_pipe(int *fildes) return error; } -asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, off_t offset) +unsigned long sys_mmap(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, off_t offset) { struct file * file = NULL; int ret = -EBADF; + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); if (!(flags & MAP_ANONYMOUS)) { if (!(file = fget(fd))) goto out; } - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); down(¤t->mm->mmap_sem); ret = do_mmap(file, addr, len, prot, flags, offset); up(¤t->mm->mmap_sem); @@ -207,7 +207,7 @@ out: return ret; } -extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +extern int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); /* * Due to some executables calling the wrong select we sometimes @@ -215,7 +215,7 @@ extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timev * (a single ptr to them all args passed) then calls * sys_select() with the appropriate args. -- Cort */ -asmlinkage int +int ppc_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp) { if ( (unsigned long)n >= 4096 ) @@ -232,14 +232,14 @@ ppc_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp) return sys_select(n, inp, outp, exp, tvp); } -asmlinkage int sys_pause(void) +int sys_pause(void) { current->state = TASK_INTERRUPTIBLE; schedule(); return -ERESTARTNOHAND; } -asmlinkage int sys_uname(struct old_utsname * name) +int sys_uname(struct old_utsname * name) { int err = -EFAULT; @@ -250,7 +250,7 @@ asmlinkage int sys_uname(struct old_utsname * name) return err; } -asmlinkage int sys_olduname(struct oldold_utsname * name) +int sys_olduname(struct oldold_utsname * name) { int error; diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index aff4838b3..f71c8cbbf 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -6,6 +6,27 @@ * Paul Mackerras' version and mine for PReP and Pmac. * MPC8xx/MBX changes by Dan Malek (dmalek@jlc.net). * + * First round of bugfixes by Gabriel Paubert (paubert@iram.es) + * to make clock more stable (2.4.0-test5). The only thing + * that this code assumes is that the timebases have been synchronized + * by firmware on SMP and are never stopped (never do sleep + * on SMP then, nap and doze are OK). + * + * TODO (not necessarily in this file): + * - improve precision and reproducibility of timebase frequency + * measurement at boot time. + * - get rid of xtime_lock for gettimeofday (generic kernel problem + * to be implemented on all architectures for SMP scalability and + * eventually implementing gettimeofday without entering the kernel). + * - put all time/clock related variables in a single structure + * to minimize number of cache lines touched by gettimeofday() + * - for astronomical applications: add a new function to get + * non ambiguous timestamps even around leap seconds. This needs + * a new timestamp format and a good name. + * + * + * The following comment is partially obsolete (at least the long wait + * is no more a valid reason): * Since the MPC8xx has a programmable interrupt timer, I decided to * use that rather than the decrementer. Two reasons: 1.) the clock * frequency is low, causing 2.) a long wait in the timer interrupt @@ -49,18 +70,32 @@ void smp_local_timer_interrupt(struct pt_regs *); /* keep track of when we need to update the rtc */ -time_t last_rtc_update = 0; +time_t last_rtc_update; extern rwlock_t xtime_lock; /* The decrementer counts down by 128 every 128ns on a 601. */ #define DECREMENTER_COUNT_601 (1000000000 / HZ) -#define COUNT_PERIOD_NUM_601 1 -#define COUNT_PERIOD_DEN_601 1000 -unsigned decrementer_count; /* count value for 1e6/HZ microseconds */ -unsigned count_period_num; /* 1 decrementer count equals */ -unsigned count_period_den; /* count_period_num / count_period_den us */ -unsigned long last_tb; +unsigned tb_ticks_per_jiffy; +unsigned tb_to_us; +unsigned tb_last_stamp; + +extern unsigned long wall_jiffies; + +static long time_offset; + +/* Timer interrupt helper function */ +static inline int tb_delta(unsigned *jiffy_stamp) { + int delta; + if (__USE_RTC()) { + delta = get_rtcl(); + if (delta < *jiffy_stamp) *jiffy_stamp -= 1000000000; + delta -= *jiffy_stamp; + } else { + delta = get_tbl() - *jiffy_stamp; + } + return delta; +} /* * timer_interrupt - gets called when the decrementer overflows, @@ -69,88 +104,56 @@ unsigned long last_tb; */ int timer_interrupt(struct pt_regs * regs) { - int dval, d; -#if 0 - unsigned long flags; -#endif + int next_dec; unsigned long cpu = smp_processor_id(); - + unsigned jiffy_stamp = last_jiffy_stamp(cpu); + hardirq_enter(cpu); -#ifdef CONFIG_SMP - { - unsigned int loops = 100000000; - while (test_bit(0, &global_irq_lock)) { - if (smp_processor_id() == global_irq_holder) { - printk("uh oh, interrupt while we hold global irq lock!\n"); -#ifdef CONFIG_XMON - xmon(0); -#endif - break; - } - if (loops-- == 0) { - printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder); -#ifdef CONFIG_XMON - xmon(0); -#endif - } - } - } -#endif /* CONFIG_SMP */ - dval = get_dec(); - /* - * Wait for the decrementer to change, then jump - * in and add decrementer_count to its value - * (quickly, before it changes again!) - */ - while ((d = get_dec()) == dval) - ; - asm volatile("mftb %0" : "=r" (last_tb) ); - /* - * Don't play catchup between the call to time_init() - * and sti() in init/main.c. - * - * This also means if we're delayed for > HZ - * we lose those ticks. If we're delayed for > HZ - * then we have something wrong anyway, though. - * - * -- Cort - */ - if ( d < (-1*decrementer_count) ) - d = 0; - set_dec(d + decrementer_count); - if ( !smp_processor_id() ) - { + do { + jiffy_stamp += tb_ticks_per_jiffy; + if (smp_processor_id()) continue; + /* We are in an interrupt, no need to save/restore flags */ + write_lock(&xtime_lock); + tb_last_stamp = jiffy_stamp; do_timer(regs); -#if 0 - /* -- BenH -- I'm removing this for now since it can cause various - * troubles with local-time RTCs. Now that we have a - * /dev/rtc that uses ppc_md.set_rtc_time() on mac, it - * should be possible to program the RTC from userland - * in all cases. - */ + /* - * update the rtc when needed + * update the rtc when needed, this should be performed on the + * right fraction of a second. Half or full second ? + * Full second works on mk48t59 clocks, others need testing. + * Note that this update is basically only used through + * the adjtimex system calls. Setting the HW clock in + * any other way is a /dev/rtc and userland business. + * This is still wrong by -0.5/+1.5 jiffies because of the + * timer interrupt resolution and possible delay, but here we + * hit a quantization limit which can only be solved by higher + * resolution timers and decoupling time management from timer + * interrupts. This is also wrong on the clocks + * which require being written at the half second boundary. + * We should have an rtc call that only sets the minutes and + * seconds like on Intel to avoid problems with non UTC clocks. */ - read_lock_irqsave(&xtime_lock, flags); - if ( (time_status & STA_UNSYNC) && - ((xtime.tv_sec > last_rtc_update + 60) || - (xtime.tv_sec < last_rtc_update)) ) - { - if (ppc_md.set_rtc_time(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; + if ( (time_status & STA_UNSYNC) == 0 && + xtime.tv_sec - last_rtc_update >= 659 && + abs(xtime.tv_usec - (1000000-1000000/HZ)) < 500000/HZ && + jiffies - wall_jiffies == 1) { + if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0) + last_rtc_update = xtime.tv_sec+1; else - /* do it again in 60 s */ - last_rtc_update = xtime.tv_sec; + /* Try again one minute later */ + last_rtc_update += 60; } - read_unlock_irqrestore(&xtime_lock, flags); -#endif - } + write_unlock(&xtime_lock); + } while((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0); + set_dec(next_dec); + last_jiffy_stamp(cpu) = jiffy_stamp; + #ifdef CONFIG_SMP smp_local_timer_interrupt(regs); #endif - if ( ppc_md.heartbeat && !ppc_md.heartbeat_count--) + if (ppc_md.heartbeat && !ppc_md.heartbeat_count--) ppc_md.heartbeat(); hardirq_exit(cpu); @@ -162,106 +165,138 @@ int timer_interrupt(struct pt_regs * regs) */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags, diff; + unsigned long flags; + unsigned delta, lost_ticks, usec, sec; - save_flags(flags); - cli(); read_lock_irqsave(&xtime_lock, flags); - *tv = xtime; + sec = xtime.tv_sec; + usec = xtime.tv_usec; + delta = tb_ticks_since(tb_last_stamp); +#ifdef CONFIG_SMP + /* As long as timebases are not in sync, gettimeofday can only + * have jiffy resolution on SMP. + */ + if (_machine != _MACH_Pmac) + delta = 0; +#endif /* CONFIG_SMP */ + lost_ticks = jiffies - wall_jiffies; read_unlock_irqrestore(&xtime_lock, flags); - /* XXX we don't seem to have the decrementers synced properly yet */ -#ifndef CONFIG_SMP - asm volatile("mftb %0" : "=r" (diff) ); - diff -= last_tb; - tv->tv_usec += diff * count_period_num / count_period_den; - tv->tv_sec += tv->tv_usec / 1000000; - tv->tv_usec = tv->tv_usec % 1000000; -#endif - - restore_flags(flags); + + usec += mulhwu(tb_to_us, tb_ticks_per_jiffy * lost_ticks + delta); + while (usec > 1000000) { + sec++; + usec -= 1000000; + } + tv->tv_sec = sec; + tv->tv_usec = usec; } void do_settimeofday(struct timeval *tv) { unsigned long flags; - int frac_tick; - - last_rtc_update = 0; /* so the rtc gets updated soon */ - - frac_tick = tv->tv_usec % (1000000 / HZ); - save_flags(flags); - cli(); + int tb_delta, new_usec, new_sec; + write_lock_irqsave(&xtime_lock, flags); - xtime.tv_sec = tv->tv_sec; - xtime.tv_usec = tv->tv_usec - frac_tick; - write_unlock_irqrestore(&xtime_lock, flags); - set_dec(frac_tick * count_period_den / count_period_num); + /* Updating the RTC is not the job of this code. If the time is + * stepped under NTP, the RTC will be update after STA_UNSYNC + * is cleared. Tool like clock/hwclock either copy the RTC + * to the system time, in which case there is no point in writing + * to the RTC again, or write to the RTC but then they don't call + * settimeofday to perform this operation. Note also that + * we don't touch the decrementer since: + * a) it would lose timer interrupt synchronization on SMP + * (if it is working one day) + * b) it could make one jiffy spuriously shorter or longer + * which would introduce another source of uncertainty potentially + * harmful to relatively short timers. + */ + + /* This works perfectly on SMP only if the tb are in sync but + * guarantees an error < 1 jiffy even if they are off by eons, + * still reasonable when gettimeofday resolution is 1 jiffy. + */ + tb_delta = tb_ticks_since(last_jiffy_stamp(smp_processor_id())); + tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy; + new_sec = tv->tv_sec; + new_usec = tv->tv_usec - mulhwu(tb_to_us, tb_delta); + while (new_usec <0) { + new_sec--; + new_usec += 1000000; + } + xtime.tv_usec = new_usec; + xtime.tv_sec = new_sec; + + /* In case of a large backwards jump in time with NTP, we want the + * clock to be updated as soon as the PLL is again in lock. + */ + last_rtc_update = new_sec - 658; + time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_state = TIME_ERROR; /* p. 24, (a) */ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - restore_flags(flags); + write_unlock_irqrestore(&xtime_lock, flags); } void __init time_init(void) { + time_t sec, old_sec; + unsigned old_stamp, stamp, elapsed; + /* This function is only called on the boot processor */ unsigned long flags; + if (ppc_md.time_init != NULL) - { - ppc_md.time_init(); - } + time_offset = ppc_md.time_init(); - if ((_get_PVR() >> 16) == 1) { + if (__USE_RTC()) { /* 601 processor: dec counts down by 128 every 128ns */ - decrementer_count = DECREMENTER_COUNT_601; - count_period_num = COUNT_PERIOD_NUM_601; - count_period_den = COUNT_PERIOD_DEN_601; - } else if (!smp_processor_id()) { + tb_ticks_per_jiffy = DECREMENTER_COUNT_601; + /* mulhwu_scale_factor(1000000000, 1000000) is 0x418937 */ + tb_to_us = 0x418937; + } else { ppc_md.calibrate_decr(); } + /* Now that the decrementer is calibrated, it can be used in case the + * clock is stuck, but the fact that we have to handle the 601 + * makes things more complex. Repeatedly read the RTC until the + * next second boundary to try to achieve some precision... + */ + stamp = get_native_tbl(); + sec = ppc_md.get_rtc_time(); + elapsed = 0; + do { + old_stamp = stamp; + old_sec = sec; + stamp = get_native_tbl(); + if (__USE_RTC() && stamp < old_stamp) old_stamp -= 1000000000; + elapsed += stamp - old_stamp; + sec = ppc_md.get_rtc_time(); + } while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy); + if (sec==old_sec) { + printk("Warning: real time clock seems stuck!\n"); + } write_lock_irqsave(&xtime_lock, flags); - xtime.tv_sec = ppc_md.get_rtc_time(); + xtime.tv_sec = sec; + last_jiffy_stamp(0) = tb_last_stamp = stamp; xtime.tv_usec = 0; + /* No update now, we just read the time from the RTC ! */ + last_rtc_update = xtime.tv_sec; write_unlock_irqrestore(&xtime_lock, flags); + /* Not exact, but the timer interrupt takes care of this */ + set_dec(tb_ticks_per_jiffy); - set_dec(decrementer_count); - /* allow setting the time right away */ - last_rtc_update = 0; -} - -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ + /* If platform provided a timezone (pmac), we correct the time + * using do_sys_settimeofday() which in turn calls warp_clock() + */ + if (time_offset) { + struct timezone tz; + tz.tz_minuteswest = -time_offset / 60; + tz.tz_dsttime = 0; + do_sys_settimeofday(NULL, &tz); + } } #define TICK_SIZE tick @@ -354,3 +389,31 @@ void to_tm(int tim, struct rtc_time * tm) */ GregorianDay(tm); } + +/* Auxiliary function to compute scaling factors */ +/* Actually the choice of a timebase running at 1/4 the of the bus + * frequency giving resolution of a few tens of nanoseconds is quite nice. + * It makes this computation very precise (27-28 bits typically) which + * is optimistic considering the stability of most processor clock + * oscillators and the precision with which the timebase frequency + * is measured but does not harm. + */ +unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) { + unsigned mlt=0, tmp, err; + /* No concern for performance, it's done once: use a stupid + * but safe and compact method to find the multiplier. + */ + for (tmp = 1U<<31; tmp != 0; tmp >>= 1) { + if (mulhwu(inscale, mlt|tmp) < outscale) mlt|=tmp; + } + /* We might still be off by 1 for the best approximation. + * A side effect of this is that if outscale is too large + * the returned value will be zero. + * Many corner cases have been checked and seem to work, + * some might have been forgotten in the test however. + */ + err = inscale*(mlt+1); + if (err <= inscale/2) mlt++; + return mlt; +} + diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 0701f7118..3b7473dda 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -87,45 +87,76 @@ _exception(int signr, struct pt_regs *regs) void MachineCheckException(struct pt_regs *regs) { - if ( !user_mode(regs) ) - { -#if defined(CONFIG_8xx) && defined(CONFIG_PCI) - /* the qspan pci read routines can cause machine checks -- Cort */ - bad_page_fault(regs, regs->dar); +#ifdef CONFIG_ALL_PPC + unsigned long fixup; +#endif /* CONFIG_ALL_PPC */ + + if (user_mode(regs)) { + _exception(SIGSEGV, regs); return; + } + +#if defined(CONFIG_8xx) && defined(CONFIG_PCI) + /* the qspan pci read routines can cause machine checks -- Cort */ + bad_page_fault(regs, regs->dar); + return; #endif #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) - if (debugger_fault_handler) { - debugger_fault_handler(regs); - return; - } + if (debugger_fault_handler) { + debugger_fault_handler(regs); + return; + } #endif - printk("Machine check in kernel mode.\n"); - printk("Caused by (from SRR1=%lx): ", regs->msr); - switch (regs->msr & 0xF0000) { - case 0x80000: - printk("Machine check signal\n"); - break; - case 0x40000: - printk("Transfer error ack signal\n"); - break; - case 0x20000: - printk("Data parity error signal\n"); - break; - case 0x10000: - printk("Address parity error signal\n"); - break; - default: - printk("Unknown values in msr\n"); + +#ifdef CONFIG_ALL_PPC + /* + * I/O accesses can cause machine checks on powermacs. + * Check if the NIP corresponds to the address of a sync + * instruction for which there is an entry in the exception + * table. + */ + if (regs->msr & (0x80000 | 0x40000) + && (fixup = search_exception_table(regs->nip)) != 0) { + /* + * Check that it's a sync instruction. + * As the address is in the exception table + * we should be able to read the instr there. + */ + if (*(unsigned int *)regs->nip == 0x7c0004ac) { + unsigned int lsi = ((unsigned int *)regs->nip)[-1]; + int rb = (lsi >> 11) & 0x1f; + printk(KERN_DEBUG "%s bad port %lx at %lx\n", + (lsi & 0x100)? "OUT to": "IN from", + regs->gpr[rb] - _IO_BASE, regs->nip); + regs->nip = fixup; + return; } - show_regs(regs); + } +#endif /* CONFIG_ALL_PPC */ + printk("Machine check in kernel mode.\n"); + printk("Caused by (from SRR1=%lx): ", regs->msr); + switch (regs->msr & 0xF0000) { + case 0x80000: + printk("Machine check signal\n"); + break; + case 0x40000: + printk("Transfer error ack signal\n"); + break; + case 0x20000: + printk("Data parity error signal\n"); + break; + case 0x10000: + printk("Address parity error signal\n"); + break; + default: + printk("Unknown values in msr\n"); + } + show_regs(regs); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) - debugger(regs); + debugger(regs); #endif - print_backtrace((unsigned long *)regs->gpr[1]); - panic("machine check"); - } - _exception(SIGSEGV, regs); + print_backtrace((unsigned long *)regs->gpr[1]); + panic("machine check"); } void @@ -166,6 +197,46 @@ RunModeException(struct pt_regs *regs) _exception(SIGTRAP, regs); } +/* Illegal instruction emulation support. Originally written to + * provide the PVR to user applications using the mfspr rd, PVR. + * Return non-zero if we can't emulate, or EFAULT if the associated + * memory access caused an access fault. Return zero on success. + * + * There are a couple of ways to do this, either "decode" the instruction + * or directly match lots of bits. In this case, matching lots of + * bits is faster and easier. + * + */ +#define INST_MFSPR_PVR 0x7c1f42a6 +#define INST_MFSPR_PVR_MASK 0xfc1fffff + +static int +emulate_instruction(struct pt_regs *regs) +{ + uint instword; + uint rd; + uint retval; + + retval = EFAULT; + + if (!user_mode(regs)) + return retval; + + if (get_user(instword, (uint *)(regs->nip))) + return retval; + + /* Emulate the mfspr rD, PVR. + */ + if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) { + rd = (instword >> 21) & 0x1f; + regs->gpr[rd] = _get_PVR(); + retval = 0; + } + if (retval == 0) + regs->nip += 4; + return(retval); +} + void ProgramCheckException(struct pt_regs *regs) { @@ -193,7 +264,14 @@ ProgramCheckException(struct pt_regs *regs) #endif _exception(SIGTRAP, regs); } else { - _exception(SIGILL, regs); + /* Try to emulate it if we should. */ + int errcode; + if ((errcode = emulate_instruction(regs))) { + if (errcode == EFAULT) + _exception(SIGBUS, regs); + else + _exception(SIGILL, regs); + } } #endif } diff --git a/arch/ppc/kernel/walnut_setup.c b/arch/ppc/kernel/walnut_setup.c index 768c36a94..e48a3e61a 100644 --- a/arch/ppc/kernel/walnut_setup.c +++ b/arch/ppc/kernel/walnut_setup.c @@ -226,10 +226,11 @@ walnut_halt(void) /* * Document me. */ -void __init +long __init walnut_time_init(void) { /* XXX - Implement me */ + return 0; } /* diff --git a/arch/ppc/kernel/xics.c b/arch/ppc/kernel/xics.c index a9772821b..2b277f952 100644 --- a/arch/ppc/kernel/xics.c +++ b/arch/ppc/kernel/xics.c @@ -166,7 +166,7 @@ xics_get_irq(struct pt_regs *regs) void xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs) { qirr_info(smp_processor_id()) = 0xff; - smp_message_recv(MSG_RESCHEDULE); + smp_message_recv(MSG_RESCHEDULE, regs); } void xics_cause_IPI(int cpu) diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S index 1c4f1f78e..a922b4361 100644 --- a/arch/ppc/lib/string.S +++ b/arch/ppc/lib/string.S @@ -9,13 +9,74 @@ * 2 of the License, or (at your option) any later version. */ #include "../kernel/ppc_asm.tmpl" +#include <linux/config.h> #include <asm/processor.h> #include <asm/errno.h> -CACHELINE_BYTES = 32 -LG_CACHELINE_BYTES = 5 -CACHELINE_MASK = 0x1f -CACHELINE_WORDS = 8 +#if defined(CONFIG_4xx) || defined(CONFIG_8xx) +#define CACHE_LINE_SIZE 16 +#define LG_CACHE_LINE_SIZE 4 +#define MAX_COPY_PREFETCH 1 +#elif !defined(CONFIG_PPC64BRIDGE) +#define CACHE_LINE_SIZE 32 +#define LG_CACHE_LINE_SIZE 5 +#define MAX_COPY_PREFETCH 4 +#else +#define CACHE_LINE_SIZE 128 +#define LG_CACHE_LINE_SIZE 7 +#define MAX_COPY_PREFETCH 1 +#endif /* CONFIG_4xx || CONFIG_8xx */ + +#define COPY_16_BYTES \ + lwz r7,4(r4); \ + lwz r8,8(r4); \ + lwz r9,12(r4); \ + lwzu r10,16(r4); \ + stw r7,4(r6); \ + stw r8,8(r6); \ + stw r9,12(r6); \ + stwu r10,16(r6) + +#define COPY_16_BYTES_WITHEX(n) \ +8 ## n ## 0: \ + lwz r7,4(r4); \ +8 ## n ## 1: \ + lwz r8,8(r4); \ +8 ## n ## 2: \ + lwz r9,12(r4); \ +8 ## n ## 3: \ + lwzu r10,16(r4); \ +8 ## n ## 4: \ + stw r7,4(r6); \ +8 ## n ## 5: \ + stw r8,8(r6); \ +8 ## n ## 6: \ + stw r9,12(r6); \ +8 ## n ## 7: \ + stwu r10,16(r6) + +#define COPY_16_BYTES_EXCODE(n) \ +9 ## n ## 0: \ + addi r5,r5,-(16 * n); \ + b 104f; \ +9 ## n ## 1: \ + addi r5,r5,-(16 * n); \ + b 105f; \ +.section __ex_table,"a"; \ + .align 2; \ + .long 8 ## n ## 0b,9 ## n ## 0b; \ + .long 8 ## n ## 1b,9 ## n ## 0b; \ + .long 8 ## n ## 2b,9 ## n ## 0b; \ + .long 8 ## n ## 3b,9 ## n ## 0b; \ + .long 8 ## n ## 4b,9 ## n ## 1b; \ + .long 8 ## n ## 5b,9 ## n ## 1b; \ + .long 8 ## n ## 6b,9 ## n ## 1b; \ + .long 8 ## n ## 7b,9 ## n ## 1b; \ +.text + +CACHELINE_BYTES = CACHE_LINE_SIZE +LG_CACHELINE_BYTES = LG_CACHE_LINE_SIZE +CACHELINE_MASK = (CACHE_LINE_SIZE-1) .globl strcpy strcpy: @@ -105,7 +166,14 @@ cacheable_memzero: bdnz 4b 3: mtctr r9 li r7,4 +#if !defined(CONFIG_8xx) 10: dcbz r7,r6 +#else +10: stw r4, 4(r6) + stw r4, 8(r6) + stw r4, 12(r6) + stw r4, 16(r6) +#endif addi r6,r6,CACHELINE_BYTES bdnz 10b clrlwi r5,r8,32-LG_CACHELINE_BYTES @@ -202,23 +270,24 @@ cacheable_memcpy: li r11,4 mtctr r0 beq 63f -53: dcbz r11,r6 - lwz r7,4(r4) - lwz r8,8(r4) - lwz r9,12(r4) - lwzu r10,16(r4) - stw r7,4(r6) - stw r8,8(r6) - stw r9,12(r6) - stwu r10,16(r6) - lwz r7,4(r4) - lwz r8,8(r4) - lwz r9,12(r4) - lwzu r10,16(r4) - stw r7,4(r6) - stw r8,8(r6) - stw r9,12(r6) - stwu r10,16(r6) +53: +#if !defined(CONFIG_8xx) + dcbz r11,r6 +#endif + COPY_16_BYTES +#if CACHE_LINE_SIZE >= 32 + COPY_16_BYTES +#if CACHE_LINE_SIZE >= 64 + COPY_16_BYTES + COPY_16_BYTES +#if CACHE_LINE_SIZE >= 128 + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES +#endif +#endif +#endif bdnz 53b 63: srwi. r0,r5,2 @@ -380,25 +449,59 @@ __copy_tofrom_user: 58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */ clrlwi r5,r5,32-LG_CACHELINE_BYTES li r11,4 - mtctr r0 beq 63f -53: dcbz r11,r6 -10: lwz r7,4(r4) -11: lwz r8,8(r4) -12: lwz r9,12(r4) -13: lwzu r10,16(r4) -14: stw r7,4(r6) -15: stw r8,8(r6) -16: stw r9,12(r6) -17: stwu r10,16(r6) -20: lwz r7,4(r4) -21: lwz r8,8(r4) -22: lwz r9,12(r4) -23: lwzu r10,16(r4) -24: stw r7,4(r6) -25: stw r8,8(r6) -26: stw r9,12(r6) -27: stwu r10,16(r6) + +#if !defined(CONFIG_8xx) + /* Here we decide how far ahead to prefetch the source */ +#if MAX_COPY_PREFETCH > 1 + /* Heuristically, for large transfers we prefetch + MAX_COPY_PREFETCH cachelines ahead. For small transfers + we prefetch 1 cacheline ahead. */ + cmpwi r0,MAX_COPY_PREFETCH + li r7,1 + li r3,4 + ble 111f + li r7,MAX_COPY_PREFETCH +111: mtctr r7 +112: dcbt r3,r4 + addi r3,r3,CACHELINE_BYTES + bdnz 112b +#else /* MAX_COPY_PREFETCH == 1 */ + li r3,CACHELINE_BYTES + 4 + dcbt r11,r4 +#endif /* MAX_COPY_PREFETCH */ +#endif /* CONFIG_8xx */ + + mtctr r0 +53: +#if !defined(CONFIG_8xx) + dcbt r3,r4 + dcbz r11,r6 +#endif +/* had to move these to keep extable in order */ + .section __ex_table,"a" + .align 2 + .long 70b,100f + .long 71b,101f + .long 72b,102f + .long 73b,103f + .long 53b,105f + .text +/* the main body of the cacheline loop */ + COPY_16_BYTES_WITHEX(0) +#if CACHE_LINE_SIZE >= 32 + COPY_16_BYTES_WITHEX(1) +#if CACHE_LINE_SIZE >= 64 + COPY_16_BYTES_WITHEX(2) + COPY_16_BYTES_WITHEX(3) +#if CACHE_LINE_SIZE >= 128 + COPY_16_BYTES_WITHEX(4) + COPY_16_BYTES_WITHEX(5) + COPY_16_BYTES_WITHEX(6) + COPY_16_BYTES_WITHEX(7) +#endif +#endif +#endif bdnz 53b 63: srwi. r0,r5,2 @@ -434,15 +537,31 @@ __copy_tofrom_user: 103: li r4,1 91: li r3,2 b 99f -/* read fault in 2nd half of cacheline loop */ -106: addi r5,r5,-16 -/* read fault in 1st half of cacheline loop */ + +/* + * this stuff handles faults in the cacheline loop and branches to either + * 104f (if in read part) or 105f (if in write part), after updating r5 + */ + COPY_16_BYTES_EXCODE(0) +#if CACHE_LINE_SIZE >= 32 + COPY_16_BYTES_EXCODE(1) +#if CACHE_LINE_SIZE >= 64 + COPY_16_BYTES_EXCODE(2) + COPY_16_BYTES_EXCODE(3) +#if CACHE_LINE_SIZE >= 128 + COPY_16_BYTES_EXCODE(4) + COPY_16_BYTES_EXCODE(5) + COPY_16_BYTES_EXCODE(6) + COPY_16_BYTES_EXCODE(7) +#endif +#endif +#endif + +/* read fault in cacheline loop */ 104: li r4,0 b 92f -/* write fault in 2nd half of cacheline loop */ -107: addi r5,r5,-16 /* fault on dcbz (effectively a write fault) */ -/* or write fault in 1st half of cacheline loop */ +/* or write fault in cacheline loop */ 105: li r4,1 92: li r3,LG_CACHELINE_BYTES b 99f @@ -485,36 +604,15 @@ __copy_tofrom_user: bdnz 114b 120: blr -.section __ex_table,"a" + .section __ex_table,"a" .align 2 - .long 70b,100b - .long 71b,101b - .long 72b,102b - .long 73b,103b - .long 53b,105b - .long 10b,104b - .long 11b,104b - .long 12b,104b - .long 13b,104b - .long 14b,105b - .long 15b,105b - .long 16b,105b - .long 17b,105b - .long 20b,106b - .long 21b,106b - .long 22b,106b - .long 23b,106b - .long 24b,107b - .long 25b,107b - .long 26b,107b - .long 27b,107b .long 30b,108b .long 31b,109b .long 40b,110b .long 41b,111b .long 112b,120b .long 114b,120b -.text + .text .globl __clear_user __clear_user: @@ -546,12 +644,13 @@ __clear_user: blr 99: li r3,-EFAULT blr -.section __ex_table,"a" + + .section __ex_table,"a" .align 2 .long 11b,99b .long 1b,99b .long 8b,99b -.text + .text .globl __strncpy_from_user __strncpy_from_user: @@ -570,10 +669,11 @@ __strncpy_from_user: blr 99: li r3,-EFAULT blr -.section __ex_table,"a" + + .section __ex_table,"a" .align 2 .long 1b,99b -.text + .text /* r3 = str, r4 = len (> 0), r5 = top (highest addr) */ .globl __strnlen_user @@ -596,6 +696,7 @@ __strnlen_user: blr 99: li r3,0 /* bad address, return 0 */ blr -.section __ex_table,"a" + + .section __ex_table,"a" .align 2 .long 1b,99b diff --git a/arch/ppc/mbxboot/misc.c b/arch/ppc/mbxboot/misc.c index 60563122d..ac400b8c6 100644 --- a/arch/ppc/mbxboot/misc.c +++ b/arch/ppc/mbxboot/misc.c @@ -269,6 +269,11 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, b */ #ifdef CONFIG_MBX cmd_line = (char *)(load_addr - 0x10000); + + /* To be like everyone else, we need one too, although this + * board information is passed from the boot rom. + */ + bp->bi_baudrate = 9600; #else cmd_line = (char *)(0x200000); #endif diff --git a/arch/ppc/mm/extable.c b/arch/ppc/mm/extable.c index dc57bf868..f43bfaff4 100644 --- a/arch/ppc/mm/extable.c +++ b/arch/ppc/mm/extable.c @@ -4,11 +4,47 @@ * from linux/arch/i386/mm/extable.c */ +#include <linux/config.h> #include <linux/module.h> #include <asm/uaccess.h> -extern const struct exception_table_entry __start___ex_table[]; -extern const struct exception_table_entry __stop___ex_table[]; +extern struct exception_table_entry __start___ex_table[]; +extern struct exception_table_entry __stop___ex_table[]; + +/* + * The exception table needs to be sorted because we use the macros + * which put things into the exception table in a variety of segments + * such as the prep, pmac, chrp, etc. segments as well as the init + * segment and the main kernel text segment. + */ +static inline void +sort_ex_table(struct exception_table_entry *start, + struct exception_table_entry *finish) +{ + struct exception_table_entry el, *p, *q; + + /* insertion sort */ + for (p = start + 1; p < finish; ++p) { + /* start .. p-1 is sorted */ + if (p[0].insn < p[-1].insn) { + /* move element p down to its right place */ + el = *p; + q = p; + do { + /* el comes before q[-1], move q[-1] up one */ + q[0] = q[-1]; + --q; + } while (q > start && el.insn < q[-1].insn); + *q = el; + } + } +} + +void +sort_exception_table(void) +{ + sort_ex_table(__start___ex_table, __stop___ex_table); +} static inline unsigned long search_one_table(const struct exception_table_entry *first, @@ -36,25 +72,21 @@ search_exception_table(unsigned long addr) { unsigned long ret; -#if 1 /*ndef CONFIG_MODULES*/ +#ifndef CONFIG_MODULES /* There is only the kernel to search. */ ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr); if (ret) return ret; #else /* The kernel is the last "module" -- no need to treat it special. */ struct module *mp; - read_lock(&modlist_lock); for (mp = module_list; mp != NULL; mp = mp->next) { if (mp->ex_table_start == NULL) continue; ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, addr); - if (ret) { - read_unlock(&modlist_lock); + if (ret) return ret; - } } - read_unlock(&modlist_lock); #endif return 0; diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index 0b551c803..b6da2cdfc 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -67,7 +67,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, #if defined(CONFIG_4xx) int is_write = error_code & ESR_DST; #else - int is_write = error_code & 0x02000000; + int is_write = 0; /* * Fortunately the bit assignments in SRR1 for an instruction @@ -77,6 +77,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, */ if (regs->trap == 0x400) error_code &= 0x48200000; + else + is_write = error_code & 0x02000000; #endif /* CONFIG_4xx */ #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 67257c50b..be7d1f063 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -36,6 +36,7 @@ #include <linux/delay.h> #include <linux/openpic.h> #include <linux/bootmem.h> +#include <linux/highmem.h> #ifdef CONFIG_BLK_DEV_INITRD #include <linux/blk.h> /* for initrd_* */ #endif @@ -69,15 +70,20 @@ #include "4xx_tlb.h" #endif +#define MAX_LOW_MEM (640 << 20) + #define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10) int prom_trashed; atomic_t next_mmu_context; unsigned long *end_of_DRAM; +unsigned long total_memory; +unsigned long total_lowmem; int mem_init_done; int init_bootmem_done; int boot_mapsize; unsigned long totalram_pages = 0; +unsigned long totalhigh_pages = 0; extern pgd_t swapper_pg_dir[]; extern char _start[], _end[]; extern char etext[], _stext[]; @@ -98,22 +104,26 @@ extern unsigned int rtas_data, rtas_size; #ifndef CONFIG_SMP struct pgtable_cache_struct quicklists; #endif +#ifdef CONFIG_HIGHMEM +pte_t *kmap_pte; +pgprot_t kmap_prot; +#endif void MMU_init(void); static void *MMU_get_page(void); -unsigned long *prep_find_end_of_memory(void); -unsigned long *pmac_find_end_of_memory(void); -unsigned long *apus_find_end_of_memory(void); -unsigned long *gemini_find_end_of_memory(void); -extern unsigned long *find_end_of_memory(void); +unsigned long prep_find_end_of_memory(void); +unsigned long pmac_find_end_of_memory(void); +unsigned long apus_find_end_of_memory(void); +unsigned long gemini_find_end_of_memory(void); +extern unsigned long find_end_of_memory(void); #ifdef CONFIG_8xx -unsigned long *m8xx_find_end_of_memory(void); +unsigned long m8xx_find_end_of_memory(void); #endif /* CONFIG_8xx */ #ifdef CONFIG_4xx -unsigned long *oak_find_end_of_memory(void); +unsigned long oak_find_end_of_memory(void); #endif #ifdef CONFIG_8260 -unsigned long *m8260_find_end_of_memory(void); +unsigned long m8260_find_end_of_memory(void); #endif /* CONFIG_8260 */ static void mapin_ram(void); void map_page(unsigned long va, unsigned long pa, int flags); @@ -269,6 +279,7 @@ void show_mem(void) int i,free = 0,total = 0,reserved = 0; int shared = 0, cached = 0; struct task_struct *p; + int highmem = 0; printk("Mem-info:\n"); show_free_areas(); @@ -276,6 +287,8 @@ void show_mem(void) i = max_mapnr; while (i-- > 0) { total++; + if (PageHighMem(mem_map+i)) + highmem++; if (PageReserved(mem_map+i)) reserved++; else if (PageSwapCache(mem_map+i)) @@ -286,6 +299,7 @@ void show_mem(void) shared += atomic_read(&mem_map[i].count) - 1; } printk("%d pages of RAM\n",total); + printk("%d pages of HIGHMEM\n", highmem); printk("%d free pages\n",free); printk("%d reserved pages\n",reserved); printk("%d pages shared\n",shared); @@ -354,6 +368,8 @@ void si_meminfo(struct sysinfo *val) continue; val->sharedram += atomic_read(&mem_map[i].count) - 1; } + val->totalhigh = totalhigh_pages; + val->freehigh = nr_free_highpages(); val->mem_unit = PAGE_SIZE; } @@ -443,7 +459,8 @@ out: void iounmap(void *addr) { - /* XXX todo */ + if (addr > high_memory && (unsigned long) addr < ioremap_bot) + vfree((void *) (PAGE_MASK & (unsigned long) addr)); } unsigned long iopa(unsigned long addr) @@ -476,7 +493,7 @@ map_page(unsigned long va, unsigned long pa, int flags) { pmd_t *pd, oldpd; pte_t *pg; - + /* Use upper 10 bits of VA to index the first level map */ pd = pmd_offset(pgd_offset_k(va), va); oldpd = *pd; @@ -516,6 +533,7 @@ local_flush_tlb_all(void) flush_hash_segments(0xd, 0xffffff); #else __clear_user(Hash, Hash_size); + _tlbia(); #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); #endif /* CONFIG_SMP */ @@ -610,6 +628,13 @@ mmu_context_overflow(void) } #endif /* CONFIG_8xx */ +void flush_page_to_ram(struct page *page) +{ + unsigned long vaddr = kmap(page); + __flush_page_to_ram(vaddr); + kunmap(page); +} + #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) static void get_mem_prop(char *, struct mem_pieces *); @@ -722,7 +747,7 @@ static void __init mapin_ram(void) if (align && align < max_size) max_size = align; - tot = (unsigned long)end_of_DRAM - KERNELBASE; + tot = total_lowmem; for (bl = 128<<10; bl < max_size; bl <<= 1) { if (bl * 2 > tot) break; @@ -745,6 +770,8 @@ static void __init mapin_ram(void) for (i = 0; i < phys_mem.n_regions; ++i) { v = (ulong)__va(phys_mem.regions[i].address); p = phys_mem.regions[i].address; + if (p >= total_lowmem) + break; for (s = 0; s < phys_mem.regions[i].size; s += PAGE_SIZE) { /* On the MPC8xx, we want the page shared so we * don't get ASID compares on kernel space. @@ -766,6 +793,8 @@ static void __init mapin_ram(void) map_page(v, p, f); v += PAGE_SIZE; p += PAGE_SIZE; + if (p >= total_lowmem) + break; } } } @@ -788,77 +817,42 @@ static void __init *MMU_get_page(void) return p; } -void __init free_initmem(void) +static void free_sec(unsigned long start, unsigned long end, const char *name) { - unsigned long a; - unsigned long num_freed_pages = 0, num_prep_pages = 0, - num_pmac_pages = 0, num_openfirmware_pages = 0, - num_apus_pages = 0, num_chrp_pages = 0; -#define FREESEC(START,END,CNT) do { \ - a = (unsigned long)(&START); \ - for (; a < (unsigned long)(&END); a += PAGE_SIZE) { \ - clear_bit(PG_reserved, &virt_to_page(a)->flags); \ - set_page_count(virt_to_page(a), 1); \ - free_page(a); \ - CNT++; \ - } \ -} while (0) - - FREESEC(__init_begin,__init_end,num_freed_pages); - switch (_machine) - { - case _MACH_Pmac: - FREESEC(__apus_begin,__apus_end,num_apus_pages); - FREESEC(__prep_begin,__prep_end,num_prep_pages); - FREESEC(__chrp_begin,__chrp_end,num_chrp_pages); - break; - case _MACH_chrp: - FREESEC(__apus_begin,__apus_end,num_apus_pages); - FREESEC(__pmac_begin,__pmac_end,num_pmac_pages); - FREESEC(__prep_begin,__prep_end,num_prep_pages); - break; - case _MACH_prep: - FREESEC(__apus_begin,__apus_end,num_apus_pages); - FREESEC(__pmac_begin,__pmac_end,num_pmac_pages); - FREESEC(__chrp_begin,__chrp_end,num_chrp_pages); - break; - case _MACH_mbx: - FREESEC(__apus_begin,__apus_end,num_apus_pages); - FREESEC(__pmac_begin,__pmac_end,num_pmac_pages); - FREESEC(__prep_begin,__prep_end,num_prep_pages); - FREESEC(__chrp_begin,__chrp_end,num_chrp_pages); - break; - case _MACH_apus: - FREESEC(__pmac_begin,__pmac_end,num_pmac_pages); - FREESEC(__prep_begin,__prep_end,num_prep_pages); - FREESEC(__chrp_begin,__chrp_end,num_chrp_pages); - break; - case _MACH_gemini: - FREESEC(__apus_begin,__apus_end,num_apus_pages); - FREESEC(__pmac_begin,__pmac_end,num_pmac_pages); - FREESEC(__prep_begin,__prep_end,num_prep_pages); - FREESEC(__chrp_begin,__chrp_end,num_chrp_pages); - break; - } + unsigned long cnt = 0; - if ( !have_of ) - FREESEC( __openfirmware_begin, __openfirmware_end, - num_openfirmware_pages ); - - printk ("Freeing unused kernel memory: %ldk init", - PGTOKB(num_freed_pages)); - - if ( num_prep_pages ) - printk(" %ldk prep", PGTOKB(num_prep_pages)); - if ( num_chrp_pages ) - printk(" %ldk chrp", PGTOKB(num_chrp_pages)); - if ( num_pmac_pages ) - printk(" %ldk pmac", PGTOKB(num_pmac_pages)); - if ( num_openfirmware_pages ) - printk(" %ldk open firmware", PGTOKB(num_openfirmware_pages)); - if ( num_apus_pages ) - printk(" %ldk apus", PGTOKB(num_apus_pages)); - printk("\n"); + while (start < end) { + clear_bit(PG_reserved, &virt_to_page(start)->flags); + set_page_count(virt_to_page(start), 1); + free_page(start); + cnt++; + start += PAGE_SIZE; + } + if (cnt) + printk(" %ldk %s", PGTOKB(cnt), name); +} + +void free_initmem(void) +{ +#define FREESEC(TYPE) \ + free_sec((unsigned long)(&__ ## TYPE ## _begin), \ + (unsigned long)(&__ ## TYPE ## _end), \ + #TYPE); + + printk ("Freeing unused kernel memory:"); + FREESEC(init); + if (_machine != _MACH_Pmac) + FREESEC(pmac); + if (_machine != _MACH_chrp) + FREESEC(chrp); + if (_machine != _MACH_prep) + FREESEC(prep); + if (_machine != _MACH_apus) + FREESEC(apus); + if (!have_of) + FREESEC(openfirmware); + printk("\n"); +#undef FREESEC } #ifdef CONFIG_BLK_DEV_INITRD @@ -909,7 +903,8 @@ MMU_init(void) * at KERNELBASE. */ - end_of_DRAM = oak_find_end_of_memory(); + total_memory = total_lowmem = oak_find_end_of_memory(); + end_of_DRAM = __va(total_memory); mapin_ram(); /* @@ -939,23 +934,33 @@ void __init MMU_init(void) if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111); #ifndef CONFIG_8xx if (have_of) - end_of_DRAM = pmac_find_end_of_memory(); + total_memory = pmac_find_end_of_memory(); #ifdef CONFIG_APUS else if (_machine == _MACH_apus ) - end_of_DRAM = apus_find_end_of_memory(); + total_memory = apus_find_end_of_memory(); #endif #ifdef CONFIG_GEMINI else if ( _machine == _MACH_gemini ) - end_of_DRAM = gemini_find_end_of_memory(); + total_memory = gemini_find_end_of_memory(); #endif /* CONFIG_GEMINI */ #if defined(CONFIG_8260) else - end_of_DRAM = m8260_find_end_of_memory(); + total_memory = m8260_find_end_of_memory(); #else else /* prep */ - end_of_DRAM = prep_find_end_of_memory(); + total_memory = prep_find_end_of_memory(); #endif + total_lowmem = total_memory; +#ifdef CONFIG_HIGHMEM + if (total_lowmem > MAX_LOW_MEM) { + total_lowmem = MAX_LOW_MEM; + mem_pieces_remove(&phys_avail, total_lowmem, + total_memory - total_lowmem, 0); + } +#endif /* CONFIG_HIGHMEM */ + end_of_DRAM = __va(total_lowmem); + if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300); hash_init(); #ifndef CONFIG_PPC64BRIDGE @@ -995,7 +1000,7 @@ void __init MMU_init(void) #endif break; case _MACH_Pmac: - ioremap_base = 0xf8000000; + ioremap_base = 0xfe000000; break; case _MACH_apus: /* Map PPC exception vectors. */ @@ -1022,7 +1027,15 @@ void __init MMU_init(void) #endif /* CONFIG_POWER4 */ #else /* CONFIG_8xx */ - end_of_DRAM = m8xx_find_end_of_memory(); + total_memory = total_lowmem = m8xx_find_end_of_memory(); +#ifdef CONFIG_HIGHMEM + if (total_lowmem > MAX_LOW_MEM) { + total_lowmem = MAX_LOW_MEM; + mem_pieces_remove(&phys_avail, total_lowmem, + total_memory - total_lowmem, 0); + } +#endif /* CONFIG_HIGHMEM */ + end_of_DRAM = __va(total_lowmem); /* Map in all of RAM starting at KERNELBASE */ mapin_ram(); @@ -1055,7 +1068,7 @@ void __init MMU_init(void) if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); #ifdef CONFIG_BOOTX_TEXT /* Must be done last, or ppc_md.progress will die */ - if (_machine == _MACH_Pmac) + if (_machine == _MACH_Pmac || _machine == _MACH_chrp) map_bootx_text(); #endif } @@ -1092,7 +1105,7 @@ void __init do_init_bootmem(void) start = PAGE_ALIGN(start); boot_mapsize = init_bootmem(start >> PAGE_SHIFT, - __pa(end_of_DRAM) >> PAGE_SHIFT); + total_lowmem >> PAGE_SHIFT); /* remove the bootmem bitmap from the available memory */ mem_pieces_remove(&phys_avail, start, boot_mapsize, 1); @@ -1105,47 +1118,6 @@ void __init do_init_bootmem(void) init_bootmem_done = 1; } -#if 0 -/* - * Find some memory for setup_arch to return. - * We use the largest chunk of available memory as the area - * that setup_arch returns, making sure that there are at - * least 32 pages unused before this for MMU_get_page to use. - */ -unsigned long __init find_available_memory(void) -{ - int i, rn; - unsigned long a, free; - unsigned long start, end; - - if (_machine == _MACH_mbx) { - /* Return the first, not the last region, because we - * may not yet have properly initialized the additonal - * memory DIMM. - */ - a = PAGE_ALIGN(phys_avail.regions[0].address); - avail_start = (unsigned long) __va(a); - return avail_start; - } - - rn = 0; - for (i = 1; i < phys_avail.n_regions; ++i) - if (phys_avail.regions[i].size > phys_avail.regions[rn].size) - rn = i; - free = 0; - for (i = 0; i < rn; ++i) { - start = phys_avail.regions[i].address; - end = start + phys_avail.regions[i].size; - free += (end & PAGE_MASK) - PAGE_ALIGN(start); - } - a = PAGE_ALIGN(phys_avail.regions[rn].address); - if (free < 32 * PAGE_SIZE) - a += 32 * PAGE_SIZE - free; - avail_start = (unsigned long) __va(a); - return avail_start; -} -#endif /* 0 */ - /* * paging_init() sets up the page tables - in fact we've already done this. */ @@ -1153,6 +1125,14 @@ void __init paging_init(void) { unsigned long zones_size[MAX_NR_ZONES], i; +#ifdef CONFIG_HIGHMEM + map_page(PKMAP_BASE, 0, 0); /* XXX gross */ + pkmap_page_table = pte_offset(pmd_offset(pgd_offset_k(PKMAP_BASE), PKMAP_BASE), PKMAP_BASE); + map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */ + kmap_pte = pte_offset(pmd_offset(pgd_offset_k(KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN); + kmap_prot = PAGE_KERNEL; +#endif /* CONFIG_HIGHMEM */ + /* * Grab some memory for bad_page and bad_pagetable to use. */ @@ -1162,9 +1142,14 @@ void __init paging_init(void) /* * All pages are DMA-able so we put them all in the DMA zone. */ - zones_size[0] = ((unsigned long)end_of_DRAM - KERNELBASE) >> PAGE_SHIFT; + zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; for (i = 1; i < MAX_NR_ZONES; i++) zones_size[i] = 0; + +#ifdef CONFIG_HIGHMEM + zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT; +#endif /* CONFIG_HIGHMEM */ + free_area_init(zones_size); } @@ -1176,7 +1161,17 @@ void __init mem_init(void) int codepages = 0; int datapages = 0; int initpages = 0; +#ifdef CONFIG_HIGHMEM + unsigned long highmem_mapnr; + + highmem_mapnr = total_lowmem >> PAGE_SHIFT; + highmem_start_page = mem_map + highmem_mapnr; + max_mapnr = total_memory >> PAGE_SHIFT; + totalram_pages += max_mapnr - highmem_mapnr; +#else max_mapnr = max_low_pfn; +#endif /* CONFIG_HIGHMEM */ + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); num_physpages = max_mapnr; /* RAM is assumed contiguous */ @@ -1217,11 +1212,28 @@ void __init mem_init(void) datapages++; } - printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08x,%08lx]\n", +#ifdef CONFIG_HIGHMEM + { + unsigned long pfn; + + for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) { + struct page *page = mem_map + pfn; + + ClearPageReserved(page); + set_bit(PG_highmem, &page->flags); + atomic_set(&page->count, 1); + __free_page(page); + totalhigh_pages++; + } + totalram_pages += totalhigh_pages; + } +#endif /* CONFIG_HIGHMEM */ + + printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n", (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10), codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10), initpages<< (PAGE_SHIFT-10), - PAGE_OFFSET, (unsigned long) end_of_DRAM); + (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); mem_init_done = 1; } @@ -1234,7 +1246,7 @@ void __init mem_init(void) * Our text, data, bss use something over 1MB, starting at 0. * Open Firmware may be using 1MB at the 4MB point. */ -unsigned long __init *pmac_find_end_of_memory(void) +unsigned long __init pmac_find_end_of_memory(void) { unsigned long a, total; unsigned long ram_limit = 0xe0000000 - KERNELBASE; @@ -1279,7 +1291,7 @@ unsigned long __init *pmac_find_end_of_memory(void) set_phys_avail(&phys_mem); - return __va(total); + return total; } #endif /* CONFIG_ALL_PPC */ @@ -1290,7 +1302,7 @@ unsigned long __init *pmac_find_end_of_memory(void) * this will likely stay separate from the pmac. * -- Cort */ -unsigned long __init *prep_find_end_of_memory(void) +unsigned long __init prep_find_end_of_memory(void) { unsigned long total; total = res->TotalMemory; @@ -1308,15 +1320,15 @@ unsigned long __init *prep_find_end_of_memory(void) mem_pieces_append(&phys_mem, 0, total); set_phys_avail(&phys_mem); - return (__va(total)); + return (total); } #endif /* defined(CONFIG_ALL_PPC) */ #if defined(CONFIG_GEMINI) -unsigned long __init *gemini_find_end_of_memory(void) +unsigned long __init gemini_find_end_of_memory(void) { - unsigned long total, *ret; + unsigned long total; unsigned char reg; reg = readb(GEMINI_MEMCFG); @@ -1327,9 +1339,8 @@ unsigned long __init *gemini_find_end_of_memory(void) phys_mem.regions[0].size = total; phys_mem.n_regions = 1; - ret = __va(phys_mem.regions[0].size); set_phys_avail(&phys_mem); - return ret; + return phys_mem.regions[0].size; } #endif /* defined(CONFIG_GEMINI) */ @@ -1337,10 +1348,9 @@ unsigned long __init *gemini_find_end_of_memory(void) /* * Same hack as 8xx. */ -unsigned long __init *m8260_find_end_of_memory(void) +unsigned long __init m8260_find_end_of_memory(void) { bd_t *binfo; - unsigned long *ret; extern unsigned char __res[]; binfo = (bd_t *)__res; @@ -1349,15 +1359,14 @@ unsigned long __init *m8260_find_end_of_memory(void) phys_mem.regions[0].size = binfo->bi_memsize; phys_mem.n_regions = 1; - ret = __va(phys_mem.regions[0].size); set_phys_avail(&phys_mem); - return ret; + return phys_mem.regions[0].size; } #endif /* CONFIG_8260 */ #ifdef CONFIG_APUS #define HARDWARE_MAPPED_SIZE (512*1024) -unsigned long __init *apus_find_end_of_memory(void) +unsigned long __init apus_find_end_of_memory(void) { int shadow = 0; @@ -1421,7 +1430,7 @@ unsigned long __init *apus_find_end_of_memory(void) the PowerUP board. Other system memory is horrible slow in comparison. The user can use other memory for swapping using the z2ram device. */ - return __va(memory[0].addr + memory[0].size); + return memory[0].addr + memory[0].size; } #endif /* CONFIG_APUS */ @@ -1484,7 +1493,7 @@ static void __init hash_init(void) /* Find some memory for the hash table. */ if ( Hash_size ) { Hash = mem_pieces_find(Hash_size, Hash_size); - /*__clear_user(Hash, Hash_size);*/ + cacheable_memzero(Hash, Hash_size); } else Hash = 0; #endif /* CONFIG_PPC64BRIDGE */ @@ -1544,10 +1553,9 @@ static void __init hash_init(void) * functions in the image just to get prom_init, all we really need right * now is the initialization of the physical memory region. */ -unsigned long __init *m8xx_find_end_of_memory(void) +unsigned long __init m8xx_find_end_of_memory(void) { bd_t *binfo; - unsigned long *ret; extern unsigned char __res[]; binfo = (bd_t *)__res; @@ -1555,12 +1563,9 @@ unsigned long __init *m8xx_find_end_of_memory(void) phys_mem.regions[0].address = 0; phys_mem.regions[0].size = binfo->bi_memsize; phys_mem.n_regions = 1; - - ret = __va(phys_mem.regions[0].address+ - phys_mem.regions[0].size); set_phys_avail(&phys_mem); - return ret; + return phys_mem.regions[0].address + phys_mem.regions[0].size; } #endif /* !CONFIG_4xx && !CONFIG_8xx */ @@ -1569,7 +1574,7 @@ unsigned long __init *m8xx_find_end_of_memory(void) * Return the virtual address representing the top of physical RAM * on the Oak board. */ -unsigned long __init * +unsigned long __init oak_find_end_of_memory(void) { extern unsigned char __res[]; @@ -1580,12 +1585,9 @@ oak_find_end_of_memory(void) phys_mem.regions[0].address = 0; phys_mem.regions[0].size = bip->bi_memsize; phys_mem.n_regions = 1; - - ret = __va(phys_mem.regions[0].address + - phys_mem.regions[0].size); set_phys_avail(&phys_mem); - return (ret); + return (phys_mem.regions[0].address + phys_mem.regions[0].size); } #endif diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c index a816f0b9d..499c5b6c8 100644 --- a/arch/ppc/xmon/start.c +++ b/arch/ppc/xmon/start.c @@ -8,6 +8,7 @@ #include <asm/page.h> #include <linux/adb.h> #include <linux/pmu.h> +#include <linux/cuda.h> #include <linux/kernel.h> #include <asm/prom.h> #include <asm/bootx.h> @@ -67,6 +68,12 @@ xmon_map_scc(void) use_screen = 1; } #endif +#ifdef CONFIG_ADB_CUDA + if (!via_modem && disp_bi ) { + prom_drawstring("xmon uses screen and keyboard\n"); + use_screen = 1; + } +#endif #endif #ifdef CHRP_ESCC @@ -100,6 +107,10 @@ xmon_map_scc(void) /* should already be mapped by the kernel boot */ sccc = (volatile unsigned char *) (isa_io_base + 0x3fd); sccd = (volatile unsigned char *) (isa_io_base + 0x3f8); + if (xmon_use_sccb) { + sccc -= 0x100; + sccd -= 0x100; + } TXRDY = 0x20; RXRDY = 1; } @@ -109,6 +120,19 @@ static int scc_initialized = 0; void xmon_init_scc(void); extern void pmu_poll(void); +extern void cuda_poll(void); + +static inline void do_poll_adb(void) +{ +#ifdef CONFIG_ADB_PMU + if (sys_ctrler == SYS_CTRLER_PMU) + pmu_poll(); +#endif /* CONFIG_ADB_PMU */ +#ifdef CONFIG_ADB_CUDA + if (sys_ctrler == SYS_CTRLER_CUDA) + cuda_poll(); +#endif /* CONFIG_ADB_CUDA */ +} int xmon_write(void *handle, void *ptr, int nb) @@ -128,12 +152,8 @@ xmon_write(void *handle, void *ptr, int nb) xmon_init_scc(); ct = 0; for (i = 0; i < nb; ++i) { - while ((*sccc & TXRDY) == 0) { -#ifdef CONFIG_ADB_PMU - if (sys_ctrler == SYS_CTRLER_PMU) - pmu_poll(); -#endif /* CONFIG_ADB_PMU */ - } + while ((*sccc & TXRDY) == 0) + do_poll_adb(); c = p[i]; if (c == '\n' && !ct) { c = '\r'; @@ -189,9 +209,7 @@ xmon_get_adb_key(void) prom_drawchar('\b'); t = 200000; } -#ifdef CONFIG_ADB_PMU - pmu_poll(); -#endif /* CONFIG_ADB_PMU */ + do_poll_adb(); } while (xmon_adb_keycode == -1); k = xmon_adb_keycode; if (on) @@ -230,14 +248,9 @@ xmon_read(void *handle, void *ptr, int nb) xmon_init_scc(); for (i = 0; i < nb; ++i) { while ((*sccc & RXRDY) == 0) -#ifdef CONFIG_ADB_PMU - if (sys_ctrler == SYS_CTRLER_PMU) - pmu_poll(); -#else - ; -#endif /* CONFIG_ADB_PMU */ + do_poll_adb(); buf_access(); - *p++ = *sccd; + *p++ = *sccd; } return i; } @@ -246,10 +259,7 @@ int xmon_read_poll(void) { if ((*sccc & RXRDY) == 0) { -#ifdef CONFIG_ADB_PMU - if (sys_ctrler == SYS_CTRLER_PMU) - pmu_poll(); -#endif /* CONFIG_ADB_PMU */ + do_poll_adb(); return -1; } buf_access(); @@ -491,3 +501,19 @@ xmon_fgets(char *str, int nb, void *f) *p = 0; return str; } + +void +xmon_enter(void) +{ +#ifdef CONFIG_ADB_PMU + pmu_suspend(); +#endif +} + +void +xmon_leave(void) +{ +#ifdef CONFIG_ADB_PMU + pmu_resume(); +#endif +} diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c index 75160d9b8..49c3be834 100644 --- a/arch/ppc/xmon/xmon.c +++ b/arch/ppc/xmon/xmon.c @@ -6,15 +6,23 @@ #include <linux/config.h> #include <linux/errno.h> #include <linux/sched.h> +#include <linux/smp.h> #include <asm/ptrace.h> #include <asm/string.h> #include <asm/prom.h> +#include <asm/bitops.h> #include "nonstdio.h" #include "privinst.h" #define scanhex xmon_scanhex #define skipbl xmon_skipbl +#ifdef CONFIG_SMP +static unsigned long cpus_in_xmon = 0; +static unsigned long got_xmon = 0; +static volatile int take_xmon = -1; +#endif /* CONFIG_SMP */ + static unsigned adrs; static int size = 1; static unsigned ndump = 64; @@ -84,6 +92,9 @@ static void insert_bpts(void); static struct bpt *at_breakpoint(unsigned pc); static void bpt_cmds(void); static void cacheflush(void); +#ifdef CONFIG_SMP +static void cpu_cmd(void); +#endif /* CONFIG_SMP */ #if 0 /* Makes compile with -Wall */ static char *pretty_print_addr(unsigned long addr); static char *lookup_name(unsigned long addr); @@ -96,8 +107,18 @@ extern int putchar(int ch); extern int setjmp(u_int *); extern void longjmp(u_int *, int); +extern void xmon_enter(void); +extern void xmon_leave(void); + #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) +#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ + || ('a' <= (c) && (c) <= 'f') \ + || ('A' <= (c) && (c) <= 'F')) +#define isalnum(c) (('0' <= (c) && (c) <= '9') \ + || ('a' <= (c) && (c) <= 'z') \ + || ('A' <= (c) && (c) <= 'Z')) + static char *help_string = "\ Commands:\n\ d dump bytes\n\ @@ -117,10 +138,12 @@ Commands:\n\ x exit monitor\n\ "; -static int xmon_trace; +static int xmon_trace[NR_CPUS]; #define SSTEP 1 /* stepping because of 's' command */ #define BRSTEP 2 /* stepping over breakpoint */ +static struct pt_regs *xmon_regs[NR_CPUS]; + void xmon(struct pt_regs *excp) { @@ -143,27 +166,52 @@ xmon(struct pt_regs *excp) msr = get_msr(); set_msr(msr & ~0x8000); /* disable interrupts */ - remove_bpts(); + xmon_regs[smp_processor_id()] = excp; + xmon_enter(); excprint(excp); +#ifdef CONFIG_SMP + if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon)) + for (;;) + ; + while (test_and_set_bit(0, &got_xmon)) { + if (take_xmon == smp_processor_id()) { + take_xmon = -1; + break; + } + } + /* + * XXX: breakpoints are removed while any cpu is in xmon + */ +#endif /* CONFIG_SMP */ + remove_bpts(); cmd = cmds(excp); if (cmd == 's') { - xmon_trace = SSTEP; + xmon_trace[smp_processor_id()] = SSTEP; excp->msr |= 0x400; } else if (at_breakpoint(excp->nip)) { - xmon_trace = BRSTEP; + xmon_trace[smp_processor_id()] = BRSTEP; excp->msr |= 0x400; } else { - xmon_trace = 0; + xmon_trace[smp_processor_id()] = 0; insert_bpts(); } + xmon_leave(); + xmon_regs[smp_processor_id()] = 0; +#ifdef CONFIG_SMP + clear_bit(0, &got_xmon); + clear_bit(smp_processor_id(), &cpus_in_xmon); +#endif /* CONFIG_SMP */ set_msr(msr); /* restore interrupt enable */ } void xmon_irq(int irq, void *d, struct pt_regs *regs) { + unsigned long flags; + save_flags(flags);cli(); printf("Keyboard interrupt\n"); xmon(regs); + restore_flags(flags); } int @@ -178,7 +226,7 @@ xmon_bpt(struct pt_regs *regs) --bp->count; remove_bpts(); excprint(regs); - xmon_trace = BRSTEP; + xmon_trace[smp_processor_id()] = BRSTEP; regs->msr |= 0x400; } else { xmon(regs); @@ -189,10 +237,10 @@ xmon_bpt(struct pt_regs *regs) int xmon_sstep(struct pt_regs *regs) { - if (!xmon_trace) + if (!xmon_trace[smp_processor_id()]) return 0; - if (xmon_trace == BRSTEP) { - xmon_trace = 0; + if (xmon_trace[smp_processor_id()] == BRSTEP) { + xmon_trace[smp_processor_id()] = 0; insert_bpts(); } else { xmon(regs); @@ -207,7 +255,7 @@ xmon_dabr_match(struct pt_regs *regs) --dabr.count; remove_bpts(); excprint(regs); - xmon_trace = BRSTEP; + xmon_trace[smp_processor_id()] = BRSTEP; regs->msr |= 0x400; } else { dabr.instr = regs->nip; @@ -223,7 +271,7 @@ xmon_iabr_match(struct pt_regs *regs) --iabr.count; remove_bpts(); excprint(regs); - xmon_trace = BRSTEP; + xmon_trace[smp_processor_id()] = BRSTEP; regs->msr |= 0x400; } else { xmon(regs); @@ -264,6 +312,7 @@ insert_bpts() bp->address); bp->enabled = 0; } + store_inst((void *) bp->address); } #if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4) if (dabr.enabled) @@ -293,6 +342,7 @@ remove_bpts() && mwrite(bp->address, &bp->instr, 4) != 4) printf("Couldn't remove breakpoint at %x\n", bp->address); + store_inst((void *) bp->address); } } @@ -306,6 +356,9 @@ cmds(struct pt_regs *excp) last_cmd = NULL; for(;;) { +#ifdef CONFIG_SMP + printf("%d:", smp_processor_id()); +#endif /* CONFIG_SMP */ printf("mon> "); fflush(stdout); flush_input(); @@ -383,12 +436,67 @@ cmds(struct pt_regs *excp) case 'b': bpt_cmds(); break; - case 'c': + case 'C': csum(); break; +#ifdef CONFIG_SMP + case 'c': + cpu_cmd(); + break; +#endif /* CONFIG_SMP */ + } + } +} + +#ifdef CONFIG_SMP +static void cpu_cmd(void) +{ + unsigned cpu; + int timeout; + int cmd; + + cmd = inchar(); + if (cmd == 'i') { + /* interrupt other cpu(s) */ + cpu = MSG_ALL_BUT_SELF; + scanhex(&cpu); + smp_send_xmon_break(cpu); + return; + } + termch = cmd; + if (!scanhex(&cpu)) { + /* print cpus waiting or in xmon */ + printf("cpus stopped:"); + for (cpu = 0; cpu < NR_CPUS; ++cpu) { + if (test_bit(cpu, &cpus_in_xmon)) { + printf(" %d", cpu); + if (cpu == smp_processor_id()) + printf("*", cpu); + } + } + printf("\n"); + return; + } + /* try to switch to cpu specified */ + take_xmon = cpu; + timeout = 10000000; + while (take_xmon >= 0) { + if (--timeout == 0) { + /* yes there's a race here */ + take_xmon = -1; + printf("cpu %u didn't take control\n", cpu); + return; + } + } + /* now have to wait to be given control back */ + while (test_and_set_bit(0, &got_xmon)) { + if (take_xmon == smp_processor_id()) { + take_xmon = -1; + break; } } } +#endif /* CONFIG_SMP */ static unsigned short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, @@ -551,6 +659,8 @@ backtrace(struct pt_regs *excp) extern char lost_irq_ret, do_bottom_half_ret, do_signal_ret; extern char ret_from_except; + printf("backtrace:\n"); + if (excp != NULL) sp = excp->gpr[1]; else @@ -592,6 +702,9 @@ getsp() void excprint(struct pt_regs *fp) { +#ifdef CONFIG_SMP + printf("cpu %d: ", smp_processor_id()); +#endif /* CONFIG_SMP */ printf("vector: %x at pc = %x", fp->trap, fp->nip); printf(", lr = %x, msr = %x, sp = %x [%x]\n", @@ -1163,9 +1276,6 @@ bsesc() return c; } -#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ - || ('a' <= (c) && (c) <= 'f') \ - || ('A' <= (c) && (c) <= 'F')) void dump() { @@ -1402,6 +1512,16 @@ skipbl() return c; } +#define N_PTREGS 44 +static char *regnames[N_PTREGS] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "mq", + "trap", "dar", "dsisr", "res" +}; + int scanhex(vp) unsigned *vp; @@ -1410,6 +1530,36 @@ unsigned *vp; unsigned v; c = skipbl(); + if (c == '%') { + /* parse register name */ + char regname[8]; + int i; + + for (i = 0; i < sizeof(regname) - 1; ++i) { + c = inchar(); + if (!isalnum(c)) { + termch = c; + break; + } + regname[i] = c; + } + regname[i] = 0; + for (i = 0; i < N_PTREGS; ++i) { + if (strcmp(regnames[i], regname) == 0) { + unsigned *rp = (unsigned *) + xmon_regs[smp_processor_id()]; + if (rp == NULL) { + printf("regs not available\n"); + return 0; + } + *vp = rp[i]; + return 1; + } + } + printf("invalid register name '%%%s'\n", regname); + return 0; + } + d = hexdigit(c); if( d == EOF ){ termch = c; diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 6f6a5287b..2fc6d08fa 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -264,6 +264,7 @@ void release_thread(struct task_struct *dead_task) } int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp, + unsigned long unused, struct task_struct * p, struct pt_regs * regs) { struct stack_frame @@ -313,7 +314,7 @@ asmlinkage int sys_fork(struct pt_regs regs) int ret; lock_kernel(); - ret = do_fork(SIGCHLD, regs.gprs[15], ®s); + ret = do_fork(SIGCHLD, regs.gprs[15], ®s, 0); unlock_kernel(); return ret; } @@ -329,7 +330,7 @@ asmlinkage int sys_clone(struct pt_regs regs) newsp = regs.gprs[2]; if (!newsp) newsp = regs.gprs[15]; - ret = do_fork(clone_flags, newsp, ®s); + ret = do_fork(clone_flags, newsp, ®s, 0); unlock_kernel(); return ret; } @@ -347,7 +348,7 @@ asmlinkage int sys_clone(struct pt_regs regs) asmlinkage int sys_vfork(struct pt_regs regs) { return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, - regs.gprs[15], ®s); + regs.gprs[15], ®s, 0); } /* diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index fd1a5e58a..a4df59c65 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -528,7 +528,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) default: lock_kernel(); - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 8f72782d2..6cf2e6918 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -528,7 +528,7 @@ static int __init fork_by_hand(void) /* don't care about the psw and regs settings since we'll never reschedule the forked task. */ memset(®s,sizeof(pt_regs),0); - return do_fork(CLONE_VM|CLONE_PID, 0, ®s); + return do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0); } static void __init do_boot_cpu(int cpu) diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index bd419991b..7e34e14da 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -36,7 +36,7 @@ piggy.o: $(SYSTEM) $(OBJCOPY) -R .empty_zero_page $(SYSTEM) $$tmppiggy; \ gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \ echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \ - $(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-shl -T $$tmppiggy.lnk; \ + $(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-sh-linux -T $$tmppiggy.lnk; \ rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk clean: diff --git a/arch/sh/config.in b/arch/sh/config.in index fa36d92f7..f0a51f8d6 100644 --- a/arch/sh/config.in +++ b/arch/sh/config.in @@ -123,6 +123,8 @@ source drivers/mtd/Config.in source drivers/block/Config.in +source drivers/md/Config.in + if [ "$CONFIG_NET" = "y" ]; then source net/Config.in fi diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index 7335803da..3b74e2d8e 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S @@ -14,7 +14,12 @@ #include <linux/linkage.h> #include <linux/config.h> -#define COMPAT_OLD_SYSCALL_ABI 1 + +/* + * Define this to turn on compatibility with the previous + * system call ABI. This feature is not properly maintained. + */ +#undef COMPAT_OLD_SYSCALL_ABI ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address @@ -28,6 +33,12 @@ * NOTE: This code handles signal-recognition, which happens every time * after a timer-interrupt and after each system call. * + * NOTE: This code uses a convention that instructions in the delay slot + * of a transfer-control instruction are indented by an extra space, thus: + * + * jmp @$k0 ! control-transfer instruction + * ldc $k1, $ssr ! delay slot + * * Stack layout in 'ret_from_syscall': * ptrace needs to have all regs on the stack. * if the order here is changed, it needs to be @@ -58,6 +69,7 @@ PT_TRACESYS = 0x00000002 PF_USEDFPU = 0x00100000 ENOSYS = 38 +EINVAL = 22 #if defined(__sh3__) TRA = 0xffffffd0 @@ -76,7 +88,14 @@ MMU_TEA = 0xff00000c ! TLB Exception Address Register #endif /* Offsets to the stack */ -R0 = 0 /* Return value */ +R0 = 0 /* Return value. New ABI also arg4 */ +R1 = 4 /* New ABI: arg5 */ +R2 = 8 /* New ABI: arg6 */ +R3 = 12 /* New ABI: syscall_nr */ +R4 = 16 /* New ABI: arg0 */ +R5 = 20 /* New ABI: arg1 */ +R6 = 24 /* New ABI: arg2 */ +R7 = 28 /* New ABI: arg3 */ SP = (15*4) SR = (16*4+8) SYSCALL_NR = (16*4+6*4) @@ -132,7 +151,6 @@ SYSCALL_NR = (16*4+6*4) tlb_miss_load: mov.l 2f, $r0 mov.l @$r0, $r6 - STI() mov $r15, $r4 mov.l 1f, $r0 jmp @$r0 @@ -142,7 +160,6 @@ tlb_miss_load: tlb_miss_store: mov.l 2f, $r0 mov.l @$r0, $r6 - STI() mov $r15, $r4 mov.l 1f, $r0 jmp @$r0 @@ -152,7 +169,6 @@ tlb_miss_store: initial_page_write: mov.l 2f, $r0 mov.l @$r0, $r6 - STI() mov $r15, $r4 mov.l 1f, $r0 jmp @$r0 @@ -162,7 +178,6 @@ initial_page_write: tlb_protection_violation_load: mov.l 2f, $r0 mov.l @$r0, $r6 - STI() mov $r15, $r4 mov.l 1f, $r0 jmp @$r0 @@ -172,14 +187,13 @@ tlb_protection_violation_load: tlb_protection_violation_store: mov.l 2f, $r0 mov.l @$r0, $r6 - STI() mov $r15, $r4 mov.l 1f, $r0 jmp @$r0 mov #1, $r5 .align 2 -1: .long SYMBOL_NAME(do_page_fault) +1: .long SYMBOL_NAME(__do_page_fault) 2: .long MMU_TEA #if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS) @@ -249,9 +263,6 @@ error: .align 2 1: .long SYMBOL_NAME(do_exception_error) -badsys: mov #-ENOSYS, $r0 - rts ! go to ret_from_syscall.. - mov.l $r0, @(R0,$r15) ! ! @@ -291,7 +302,7 @@ ENTRY(ret_from_fork) */ system_call: - mov.l 1f, $r9 + mov.l __TRA, $r9 mov.l @$r9, $r8 ! ! Is the trap argument >= 0x20? (TRA will be >= 0x80) @@ -304,122 +315,160 @@ system_call: mov #SYSCALL_NR, $r14 add $r15, $r14 ! - mov #0x40, $r9 #ifdef COMPAT_OLD_SYSCALL_ABI + mov #0x40, $r9 cmp/hs $r9, $r8 - mov $r0, $r10 - bf/s 0f - mov $r0, $r9 + bf/s old_abi_system_call + nop #endif ! New Syscall ABI add #-0x40, $r8 shlr2 $r8 shll8 $r8 - shll8 $r8 + shll8 $r8 ! $r8 = num_args<<16 mov $r3, $r10 or $r8, $r10 ! Encode syscall # and # of arguments - ! - mov $r3, $r9 - mov #0, $r8 -0: mov.l $r10, @$r14 ! set syscall_nr STI() - mov.l __n_sys, $r10 - cmp/hs $r10, $r9 - bt badsys ! -#ifdef COMPAT_OLD_SYSCALL_ABI - ! Build the stack frame if TRA > 0 - mov $r8, $r10 - cmp/pl $r10 - bf 0f - mov.l @(SP,$r15), $r0 ! get original stack -7: add #-4, $r10 -4: mov.l @($r0,$r10), $r1 ! May cause address error exception.. - mov.l $r1, @-$r15 - cmp/pl $r10 - bt 7b -#endif -0: stc $k_current, $r11 - mov.l @(tsk_ptrace,$r11), $r10 ! Is it trace? + stc $k_current, $r11 + mov.l @(tsk_ptrace,$r11), $r10 ! Is current PTRACE_SYSCALL'd? mov #PT_TRACESYS, $r11 tst $r11, $r10 bt 5f - ! Trace system call - mov #-ENOSYS, $r11 - mov.l $r11, @(R0,$r15) - ! Push up $R0--$R2, and $R4--$R7 - mov.l $r0, @-$r15 - mov.l $r1, @-$r15 - mov.l $r2, @-$r15 - mov.l $r4, @-$r15 - mov.l $r5, @-$r15 - mov.l $r6, @-$r15 - mov.l $r7, @-$r15 - ! - mov.l 2f, $r11 - jsr @$r11 + ! Yes it is traced. + mov.l __syscall_trace, $r11 ! Call syscall_trace() which notifies + jsr @$r11 ! superior (will chomp $R[0-7]) nop - ! Pop down $R0--$R2, and $R4--$R7 - mov.l @$r15+, $r7 - mov.l @$r15+, $r6 - mov.l @$r15+, $r5 - mov.l @$r15+, $r4 - mov.l @$r15+, $r2 - mov.l @$r15+, $r1 - mov.l @$r15+, $r0 - ! + ! Reload $R0-$R4 from kernel stack, where the + ! parent may have modified them using + ! ptrace(POKEUSR). (Note that $R0-$R2 are + ! used by the system call handler directly + ! from the kernel stack anyway, so don't need + ! to be reloaded here.) This allows the parent + ! to rewrite system calls and args on the fly. + mov.l @(R4,$r15), $r4 ! arg0 + mov.l @(R5,$r15), $r5 + mov.l @(R6,$r15), $r6 + mov.l @(R7,$r15), $r7 ! arg3 + mov.l @(R3,$r15), $r3 ! syscall_nr + ! Arrange for syscall_trace() to be called + ! again as the system call returns. mov.l __syscall_ret_trace, $r10 bra 6f lds $r10, $pr - ! + ! No it isn't traced. + ! Arrange for normal system call return. 5: mov.l __syscall_ret, $r10 lds $r10, $pr - ! -6: mov $r9, $r10 - shll2 $r10 ! x4 + ! Call the system call handler through the table. + ! (both normal and ptrace'd) + ! First check for bad syscall number +6: mov $r3, $r9 + mov.l __n_sys, $r10 + cmp/hs $r10, $r9 + bf 2f + ! Bad syscall number + rts ! go to syscall_ret or syscall_ret_trace + mov #-ENOSYS, $r0 + ! Good syscall number +2: shll2 $r9 ! x4 mov.l __sct, $r11 - add $r11, $r10 - mov.l @$r10, $r11 - jmp @$r11 + add $r11, $r9 + mov.l @$r9, $r11 + jmp @$r11 ! jump to specific syscall handler nop ! In case of trace - .align 2 -3: -#ifdef COMPAT_OLD_SYSCALL_ABI - add $r8, $r15 ! pop off the arguments -#endif +syscall_ret_trace: mov.l $r0, @(R0,$r15) ! save the return value - mov.l 2f, $r1 + mov.l __syscall_trace, $r1 mova SYMBOL_NAME(ret_from_syscall), $r0 - jmp @$r1 - lds $r0, $pr - .align 2 -1: .long TRA -2: .long SYMBOL_NAME(syscall_trace) -__n_sys: .long NR_syscalls -__sct: .long SYMBOL_NAME(sys_call_table) -__syscall_ret_trace: - .long 3b -__syscall_ret: - .long SYMBOL_NAME(syscall_ret) + jmp @$r1 ! Call syscall_trace() which notifies superior + lds $r0, $pr ! Then return to ret_from_syscall() + + #ifdef COMPAT_OLD_SYSCALL_ABI +! Handle old ABI system call. +! Note that ptrace(SYSCALL) is not supported for the old ABI. +! At this point: +! $r0, $r4-7 as per ABI +! $r8 = value of TRA register (= num_args<<2) +! $r14 = points to SYSCALL_NR in stack frame +old_abi_system_call: + mov $r0, $r9 ! Save system call number in $r9 + ! ! arrange for return which pops stack + mov.l __old_abi_syscall_ret, $r10 + lds $r10, $pr + ! Build the stack frame if TRA > 0 + mov $r8, $r10 + cmp/pl $r10 + bf 0f + mov.l @(SP,$r15), $r0 ! get original user stack +7: add #-4, $r10 +4: mov.l @($r0,$r10), $r1 ! May cause address error exception.. + mov.l $r1, @-$r15 + cmp/pl $r10 + bt 7b +0: + mov.l $r9, @$r14 ! set syscall_nr + STI() + ! Call the system call handler through the table. + ! First check for bad syscall number + mov.l __n_sys, $r10 + cmp/hs $r10, $r9 + bf 2f + ! Bad syscall number + rts ! return to old_abi_syscall_ret + mov #-ENOSYS, $r0 + ! Good syscall number +2: shll2 $r9 ! x4 + mov.l __sct, $r11 + add $r11, $r9 + mov.l @$r9, $r11 + jmp @$r11 ! call specific syscall handler, + nop + + .align 2 +__old_abi_syscall_ret: + .long old_abi_syscall_ret + + ! This code gets called on address error exception when copying + ! syscall arguments from user stack to kernel stack. It is + ! supposed to return -EINVAL through old_abi_syscall_ret, but it + ! appears to have been broken for a long time in that the $r0 + ! return value will be saved into the kernel stack relative to $r15 + ! but the value of $r15 is not correct partway through the loop. + ! So the user prog is returned its old $r0 value, not -EINVAL. + ! Greg Banks 28 Aug 2000. .section .fixup,"ax" fixup_syscall_argerr: + ! First get $r15 back to rts - mov.l 1f, $r0 -1: .long -22 ! -EINVAL -.previous + mov #-EINVAL, $r0 + .previous .section __ex_table, "a" .align 2 .long 4b,fixup_syscall_argerr -.previous + .previous #endif .align 2 +__TRA: .long TRA +__syscall_trace: + .long SYMBOL_NAME(syscall_trace) +__n_sys:.long NR_syscalls +__sct: .long SYMBOL_NAME(sys_call_table) +__syscall_ret_trace: + .long syscall_ret_trace +__syscall_ret: + .long SYMBOL_NAME(syscall_ret) + + + + .align 2 reschedule: mova SYMBOL_NAME(ret_from_syscall), $r0 mov.l 1f, $r1 @@ -454,10 +503,12 @@ __INV_IMASK: .long 0xffffff0f ! ~(IMASK) .align 2 -syscall_ret: #ifdef COMPAT_OLD_SYSCALL_ABI +old_abi_syscall_ret: add $r8, $r15 ! pop off the arguments + /* fall through */ #endif +syscall_ret: mov.l $r0, @(R0,$r15) ! save the return value /* fall through */ @@ -707,7 +758,7 @@ handle_exception: #endif 8: /* User space to kernel */ mov #0x20, $k1 - shll8 $k1 ! $k1 <= 8192 + shll8 $k1 ! $k1 <= 8192 == THREAD_SIZE add $current, $k1 mov $k1, $r15 ! change to kernel stack ! @@ -1107,6 +1158,7 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_mincore) .long SYMBOL_NAME(sys_madvise) .long SYMBOL_NAME(sys_getdents64) /* 220 */ + .long SYMBOL_NAME(sys_fcntl64) /* * NOTE!! This doesn't have to be exact - we just have @@ -1114,7 +1166,7 @@ ENTRY(sys_call_table) * entries. Don't panic if you notice that this hasn't * been shrunk every time we add a new system call. */ - .rept NR_syscalls-220 + .rept NR_syscalls-221 .long SYMBOL_NAME(sys_ni_syscall) .endr diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S index db3e8b0a3..f1ac6fd17 100644 --- a/arch/sh/kernel/head.S +++ b/arch/sh/kernel/head.S @@ -21,9 +21,9 @@ ENTRY(empty_zero_page) .long 0x00360000 /* INITRD_START */ .long 0x000a0000 /* INITRD_SIZE */ .long 0 + .balign 4096,0,4096 .text - .balign 4096,0,4096 /* * Condition at the entry of _stext: * diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c index fca718ece..80f50d9ad 100644 --- a/arch/sh/kernel/io.c +++ b/arch/sh/kernel/io.c @@ -1,5 +1,5 @@ /* - * linux/arch/sh/kernel/io_generic.c + * linux/arch/sh/kernel/io.c * * Copyright (C) 2000 Stuart Menefy * diff --git a/arch/sh/kernel/irq_imask.c b/arch/sh/kernel/irq_imask.c index 8ac95823b..27d91b372 100644 --- a/arch/sh/kernel/irq_imask.c +++ b/arch/sh/kernel/irq_imask.c @@ -41,7 +41,7 @@ static void end_imask_irq(unsigned int irq); static unsigned int startup_imask_irq(unsigned int irq) { - enable_imask_irq(irq); + /* Nothing to do */ return 0; /* never anything pending */ } @@ -71,7 +71,8 @@ void static inline set_interrupt_registers(int ip) "ldc %0, $sr\n" "1:" : "=&z" (__dummy) - : "r" (~0xf0), "r" (ip << 4)); + : "r" (~0xf0), "r" (ip << 4) + : "t"); } static void disable_imask_irq(unsigned int irq) @@ -103,7 +104,7 @@ static void end_imask_irq(unsigned int irq) static void shutdown_imask_irq(unsigned int irq) { - disable_imask_irq(irq); + /* Nothing to do */ } void make_imask_irq(unsigned int irq) diff --git a/arch/sh/kernel/irq_ipr.c b/arch/sh/kernel/irq_ipr.c index f229e8a12..918e010e9 100644 --- a/arch/sh/kernel/irq_ipr.c +++ b/arch/sh/kernel/irq_ipr.c @@ -128,12 +128,14 @@ void __init init_IRQ(void) #ifdef SCIF_ERI_IRQ make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); + make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); #endif #ifdef IRDA_ERI_IRQ make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); + make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); #endif diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 60205379c..c7511093b 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -136,11 +136,12 @@ void free_task_struct(struct task_struct *p) */ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { /* Don't use this in BL=1(cli). Or else, CPU resets! */ - register unsigned long __sc0 __asm__ ("$r3") = __NR_clone; - register unsigned long __sc4 __asm__ ("$r4") = (long) flags | CLONE_VM; - register unsigned long __sc5 __asm__ ("$r5") = 0; - register unsigned long __sc8 __asm__ ("$r8") = (long) arg; - register unsigned long __sc9 __asm__ ("$r9") = (long) fn; + register unsigned long __sc0 __asm__ ("r0"); + register unsigned long __sc3 __asm__ ("r3") = __NR_clone; + register unsigned long __sc4 __asm__ ("r4") = (long) flags | CLONE_VM; + register unsigned long __sc5 __asm__ ("r5") = 0; + register unsigned long __sc8 __asm__ ("r8") = (long) arg; + register unsigned long __sc9 __asm__ ("r9") = (long) fn; __asm__("trapa #0x12\n\t" /* Linux/SH system call */ "tst #0xff, $r0\n\t" /* child or parent? */ @@ -148,13 +149,13 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) "jsr @$r9\n\t" /* call fn */ " mov $r8, $r4\n\t" /* push argument */ "mov $r0, $r4\n\t" /* return value to arg of exit */ - "mov %2, $r3\n\t" /* exit */ + "mov %1, $r3\n\t" /* exit */ "trapa #0x11\n" "1:" : "=z" (__sc0) - : "0" (__sc0), "i" (__NR_exit), - "r" (__sc4), "r" (__sc5), "r" (__sc8), "r" (__sc9) - : "memory"); + : "i" (__NR_exit), "r" (__sc3), "r" (__sc4), "r" (__sc5), + "r" (__sc8), "r" (__sc9) + : "memory", "t"); return __sc0; } @@ -211,6 +212,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) asmlinkage void ret_from_fork(void); int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, + unsigned long unused, struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; @@ -292,7 +294,7 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { - return do_fork(SIGCHLD, regs.regs[15], ®s); + return do_fork(SIGCHLD, regs.regs[15], ®s, 0); } asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, @@ -301,7 +303,7 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, { if (!newsp) newsp = regs.regs[15]; - return do_fork(clone_flags, newsp, ®s); + return do_fork(clone_flags, newsp, ®s, 0); } /* @@ -318,7 +320,7 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s); + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s, 0); } /* diff --git a/arch/sh/kernel/setup_cqreek.c b/arch/sh/kernel/setup_cqreek.c index ea5dd7ece..af7dfe568 100644 --- a/arch/sh/kernel/setup_cqreek.c +++ b/arch/sh/kernel/setup_cqreek.c @@ -1,4 +1,4 @@ -/* $Id: setup_cqreek.c,v 1.1 2000/08/05 06:25:23 gniibe Exp $ +/* $Id: setup_cqreek.c,v 1.5 2000/09/18 05:51:24 gniibe Exp $ * * arch/sh/kernel/setup_cqreek.c * @@ -44,15 +44,24 @@ static unsigned long cqreek_port2addr(unsigned long port) return ISA_OFFSET + port; } +struct cqreek_irq_data { + unsigned short mask_port; /* Port of Interrupt Mask Register */ + unsigned short stat_port; /* Port of Interrupt Status Register */ + unsigned short bit; /* Value of the bit */ +}; +static struct cqreek_irq_data cqreek_irq_data[NR_IRQS]; + static void disable_cqreek_irq(unsigned int irq) { unsigned long flags; unsigned short mask; + unsigned short mask_port = cqreek_irq_data[irq].mask_port; + unsigned short bit = cqreek_irq_data[irq].bit; save_and_cli(flags); /* Disable IRQ */ - mask = inw(BRIDGE_ISA_INTR_MASK) & ~(1 << irq); - outw_p(mask, BRIDGE_ISA_INTR_MASK); + mask = inw(mask_port) & ~bit; + outw_p(mask, mask_port); restore_flags(flags); } @@ -60,32 +69,29 @@ static void enable_cqreek_irq(unsigned int irq) { unsigned long flags; unsigned short mask; + unsigned short mask_port = cqreek_irq_data[irq].mask_port; + unsigned short bit = cqreek_irq_data[irq].bit; save_and_cli(flags); /* Enable IRQ */ - mask = inw(BRIDGE_ISA_INTR_MASK) | (1 << irq); - outw_p(mask, BRIDGE_ISA_INTR_MASK); + mask = inw(mask_port) | bit; + outw_p(mask, mask_port); restore_flags(flags); } -#define CLEAR_AT_ACCEPT - static void mask_and_ack_cqreek(unsigned int irq) { - inw(BRIDGE_ISA_INTR_STAT); + unsigned short stat_port = cqreek_irq_data[irq].stat_port; + unsigned short bit = cqreek_irq_data[irq].bit; + + inw(stat_port); disable_cqreek_irq(irq); -#ifdef CLEAR_AT_ACCEPT /* Clear IRQ (it might be edge IRQ) */ - outw_p((1<<irq), BRIDGE_ISA_INTR_STAT); -#endif + outw_p(bit, stat_port); } static void end_cqreek_irq(unsigned int irq) { -#ifndef CLEAR_AT_ACCEPT - /* Clear IRQ (it might be edge IRQ) */ - outw_p((1<<irq), BRIDGE_ISA_INTR_STAT); -#endif enable_cqreek_irq(irq); } @@ -101,7 +107,7 @@ static void shutdown_cqreek_irq(unsigned int irq) } static struct hw_interrupt_type cqreek_irq_type = { - "CQREEK-IRQ", + "CqREEK-IRQ", startup_cqreek_irq, shutdown_cqreek_irq, enable_cqreek_irq, @@ -116,10 +122,24 @@ static int has_ide, has_isa; What we really need is virtualized IRQ and demultiplexer like HP600 port */ void __init init_cqreek_IRQ(void) { - if (has_ide) - make_ipr_irq(14, IDE_OFFSET+BRIDGE_IDE_INTR_LVL, 0, 0x0f-14); + if (has_ide) { + cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK; + cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT; + cqreek_irq_data[14].bit = 1; + + irq_desc[14].handler = &cqreek_irq_type; + irq_desc[14].status = IRQ_DISABLED; + irq_desc[14].action = 0; + irq_desc[14].depth = 1; + + disable_cqreek_irq(14); + } if (has_isa) { + cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK; + cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT; + cqreek_irq_data[10].bit = (1 << 10); + /* XXX: Err... we may need demultiplexer for ISA irq... */ irq_desc[10].handler = &cqreek_irq_type; irq_desc[10].status = IRQ_DISABLED; @@ -135,10 +155,17 @@ void __init init_cqreek_IRQ(void) */ void __init setup_cqreek(void) { + extern void disable_hlt(void); int i; /* udelay is not available at setup time yet... */ #define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0) + /* + * XXX: I don't know the reason, but it becomes so fragile with + * "sleep", so we need to stop sleeping. + */ + disable_hlt(); + if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */ outw_p(0, BRIDGE_IDE_INTR_LVL); outw_p(0, BRIDGE_IDE_INTR_MASK); @@ -219,7 +246,6 @@ struct sh_machine_vector mv_cqreek __initmv = { mv_init_arch: setup_cqreek, mv_init_irq: init_cqreek_IRQ, - mv_port2addr: cqreek_port2addr, mv_isa_port2addr: cqreek_port2addr, }; ALIAS_MV(cqreek) diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index 12f716249..81a56b960 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c @@ -1,4 +1,4 @@ -/* $Id: sh_bios.c,v 1.2 2000/07/26 04:37:32 gniibe Exp $ +/* $Id: sh_bios.c,v 1.3 2000/09/30 03:43:30 gniibe Exp $ * * linux/arch/sh/kernel/sh_bios.c * C interface for trapping into the standard LinuxSH BIOS. @@ -20,11 +20,11 @@ static __inline__ long sh_bios_call(long func, long arg0, long arg1, long arg2, long arg3) { - register long r0 __asm__("$r0") = func; - register long r4 __asm__("$r4") = arg0; - register long r5 __asm__("$r5") = arg1; - register long r6 __asm__("$r6") = arg2; - register long r7 __asm__("$r7") = arg3; + register long r0 __asm__("r0") = func; + register long r4 __asm__("r4") = arg0; + register long r5 __asm__("r5") = arg1; + register long r6 __asm__("r6") = arg2; + register long r7 __asm__("r7") = arg3; __asm__ __volatile__("trapa #0x3f" : "=z" (r0) : "0" (r0), "r" (r4), "r" (r5), "r" (r6), "r" (r7) diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index 73d971982..de03cfb19 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -17,6 +17,7 @@ #include <asm/hardirq.h> #include <asm/delay.h> #include <asm/irq.h> +#include <asm/pgtable.h> extern void dump_thread(struct pt_regs *, struct user *); extern int dump_fpu(elf_fpregset_t *); @@ -35,7 +36,35 @@ EXPORT_SYMBOL(csum_partial_copy); EXPORT_SYMBOL(strtok); EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(strlen); + +/* mem exports */ +EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(memmove); + +/* this is not provided by arch/sh/lib/*.S but is + potentially needed by modules (af_packet.o/unix.o + use memcmp, for instance) */ +EXPORT_SYMBOL(memcmp); #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); #endif + + +#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL_NOVERS(name) + +/* These symbols are generated by the compiler itself */ +#ifdef __SH4__ + +DECLARE_EXPORT(__udivsi3_i4); +DECLARE_EXPORT(__sdivsi3_i4); +DECLARE_EXPORT(__movstr_i4_even); +DECLARE_EXPORT(__movstr_i4_odd); +DECLARE_EXPORT(__ashrdi3); +DECLARE_EXPORT(__ashldi3); + +/* needed by some modules */ +EXPORT_SYMBOL(flush_dcache_page); +#endif diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 9bdddc9d9..fe2f1b319 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -672,7 +672,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index f1e8d28bf..5af1e6de8 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -274,37 +274,6 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) write_unlock(&xtime_lock); } -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - static unsigned long get_rtc_time(void) { unsigned int sec, min, hr, wk, day, mon, yr, yr100; @@ -373,7 +342,8 @@ static __init unsigned int get_cpu_mhz(void) "bt/s 1b\n\t" " add #1,%0" : "=r"(count), "=z" (__dummy) - : "0" (0), "1" (0)); + : "0" (0), "1" (0) + : "t"); cli(); /* * SH-3: diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index a9775f306..db11c1247 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -131,9 +131,16 @@ void dump_stack(void) asm("mov $r15, %0" : "=r" (start)); asm("stc $r7_bank, %0" : "=r" (end)); - end += 8192; + end += 8192/4; printk("%08lx:%08lx\n", (unsigned long)start, (unsigned long)end); - for (p=start; p < end; p++) - printk("%08lx\n", *p); + for (p=start; p < end; p++) { + extern long _text, _etext; + unsigned long v=*p; + + if ((v >= (unsigned long )&_text) + && (v <= (unsigned long )&_etext)) { + printk("%08lx\n", v); + } + } } diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S index 3317b3ccc..c7e96a394 100644 --- a/arch/sh/lib/checksum.S +++ b/arch/sh/lib/checksum.S @@ -159,14 +159,14 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, * them all but there's no guarantee. */ -#define SRC(y...) \ - 9999: y; \ +#define SRC(x,y) \ + 9999: x,y; \ .section __ex_table, "a"; \ .long 9999b, 6001f ; \ .previous -#define DST(y...) \ - 9999: y; \ +#define DST(x,y) \ + 9999: x,y; \ .section __ex_table, "a"; \ .long 9999b, 6002f ; \ .previous @@ -276,7 +276,7 @@ DST( mov.l r0,@r5 ) DST( mov.l r1,@r5 ) add #4,r5 -SRC( mov.l @r4+,r0 ) +SRC( mov.l @r4+,r0 ) SRC( mov.l @r4+,r1 ) addc r0,r7 DST( mov.l r0,@r5 ) diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index af494b9a3..ab63535e4 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -64,9 +64,9 @@ static struct _cache_system_info cache_system_info = {0,}; #define CACHE_IC_WAY_SHIFT 13 #define CACHE_OC_ENTRY_SHIFT 5 #define CACHE_IC_ENTRY_SHIFT 5 -#define CACHE_OC_ENTRY_MASK 0x3fe0 -#define CACHE_OC_ENTRY_PHYS_MASK 0x0fe0 -#define CACHE_IC_ENTRY_MASK 0x1fe0 +#define CACHE_OC_ENTRY_MASK 0x3fe0 +#define CACHE_OC_ENTRY_PHYS_MASK 0x0fe0 +#define CACHE_IC_ENTRY_MASK 0x1fe0 #define CACHE_IC_NUM_ENTRIES 256 #define CACHE_OC_NUM_ENTRIES 512 #define CACHE_OC_NUM_WAYS 1 @@ -92,7 +92,8 @@ static inline void cache_wback_all(void) addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)| (i<<CACHE_OC_ENTRY_SHIFT); data = ctrl_inl(addr); - if (data & CACHE_UPDATED) { + if ((data & (CACHE_UPDATED|CACHE_VALID)) + == (CACHE_UPDATED|CACHE_VALID)) { data &= ~CACHE_UPDATED; ctrl_outl(data, addr); } @@ -114,17 +115,25 @@ detect_cpu_and_cache_system(void) */ addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12); addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12); + + /* First, write back & invalidate */ data0 = ctrl_inl(addr0); - data0 ^= 0x00000001; - ctrl_outl(data0,addr0); + ctrl_outl(data0&~(CACHE_VALID|CACHE_UPDATED), addr0); + data1 = ctrl_inl(addr1); + ctrl_outl(data1&~(CACHE_VALID|CACHE_UPDATED), addr1); + + /* Next, check if there's shadow or not */ + data0 = ctrl_inl(addr0); + data0 ^= CACHE_VALID; + ctrl_outl(data0, addr0); data1 = ctrl_inl(addr1); - data2 = data1 ^ 0x00000001; - ctrl_outl(data2,addr1); + data2 = data1 ^ CACHE_VALID; + ctrl_outl(data2, addr1); data3 = ctrl_inl(addr0); - /* Invaliate them, in case the cache has been enabled already. */ - ctrl_outl(data0&~0x00000001, addr0); - ctrl_outl(data2&~0x00000001, addr1); + /* Lastly, invaliate them. */ + ctrl_outl(data0&~CACHE_VALID, addr0); + ctrl_outl(data2&~CACHE_VALID, addr1); back_to_P1(); if (data0 == data1 && data2 == data3) { /* Shadow */ @@ -150,8 +159,6 @@ void __init cache_init(void) detect_cpu_and_cache_system(); ccr = ctrl_inl(CCR); - if (ccr == CCR_CACHE_VAL) - return; jump_to_P2(); if (ccr & CCR_CACHE_ENABLE) /* @@ -380,29 +387,114 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long addr) } /* + * Write-back & invalidate the cache. + * * After accessing the memory from kernel space (P1-area), we need to - * write back the cache line to maintain DMA coherency. + * write back the cache line. * * We search the D-cache to see if we have the entries corresponding to * the page, and if found, write back them. */ +void __flush_page_to_ram(void *kaddr) +{ + unsigned long phys, addr, data, i; + + /* Physical address of this page */ + phys = PHYSADDR(kaddr); + + jump_to_P2(); + /* Loop all the D-cache */ + for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { + addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT); + data = ctrl_inl(addr); + if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) { + data &= ~(CACHE_UPDATED|CACHE_VALID); + ctrl_outl(data, addr); + } + } + back_to_P1(); +} + void flush_page_to_ram(struct page *pg) { + unsigned long phys; + + /* Physical address of this page */ + phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; + __flush_page_to_ram(phys_to_virt(phys)); +} + +/* + * Check entries of the I-cache & D-cache of the page. + * (To see "alias" issues) + */ +void check_cache_page(struct page *pg) +{ unsigned long phys, addr, data, i; + unsigned long kaddr; + unsigned long cache_line_index; + int bingo = 0; /* Physical address of this page */ phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START; + kaddr = phys + PAGE_OFFSET; + cache_line_index = (kaddr&CACHE_OC_ENTRY_MASK)>>CACHE_OC_ENTRY_SHIFT; jump_to_P2(); /* Loop all the D-cache */ for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) { addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT); data = ctrl_inl(addr); - if ((data & CACHE_UPDATED) && (data&PAGE_MASK) == phys) { - data &= ~CACHE_UPDATED; + if ((data & (CACHE_UPDATED|CACHE_VALID)) + == (CACHE_UPDATED|CACHE_VALID) + && (data&PAGE_MASK) == phys) { + data &= ~(CACHE_VALID|CACHE_UPDATED); ctrl_outl(data, addr); + if ((i^cache_line_index)&0x180) + bingo = 1; + } + } + + cache_line_index &= 0xff; + /* Loop all the I-cache */ + for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) { + addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT); + data = ctrl_inl(addr); + if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) { + data &= ~CACHE_VALID; + ctrl_outl(data, addr); + if (((i^cache_line_index)&0x80)) + bingo = 2; } } back_to_P1(); + + if (bingo) { + extern void dump_stack(void); + + if (bingo ==1) + printk("BINGO!\n"); + else + printk("Bingo!\n"); + dump_stack(); + printk("--------------------\n"); + } +} + +/* Page is 4K, OC size is 16K, there are four lines. */ +#define CACHE_ALIAS 0x00003000 + +void clear_user_page(void *to, unsigned long address) +{ + clear_page(to); + if (((address ^ (unsigned long)to) & CACHE_ALIAS)) + __flush_page_to_ram(to); +} + +void copy_user_page(void *to, void *from, unsigned long address) +{ + copy_page(to, from); + if (((address ^ (unsigned long)to) & CACHE_ALIAS)) + __flush_page_to_ram(to); } #endif diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index f2e342f0b..9c06626da 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -28,9 +28,9 @@ #include <asm/mmu_context.h> extern void die(const char *,struct pt_regs *,long); -static void __flush_tlb_page(struct mm_struct *mm, unsigned long page); +static void __flush_tlb_page(unsigned long asid, unsigned long page); #if defined(__SH4__) -static void __flush_tlb_phys(struct mm_struct *mm, unsigned long phys); +static void __flush_tlb_phys(unsigned long phys); #endif /* @@ -85,42 +85,6 @@ bad_area: return 0; } -static void handle_vmalloc_fault(struct mm_struct *mm, unsigned long address) -{ - pgd_t *dir; - pmd_t *pmd; - pte_t *pte; - pte_t entry; - - dir = pgd_offset_k(address); - pmd = pmd_offset(dir, address); - if (pmd_none(*pmd)) { - printk(KERN_ERR "vmalloced area %08lx bad\n", address); - return; - } - if (pmd_bad(*pmd)) { - pmd_ERROR(*pmd); - pmd_clear(pmd); - return; - } - pte = pte_offset(pmd, address); - entry = *pte; - if (pte_none(entry) || !pte_present(entry) || !pte_write(entry)) { - printk(KERN_ERR "vmalloced area %08lx bad\n", address); - return; - } - -#if defined(__SH4__) - /* - * ITLB is not affected by "ldtlb" instruction. - * So, we need to flush the entry by ourselves. - */ - if (mm) - __flush_tlb_page(mm, address&PAGE_MASK); -#endif - update_mmu_cache(NULL, address, entry); -} - /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate @@ -138,11 +102,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, tsk = current; mm = tsk->mm; - if (address >= VMALLOC_START && address < VMALLOC_END) { - handle_vmalloc_fault(mm, address); - return; - } - /* * If we're in an interrupt or have no user * context, we must not take the fault.. @@ -272,6 +231,67 @@ do_sigbus: goto no_context; } +static int __do_page_fault1(struct pt_regs *regs, unsigned long writeaccess, + unsigned long address) +{ + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + + if (address >= VMALLOC_START && address < VMALLOC_END) + /* We can change the implementation of P3 area pte entries. + set_pgdir and such. */ + dir = pgd_offset_k(address); + else + dir = pgd_offset(current->mm, address); + + pmd = pmd_offset(dir, address); + if (pmd_none(*pmd)) + return 1; + if (pmd_bad(*pmd)) { + pmd_ERROR(*pmd); + pmd_clear(pmd); + return 1; + } + pte = pte_offset(pmd, address); + entry = *pte; + if (pte_none(entry) || !pte_present(entry) + || (writeaccess && !pte_write(entry))) + return 1; + + if (writeaccess) + entry = pte_mkdirty(entry); + entry = pte_mkyoung(entry); +#if defined(__SH4__) + /* + * ITLB is not affected by "ldtlb" instruction. + * So, we need to flush the entry by ourselves. + */ + __flush_tlb_page(get_asid(), address&PAGE_MASK); +#endif + set_pte(pte, entry); + update_mmu_cache(NULL, address, entry); + return 0; +} + +/* + * Called with interrupt disabled. + */ +asmlinkage void __do_page_fault(struct pt_regs *regs, unsigned long writeaccess, + unsigned long address) +{ + /* + * XXX: Could you please implement this (calling __do_page_fault1) + * in assembler language in entry.S? + */ + if (__do_page_fault1(regs, writeaccess, address) == 0) + /* Done. */ + return; + sti(); + do_page_fault(regs, writeaccess, address); +} + void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte) { @@ -282,28 +302,30 @@ void update_mmu_cache(struct vm_area_struct * vma, save_and_cli(flags); #if defined(__SH4__) - if (vma && (vma->vm_flags & VM_SHARED)) { + if (pte_shared(pte)) { struct page *pg; pteval = pte_val(pte); pteval &= PAGE_MASK; /* Physicall page address */ - __flush_tlb_phys(vma->vm_mm, pteval); + __flush_tlb_phys(pteval); pg = virt_to_page(__va(pteval)); flush_dcache_page(pg); } #endif - /* Set PTEH register */ - if (vma) { - pteaddr = (address & MMU_VPN_MASK) | - (vma->vm_mm->context & MMU_CONTEXT_ASID_MASK); - ctrl_outl(pteaddr, MMU_PTEH); + /* Ptrace may call this routine. */ + if (vma && current->active_mm != vma->vm_mm) { + restore_flags(flags); + return; } + /* Set PTEH register */ + pteaddr = (address & MMU_VPN_MASK) | get_asid(); + ctrl_outl(pteaddr, MMU_PTEH); + /* Set PTEL register */ pteval = pte_val(pte); pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ - pteval |= _PAGE_FLAGS_HARDWARE_DEFAULT; /* add default flags */ ctrl_outl(pteval, MMU_PTEL); /* Load the TLB */ @@ -311,24 +333,16 @@ void update_mmu_cache(struct vm_area_struct * vma, restore_flags(flags); } -static void __flush_tlb_page(struct mm_struct *mm, unsigned long page) +static void __flush_tlb_page(unsigned long asid, unsigned long page) { - unsigned long addr, data, asid; - unsigned long saved_asid = MMU_NO_ASID; - - if (mm->context == NO_CONTEXT) - return; - - asid = mm->context & MMU_CONTEXT_ASID_MASK; - if (mm != current->mm) { - saved_asid = get_asid(); - /* - * We need to set ASID of the target entry to flush, - * because TLB is indexed by (ASID and PAGE). - */ - set_asid(asid); - } + unsigned long addr, data; + /* + * NOTE: PTEH.ASID should be set to this MM + * _AND_ we need to write ASID to the array. + * + * It would be simple if we didn't need to set PTEH.ASID... + */ #if defined(__sh3__) addr = MMU_TLB_ADDRESS_ARRAY |(page & 0x1F000)| MMU_PAGE_ASSOC_BIT; data = (page & 0xfffe0000) | asid; /* VALID bit is off */ @@ -340,12 +354,10 @@ static void __flush_tlb_page(struct mm_struct *mm, unsigned long page) ctrl_outl(data, addr); back_to_P1(); #endif - if (saved_asid != MMU_NO_ASID) - set_asid(saved_asid); } #if defined(__SH4__) -static void __flush_tlb_phys(struct mm_struct *mm, unsigned long phys) +static void __flush_tlb_phys(unsigned long phys) { int i; unsigned long addr, data; @@ -373,12 +385,22 @@ static void __flush_tlb_phys(struct mm_struct *mm, unsigned long phys) void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { - unsigned long flags; + if (vma->vm_mm && vma->vm_mm->context != NO_CONTEXT) { + unsigned long flags; + unsigned long asid; + unsigned long saved_asid = MMU_NO_ASID; - if (vma->vm_mm) { + asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK; page &= PAGE_MASK; + save_and_cli(flags); - __flush_tlb_page(vma->vm_mm, page); + if (vma->vm_mm != current->mm) { + saved_asid = get_asid(); + set_asid(asid); + } + __flush_tlb_page(asid, page); + if (saved_asid != MMU_NO_ASID) + set_asid(saved_asid); restore_flags(flags); } } @@ -397,13 +419,22 @@ void flush_tlb_range(struct mm_struct *mm, unsigned long start, if (mm == current->mm) activate_context(mm); } else { + unsigned long asid = mm->context&MMU_CONTEXT_ASID_MASK; + unsigned long saved_asid = MMU_NO_ASID; + start &= PAGE_MASK; end += (PAGE_SIZE - 1); end &= PAGE_MASK; + if (mm != current->mm) { + saved_asid = get_asid(); + set_asid(asid); + } while (start < end) { - __flush_tlb_page(mm, start); + __flush_tlb_page(asid, start); start += PAGE_SIZE; } + if (saved_asid != MMU_NO_ASID) + set_asid(saved_asid); } restore_flags(flags); } diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 5e0632a86..8568afb31 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -227,7 +227,7 @@ void __init paging_init(void) zones_size[ZONE_DMA] = max_dma - start_pfn; zones_size[ZONE_NORMAL] = low - max_dma; } - free_area_init_node(0, 0, zones_size, __MEMORY_START, 0); + free_area_init_node(0, 0, 0, zones_size, __MEMORY_START, 0); } } @@ -241,6 +241,7 @@ void __init mem_init(void) /* clear the zero-page */ memset(empty_zero_page, 0, PAGE_SIZE); + flush_page_to_ram(virt_to_page(empty_zero_page)); /* this will put all low memory onto the freelists */ totalram_pages += free_all_bootmem(); diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S index ad1fc1c1b..93ea453cb 100644 --- a/arch/sh/vmlinux.lds.S +++ b/arch/sh/vmlinux.lds.S @@ -4,9 +4,9 @@ */ #include <linux/config.h> #ifdef CONFIG_CPU_LITTLE_ENDIAN -OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl") +OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux") #else -OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh") +OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux") #endif OUTPUT_ARCH(sh) ENTRY(_start) @@ -89,6 +89,7 @@ SECTIONS /DISCARD/ : { *(.text.exit) *(.data.exit) + *(.exitcall.exit) } /* Stabs debugging sections. */ diff --git a/arch/sparc/config.in b/arch/sparc/config.in index ef948c181..0a7c2140a 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -94,15 +94,7 @@ dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET # bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y #fi -tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD -dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD -dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD -dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD -#dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD -#if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then -# bool ' Boot support' CONFIG_MD_BOOT -# bool ' Auto Detect support' CONFIG_AUTODETECT_RAID -#fi +include drivers/md/Config.in tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index c8c79591c..d57c23c1f 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.60 2000/08/12 08:35:53 ecd Exp $ +# $Id: Makefile,v 1.61 2000/09/03 13:58:04 anton Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -22,7 +22,7 @@ IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o O_OBJS := entry.o wof.o wuf.o etrap.o rtrap.o traps.o ${IRQ_OBJS} \ process.o signal.o ioport.o setup.o idprom.o \ sys_sparc.o sunos_asm.o sparc-stub.o systbls.o \ - time.o windows.o cpu.o devices.o sclow.o solaris.o \ + time.o windows.o cpu.o devices.o sclow.o \ tadpole.o tick14.o ptrace.o sys_solaris.o \ unaligned.o muldiv.o pcic.o semaphore.o diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index f701027e0..c44fe3196 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.166 2000/06/19 06:24:36 davem Exp $ +/* $Id: entry.S,v 1.167 2000/09/06 00:45:00 davem Exp $ * arch/sparc/kernel/entry.S: Sparc trap low-level entry points. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1391,6 +1391,7 @@ flush_patch_two: mov %fp, %o1 ! arg1: usp std %g4, [%curptr + AOFF_task_thread + AOFF_thread_fork_kpsr] add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr + mov 0, %o3 call C_LABEL(do_fork) mov %l5, %o7 @@ -1413,6 +1414,7 @@ flush_patch_three: 1: std %g4, [%curptr + AOFF_task_thread + AOFF_thread_fork_kpsr] add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr + mov 0, %o3 call C_LABEL(do_fork) mov %l5, %o7 @@ -1430,6 +1432,7 @@ flush_patch_four: mov %fp, %o1 or %o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0 sethi %hi(C_LABEL(do_fork)), %l1 + mov 0, %o3 jmpl %l1 + %lo(C_LABEL(do_fork)), %g0 add %sp, REGWIN_SZ, %o2 diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index f2aa6cae4..eaa7fc4a3 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.106 2000/08/05 10:48:40 davem Exp $ +/* $Id: irq.c,v 1.109 2000/08/31 10:00:39 anton Exp $ * arch/sparc/kernel/irq.c: Interrupt request handling routines. On the * Sparc the IRQ's are basically 'cast in stone' * and you are supposed to probe the prom's device @@ -8,7 +8,7 @@ * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) * Copyright (C) 1995 Pete A. Zaitcev (zaitcev@metabyte.com) * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk) - * Copyright (C) 1998-99 Anton Blanchard (anton@progsoc.uts.edu.au) + * Copyright (C) 1998-2000 Anton Blanchard (anton@linuxcare.com) */ #include <linux/config.h> @@ -196,41 +196,29 @@ void free_irq(unsigned int irq, void *dev_id) } #ifdef CONFIG_SMP -/* SMP interrupt locking on Sparc. */ -/* Who has global_irq_lock. */ +/* Who has the global irq brlock */ unsigned char global_irq_holder = NO_PROC_ID; -/* This protects IRQ's. */ -spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED; - -/* Global IRQ locking depth. */ -atomic_t global_irq_count = ATOMIC_INIT(0); - void smp_show_backtrace_all_cpus(void); void show_backtrace(void); -#define MAXCOUNT 100000000 #define VERBOSE_DEBUG_IRQLOCK +#define MAXCOUNT 100000000 static void show(char * str) { - int i; int cpu = smp_processor_id(); + int i; printk("\n%s, CPU %d:\n", str, cpu); - printk("irq: %d [ ", atomic_read(&global_irq_count)); - - for (i = 0; i < NR_CPUS; i++) { - printk("%d ", local_irq_count(i)); - } - printk("]\n"); - - printk("bh: %d [ ", (spin_is_locked(&global_bh_lock) ? 1 : 0)); - - for (i = 0; i < NR_CPUS; i++) { - printk("%d ", local_bh_count(cpu)); - } + printk("irq: %d [ ", irqs_running()); + for (i = 0; i < smp_num_cpus; i++) + printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]); + printk("]\nbh: %d [ ", + (spin_is_locked(&global_bh_lock) ? 1 : 0)); + for (i = 0; i < smp_num_cpus; i++) + printk("%u ", local_bh_count(i)); printk("]\n"); #ifdef VERBOSE_DEBUG_IRQLOCK @@ -240,48 +228,11 @@ static void show(char * str) #endif } + /* * We have to allow irqs to arrive between __sti and __cli */ -#define SYNC_OTHER_CORES(x) udelay(x+1) - -static inline void wait_on_irq(int cpu) -{ - int count = MAXCOUNT; - - for (;;) { - /* - * Wait until all interrupts are gone. Wait - * for bottom half handlers unless we're - * already executing in one.. - */ - if (!atomic_read(&global_irq_count)) { - if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock)) - break; - } - - /* Duh, we have to loop. Release the lock to avoid deadlocks */ - spin_unlock(&global_irq_lock); - - for (;;) { - if (!--count) { - show("wait_on_irq"); - count = ~0; - } - __sti(); - SYNC_OTHER_CORES(cpu); - __cli(); - if (atomic_read(&global_irq_count)) - continue; - if (spin_is_locked (&global_irq_lock)) - continue; - if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock)) - continue; - if (spin_trylock(&global_irq_lock)) - break; - } - } -} +#define SYNC_OTHER_CORES(x) barrier() /* * This is called when we want to synchronize with @@ -292,8 +243,7 @@ static inline void wait_on_irq(int cpu) */ void synchronize_irq(void) { - if (atomic_read(&global_irq_count)) { - /* Stupid approach */ + if (irqs_running()) { cli(); sti(); } @@ -301,32 +251,37 @@ void synchronize_irq(void) static inline void get_irqlock(int cpu) { - int count = MAXCOUNT; + int count; - if (!spin_trylock(&global_irq_lock)) { - /* do we already hold the lock? */ - if ((unsigned char) cpu == global_irq_holder) - return; - /* Uhhuh.. Somebody else got it. Wait.. */ - do { - while (spin_is_locked(&global_irq_lock)) { - if (!--count) { - show("get_irqlock"); - count = ~0; - } - barrier(); + if ((unsigned char)cpu == global_irq_holder) + return; + + count = MAXCOUNT; +again: + br_write_lock(BR_GLOBALIRQ_LOCK); + for (;;) { + spinlock_t *lock; + + if (!irqs_running() && + (local_bh_count(smp_processor_id()) || !spin_is_locked(&global_bh_lock))) + break; + + br_write_unlock(BR_GLOBALIRQ_LOCK); + lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock; + while (irqs_running() || + spin_is_locked(lock) || + (!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) { + if (!--count) { + show("get_irqlock"); + count = (~0 >> 1); } - } while (!spin_trylock(&global_irq_lock)); + __sti(); + SYNC_OTHER_CORES(cpu); + __cli(); + } + goto again; } - /* - * We also to make sure that nobody else is running - * in an interrupt context. - */ - wait_on_irq(cpu); - /* - * Ok, finally.. - */ global_irq_holder = cpu; } @@ -344,7 +299,7 @@ static inline void get_irqlock(int cpu) */ void __global_cli(void) { - unsigned int flags; + unsigned long flags; __save_flags(flags); @@ -374,9 +329,8 @@ void __global_sti(void) */ unsigned long __global_save_flags(void) { - int retval; - int local_enabled = 0; - unsigned long flags; + unsigned long flags, retval; + unsigned long local_enabled = 0; __save_flags(flags); diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index d5ce7038a..028612687 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -1,4 +1,4 @@ -/* $Id: pcic.c,v 1.16 2000/07/11 01:38:57 davem Exp $ +/* $Id: pcic.c,v 1.18 2000/09/25 06:09:12 anton Exp $ * pcic.c: Sparc/PCI controller support * * Copyright (C) 1998 V. Roganov and G. Raiko @@ -35,11 +35,6 @@ #ifndef CONFIG_PCI -int pcibios_present(void) -{ - return 0; -} - asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn, unsigned long off, @@ -940,7 +935,6 @@ asmlinkage int sys_pciconfig_read(unsigned long bus, if(!suser()) return -EPERM; - lock_kernel(); switch(len) { case 1: pcibios_read_config_byte(bus, dfn, off, &ubyte); @@ -959,7 +953,6 @@ asmlinkage int sys_pciconfig_read(unsigned long bus, err = -EINVAL; break; }; - unlock_kernel(); return err; } @@ -978,7 +971,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus, if(!suser()) return -EPERM; - lock_kernel(); switch(len) { case 1: err = get_user(ubyte, (unsigned char *)buf); @@ -1006,7 +998,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus, break; }; - unlock_kernel(); return err; } diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index f119c59ac..fe45f1f3c 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.151 2000/07/11 23:22:17 davem Exp $ +/* $Id: process.c,v 1.153 2000/09/06 00:45:01 davem Exp $ * linux/arch/sparc/kernel/process.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -234,7 +234,6 @@ void show_backtrace(void) void smp_show_backtrace_all_cpus(void) { xc0((smpfunc_t) show_backtrace); - show_backtrace(); } #endif @@ -462,6 +461,7 @@ extern void ret_from_syscall(void); #endif int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, + unsigned long unused, struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index 5398a9381..bce4ffcdf 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.118 2000/05/09 17:40:13 davem Exp $ +/* $Id: setup.c,v 1.119 2000/08/31 10:24:17 anton Exp $ * linux/arch/sparc/kernel/setup.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -80,12 +80,7 @@ void prom_sync_me(void) { unsigned long prom_tbr, flags; -#ifdef CONFIG_SMP - global_irq_holder = NO_PROC_ID; - *((unsigned char *)&global_irq_lock) = 0; - *((unsigned char *)&global_bh_lock) = 0; -#endif - __save_and_cli(flags); + save_and_cli(flags); __asm__ __volatile__("rd %%tbr, %0\n\t" : "=r" (prom_tbr)); __asm__ __volatile__("wr %0, 0x0, %%tbr\n\t" "nop\n\t" @@ -99,9 +94,9 @@ void prom_sync_me(void) prom_printf("PROM SYNC COMMAND...\n"); show_free_areas(); if(current->pid != 0) { - __sti(); + sti(); sys_sync(); - __cli(); + cli(); } prom_printf("Returning to prom\n"); @@ -109,7 +104,7 @@ void prom_sync_me(void) "nop\n\t" "nop\n\t" "nop\n\t" : : "r" (prom_tbr)); - __restore_flags(flags); + restore_flags(flags); return; } diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c index bcad13dbc..6ac8c4b00 100644 --- a/arch/sparc/kernel/signal.c +++ b/arch/sparc/kernel/signal.c @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.106 2000/07/07 04:25:17 davem Exp $ +/* $Id: signal.c,v 1.107 2000/09/05 21:44:54 davem Exp $ * linux/arch/sparc/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -1282,7 +1282,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, #endif /* fall through */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 677b2c811..0e1944411 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c @@ -145,35 +145,33 @@ void __init smp_boot_cpus(void) void smp_flush_cache_all(void) { xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all)); - local_flush_cache_all(); } void smp_flush_tlb_all(void) { xc0((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_all)); - local_flush_tlb_all(); } void smp_flush_cache_mm(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_cache_mm(mm); + else xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm); - - local_flush_cache_mm(mm); } } void smp_flush_tlb_mm(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) { + if(mm->cpu_vm_mask == (1 << smp_processor_id())) { + local_flush_tlb_mm(mm); + } else { xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm); if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) mm->cpu_vm_mask = (1 << smp_processor_id()); } - - local_flush_tlb_mm(mm); } } @@ -181,10 +179,10 @@ void smp_flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_cache_range(mm, start, end); + else xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) mm, start, end); - - local_flush_cache_range(mm, start, end); } } @@ -192,10 +190,10 @@ void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_tlb_range(mm, start, end); + else xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) mm, start, end); - - local_flush_tlb_range(mm, start, end); } } @@ -204,10 +202,10 @@ void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page) struct mm_struct *mm = vma->vm_mm; if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_cache_page(vma, page); + else xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page); - - local_flush_cache_page(vma, page); } } @@ -216,10 +214,10 @@ void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) struct mm_struct *mm = vma->vm_mm; if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_tlb_page(vma, page); + else xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page); - - local_flush_tlb_page(vma, page); } } @@ -233,7 +231,6 @@ void smp_flush_page_to_ram(unsigned long page) */ #if 1 xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_to_ram), page); - local_flush_page_to_ram(page); #else local_flush_page_to_ram(page); #endif @@ -241,10 +238,10 @@ void smp_flush_page_to_ram(unsigned long page) void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) { - if(mm->cpu_vm_mask != (1 << smp_processor_id())) + if(mm->cpu_vm_mask == (1 << smp_processor_id())) + local_flush_sig_insns(mm, insn_addr); + else xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr); - - local_flush_sig_insns(mm, insn_addr); } /* Reschedule call back. */ diff --git a/arch/sparc/kernel/solaris.c b/arch/sparc/kernel/solaris.c deleted file mode 100644 index bcebd9262..000000000 --- a/arch/sparc/kernel/solaris.c +++ /dev/null @@ -1,39 +0,0 @@ -/* solaris.c: Solaris binary emulation, whee... - * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/fcntl.h> -#include <linux/sched.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> - -#include <asm/errno.h> -#include <asm/solerrno.h> - -asmlinkage int solaris_open(const char *filename, int flags, int mode) -{ - int newflags; - int ret; - - lock_kernel(); - newflags = flags & 0xf; - flags &= ~0xf; - if(flags & 0x8050) - newflags |= FASYNC; - if(flags & 0x80) - newflags |= O_NONBLOCK; - if(flags & 0x100) - newflags |= O_CREAT; - if(flags & 0x200) - newflags |= O_TRUNC; - if(flags & 0x400) - newflags |= O_EXCL; - if(flags & 0x800) - newflags |= O_NOCTTY; - ret = sys_open(filename, newflags, mode); - unlock_kernel(); - return ret; -} diff --git a/arch/sparc/kernel/sparc-stub.c b/arch/sparc/kernel/sparc-stub.c index c9bb60a86..a0e5f6ad2 100644 --- a/arch/sparc/kernel/sparc-stub.c +++ b/arch/sparc/kernel/sparc-stub.c @@ -123,7 +123,7 @@ extern char getDebugChar(void); /* read and return a single char */ */ #define BUFMAX 2048 -static int initialized = 0; /* !0 means we've been initialized */ +static int initialized; /* !0 means we've been initialized */ static const char hexchars[]="0123456789abcdef"; diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index e05b20f4e..997e4d0ce 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.102 2000/08/05 10:48:40 davem Exp $ +/* $Id: sparc_ksyms.c,v 1.104 2000/09/06 05:43:00 anton Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -111,13 +111,6 @@ EXPORT_SYMBOL_PRIVATE(_rw_read_enter); EXPORT_SYMBOL_PRIVATE(_rw_read_exit); EXPORT_SYMBOL_PRIVATE(_rw_write_enter); #endif -#ifdef CONFIG_SMP -EXPORT_SYMBOL(__global_save_flags); -EXPORT_SYMBOL(__global_restore_flags); -EXPORT_SYMBOL(__global_sti); -EXPORT_SYMBOL(__global_cli); -#endif - /* rw semaphores */ EXPORT_SYMBOL_NOVERS(___down_read); EXPORT_SYMBOL_NOVERS(___down_write); @@ -137,14 +130,22 @@ EXPORT_SYMBOL_PRIVATE(_change_bit); EXPORT_SYMBOL_PRIVATE(_set_le_bit); EXPORT_SYMBOL_PRIVATE(_clear_le_bit); -/* IRQ implementation. */ #ifdef CONFIG_SMP +/* Kernel wide locking */ EXPORT_SYMBOL(kernel_flag); + +/* IRQ implementation. */ EXPORT_SYMBOL(global_irq_holder); -EXPORT_SYMBOL(global_irq_lock); -EXPORT_SYMBOL(global_bh_lock); -EXPORT_SYMBOL(global_irq_count); EXPORT_SYMBOL(synchronize_irq); +EXPORT_SYMBOL(__global_cli); +EXPORT_SYMBOL(__global_sti); +EXPORT_SYMBOL(__global_save_flags); +EXPORT_SYMBOL(__global_restore_flags); + +/* Misc SMP information */ +EXPORT_SYMBOL(smp_num_cpus); +EXPORT_SYMBOL(__cpu_number_map); +EXPORT_SYMBOL(__cpu_logical_map); #endif EXPORT_SYMBOL(udelay); diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 280392629..3a4e93eb8 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -376,6 +376,9 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } } + /* First, run local copy. */ + func(arg1, arg2, arg3, arg4, arg5); + { register int i; @@ -393,6 +396,8 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } spin_unlock_irqrestore(&cross_call_lock, flags); + } else { + func(arg1, arg2, arg3, arg4, arg5); /* Just need to run local copy. */ } } diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index d6c126d00..52c37f51b 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -405,6 +405,9 @@ void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } } + /* First, run local copy. */ + func(arg1, arg2, arg3, arg4, arg5); + { register int i; @@ -422,6 +425,8 @@ void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, } spin_unlock_irqrestore(&cross_call_lock, flags); + } else { + func(arg1, arg2, arg3, arg4, arg5); /* Just need to run local copy. */ } } diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c index dc26d2cc2..61df3ea6d 100644 --- a/arch/sparc/kernel/sunos_ioctl.c +++ b/arch/sparc/kernel/sunos_ioctl.c @@ -1,4 +1,4 @@ -/* $Id: sunos_ioctl.c,v 1.33 1999/07/28 12:59:03 anton Exp $ +/* $Id: sunos_ioctl.c,v 1.34 2000/09/03 14:10:56 anton Exp $ * sunos_ioctl.c: The Linux Operating system: SunOS ioctl compatibility. * * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -39,7 +39,6 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg) { int ret = -EBADF; - lock_kernel(); if (fd >= SUNOS_NR_OPEN || !fcheck(fd)) goto out; @@ -227,7 +226,6 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg) /* so stupid... */ ret = (ret == -EINVAL ? -EOPNOTSUPP : ret); out: - unlock_kernel(); return ret; } diff --git a/arch/sparc/kernel/sys_solaris.c b/arch/sparc/kernel/sys_solaris.c index d099c4e8a..fb7578554 100644 --- a/arch/sparc/kernel/sys_solaris.c +++ b/arch/sparc/kernel/sys_solaris.c @@ -16,30 +16,13 @@ #include <linux/smp_lock.h> #include <linux/module.h> -/* CHECKME: this stuff looks rather bogus */ asmlinkage int do_solaris_syscall (struct pt_regs *regs) { - int ret; - - lock_kernel(); - set_personality(PER_SVR4); - - if (current->exec_domain && current->exec_domain->handler){ - current->exec_domain->handler (0, regs); - - /* What is going on here? Why do we do this? */ - - /* XXX current->exec_domain->use_count = 0; XXX */ - - ret = regs->u_regs [UREG_I0]; - } else { - printk ("No solaris handler\n"); - send_sig (SIGSEGV, current, 1); - ret = 0; - } - unlock_kernel(); - return ret; + static int cnt = 0; + if (++cnt < 10) printk ("No solaris handler\n"); + force_sig(SIGSEGV, current); + return 0; } #ifndef CONFIG_SUNOS_EMUL @@ -48,9 +31,7 @@ do_sunos_syscall (struct pt_regs *regs) { static int cnt = 0; if (++cnt < 10) printk ("SunOS binary emulation not compiled in\n"); - lock_kernel(); force_sig (SIGSEGV, current); - unlock_kernel(); return 0; } #endif diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 43ffb3d33..980981592 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.56 2000/06/13 22:51:28 anton Exp $ +/* $Id: time.c,v 1.57 2000/09/16 07:33:45 davem Exp $ * linux/arch/sparc/kernel/time.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -149,37 +149,6 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) write_unlock(&xtime_lock); } -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ static void __init kick_start_clock(void) { diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c index 3564a4517..5c361f933 100644 --- a/arch/sparc/kernel/traps.c +++ b/arch/sparc/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.63 2000/06/04 06:23:52 anton Exp $ +/* $Id: traps.c,v 1.64 2000/09/03 15:00:49 anton Exp $ * arch/sparc/kernel/traps.c * * Copyright 1995 David S. Miller (davem@caip.rutgers.edu) @@ -132,7 +132,6 @@ void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc) { siginfo_t info; - lock_kernel(); if(type < 0x80) { /* Sun OS's puke from bad traps, Linux survives! */ printk("Unimplemented Sparc TRAP, type = %02lx\n", type); @@ -148,7 +147,6 @@ void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc) info.si_addr = (void *)pc; info.si_trapno = type - 0x80; force_sig_info(SIGILL, &info, current); - unlock_kernel(); } void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -156,7 +154,6 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon { siginfo_t info; - lock_kernel(); if(psr & PSR_PS) die_if_kernel("Kernel illegal instruction", regs); #ifdef TRAP_DEBUG @@ -166,7 +163,7 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon if (sparc_cpu_model == sun4c || sparc_cpu_model == sun4) { extern int do_user_muldiv (struct pt_regs *, unsigned long); if (!do_user_muldiv (regs, pc)) - goto out; + return; } info.si_signo = SIGILL; info.si_errno = 0; @@ -174,8 +171,6 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGILL, &info, current); -out: - unlock_kernel(); } void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -183,7 +178,6 @@ void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long n { siginfo_t info; - lock_kernel(); if(psr & PSR_PS) die_if_kernel("Penguin instruction from Penguin mode??!?!", regs); info.si_signo = SIGILL; @@ -192,7 +186,6 @@ void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long n info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGILL, &info, current); - unlock_kernel(); } /* XXX User may want to be allowed to do this. XXX */ @@ -202,7 +195,6 @@ void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned lon { siginfo_t info; - lock_kernel(); if(regs->psr & PSR_PS) { printk("KERNEL MNA at pc %08lx npc %08lx called by %08lx\n", pc, npc, regs->u_regs[UREG_RETPC]); @@ -220,7 +212,6 @@ void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned lon info.si_addr = /* FIXME: Should dig out mna address */ (void *)0; info.si_trapno = 0; send_sig_info(SIGBUS, &info, current); - unlock_kernel(); } extern void fpsave(unsigned long *fpregs, unsigned long *fsr, @@ -237,7 +228,6 @@ static unsigned long init_fregs[32] __attribute__ ((aligned (8))) = void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { - lock_kernel(); /* Sanity check... */ if(psr & PSR_PS) die_if_kernel("Kernel gets FloatingPenguinUnit disabled trap", regs); @@ -246,7 +236,7 @@ void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, regs->psr |= PSR_EF; #ifndef CONFIG_SMP if(last_task_used_math == current) - goto out; + return; if(last_task_used_math) { /* Other processes fpu state, save away */ struct task_struct *fptask = last_task_used_math; @@ -270,10 +260,6 @@ void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, } current->flags |= PF_USEDFPU; #endif -#ifndef CONFIG_SMP -out: -#endif - unlock_kernel(); } static unsigned long fake_regs[32] __attribute__ ((aligned (8))); @@ -295,7 +281,6 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, #else struct task_struct *fpt = current; #endif - lock_kernel(); put_psr(get_psr() | PSR_EF); /* If nobody owns the fpu right now, just clear the * error into our fake static buffer and hope it don't @@ -308,7 +293,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, #endif fpsave(&fake_regs[0], &fake_fsr, &fake_queue[0], &fake_depth); regs->psr &= ~PSR_EF; - goto out; + return; } fpsave(&fpt->thread.float_regs[0], &fpt->thread.fsr, &fpt->thread.fpqueue[0], &fpt->thread.fpqdepth); @@ -361,7 +346,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, if(calls > 2) die_if_kernel("Too many Penguin-FPU traps from kernel mode", regs); - goto out; + return; } fsr = fpt->thread.fsr; @@ -389,8 +374,6 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, regs->psr &= ~PSR_EF; if(calls > 0) calls=0; -out: - unlock_kernel(); } void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -398,7 +381,6 @@ void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long n { siginfo_t info; - lock_kernel(); if(psr & PSR_PS) die_if_kernel("Penguin overflow trap from kernel mode", regs); info.si_signo = SIGEMT; @@ -407,13 +389,11 @@ void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long n info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGEMT, &info, current); - unlock_kernel(); } void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { - lock_kernel(); #ifdef TRAP_DEBUG printk("Watchpoint detected at PC %08lx NPC %08lx PSR %08lx\n", pc, npc, psr); @@ -421,7 +401,6 @@ void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc if(psr & PSR_PS) panic("Tell me what a watchpoint trap is, and I'll then deal " "with such a beast..."); - unlock_kernel(); } void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -429,7 +408,6 @@ void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc { siginfo_t info; - lock_kernel(); #ifdef TRAP_DEBUG printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n", pc, npc, psr); @@ -440,7 +418,6 @@ void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc info.si_addr = (void *)pc; info.si_trapno = 0; force_sig_info(SIGBUS, &info, current); - unlock_kernel(); } void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -448,14 +425,12 @@ void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long np { siginfo_t info; - lock_kernel(); info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_COPROC; info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGILL, &info, current); - unlock_kernel(); } void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -463,7 +438,6 @@ void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long n { siginfo_t info; - lock_kernel(); #ifdef TRAP_DEBUG printk("Co-Processor Exception at PC %08lx NPC %08lx PSR %08lx\n", pc, npc, psr); @@ -474,7 +448,6 @@ void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long n info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGILL, &info, current); - unlock_kernel(); } void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc, @@ -482,15 +455,12 @@ void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc { siginfo_t info; - lock_kernel(); info.si_signo = SIGFPE; info.si_errno = 0; info.si_code = FPE_INTDIV; info.si_addr = (void *)pc; info.si_trapno = 0; send_sig_info(SIGFPE, &info, current); - - unlock_kernel(); } /* Since we have our mappings set up, on multiprocessors we can spin them diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index b323ccacd..642c986bd 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.91 2000/08/09 23:10:19 anton Exp $ +/* $Id: init.c,v 1.93 2000/08/31 11:40:55 anton Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -89,8 +89,6 @@ pgprot_t kmap_prot; void __init kmap_init(void) { - unsigned long pteval; - /* cache the first kmap pte */ kmap_pte = kmap_get_fixed_pte(FIX_KMAP_BEGIN); kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE); @@ -583,6 +581,6 @@ void flush_page_to_ram(struct page *page) { unsigned long vaddr; vaddr = kmap(page); - __flush_page_to_ram(page_address(page)); + __flush_page_to_ram((unsigned long)page_address(page)); kunmap(page); } diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 4f5bd16c5..408d59cbf 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.221 2000/08/14 00:46:13 anton Exp $ +/* $Id: srmmu.c,v 1.222 2000/08/29 08:59:23 davem Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -1323,8 +1323,8 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma, mapping = file->f_dentry->d_inode->i_mapping; offset = (address & PAGE_MASK) - vma->vm_start; spin_lock(&mapping->i_shared_lock); - vmaring = mapping->i_mmap; - do { + vmaring = mapping->i_mmap_shared; + if (vmaring != NULL) do { /* Do not mistake ourselves as another mapping. */ if(vmaring == vma) continue; diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 66bc3af7b..a99ce736e 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1,4 +1,4 @@ -/* $Id: sun4c.c,v 1.198 2000/08/14 00:46:13 anton Exp $ +/* $Id: sun4c.c,v 1.199 2000/08/29 08:59:23 davem Exp $ * sun4c.c: Doing in software what should be done in hardware. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -2404,8 +2404,8 @@ static void sun4c_vac_alias_fixup(struct vm_area_struct *vma, unsigned long addr mapping = vma->vm_file->f_dentry->d_inode->i_mapping; spin_lock(&mapping->i_shared_lock); - vmaring = mapping->i_mmap; - do { + vmaring = mapping->i_mmap_shared; + if (vmaring != NULL) do { unsigned long vaddr = vmaring->vm_start + offset; unsigned long start; diff --git a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c index c2b857459..bf61ff1a7 100644 --- a/arch/sparc/prom/console.c +++ b/arch/sparc/prom/console.c @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.22 2000/02/08 20:24:23 davem Exp $ +/* $Id: console.c,v 1.23 2000/08/26 02:38:03 anton Exp $ * console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. * @@ -30,7 +30,7 @@ prom_nbgetchar(void) int i = -1; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_SUN4: @@ -49,7 +49,7 @@ prom_nbgetchar(void) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return i; /* Ugh, we could spin forever on unsupported proms ;( */ } @@ -63,7 +63,7 @@ prom_nbputchar(char c) unsigned long flags; int i = -1; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_SUN4: @@ -82,7 +82,7 @@ prom_nbputchar(char c) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return i; /* Ugh, we could spin forever on unsupported proms ;( */ } @@ -125,10 +125,10 @@ prom_query_input_device() return PROMDEV_I_UNK; }; case PROM_V3: - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); if(prom_node_has_property(st_p, "keyboard")) return PROMDEV_IKBD; if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) { @@ -174,10 +174,10 @@ prom_query_output_device() break; case PROM_V2: case PROM_V3: - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb)); if (propl >= 0 && propl == sizeof("display") && strncmp("display", propb, sizeof("display")) == 0) diff --git a/arch/sparc/prom/devmap.c b/arch/sparc/prom/devmap.c index 463b07527..eb1207357 100644 --- a/arch/sparc/prom/devmap.c +++ b/arch/sparc/prom/devmap.c @@ -1,4 +1,4 @@ -/* $Id: devmap.c,v 1.6 1998/03/09 14:04:23 jj Exp $ +/* $Id: devmap.c,v 1.7 2000/08/26 02:38:03 anton Exp $ * promdevmap.c: Map device/IO areas to virtual addresses. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -29,13 +29,13 @@ prom_mapio(char *vhint, int ios, unsigned int paddr, unsigned int num_bytes) unsigned long flags; char *ret; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); if((num_bytes == 0) || (paddr == 0)) ret = (char *) 0x0; else ret = (*(romvec->pv_v2devops.v2_dumb_mmap))(vhint, ios, paddr, num_bytes); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -46,9 +46,9 @@ prom_unmapio(char *vaddr, unsigned int num_bytes) unsigned long flags; if(num_bytes == 0x0) return; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); (*(romvec->pv_v2devops.v2_dumb_munmap))(vaddr, num_bytes); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return; } diff --git a/arch/sparc/prom/devops.c b/arch/sparc/prom/devops.c index 5a58efa0b..61919b54f 100644 --- a/arch/sparc/prom/devops.c +++ b/arch/sparc/prom/devops.c @@ -1,4 +1,4 @@ -/* $Id: devops.c,v 1.12 2000/01/29 01:09:12 anton Exp $ +/* $Id: devops.c,v 1.13 2000/08/26 02:38:03 anton Exp $ * devops.c: Device operations using the PROM. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -21,7 +21,7 @@ prom_devopen(char *dstr) { int handle; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: handle = (*(romvec->pv_v0devops.v0_devopen))(dstr); @@ -36,7 +36,7 @@ prom_devopen(char *dstr) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return handle; } @@ -46,7 +46,7 @@ int prom_devclose(int dhandle) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: (*(romvec->pv_v0devops.v0_devclose))(dhandle); @@ -59,7 +59,7 @@ prom_devclose(int dhandle) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return 0; } @@ -70,7 +70,7 @@ void prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo); @@ -83,7 +83,7 @@ prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return; } diff --git a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c index 3c2f2434d..86ce39910 100644 --- a/arch/sparc/prom/misc.c +++ b/arch/sparc/prom/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.17 1998/07/21 10:36:22 jj Exp $ +/* $Id: misc.c,v 1.18 2000/08/26 02:38:03 anton Exp $ * misc.c: Miscellaneous prom functions that don't belong * anywhere else. * @@ -15,16 +15,18 @@ extern void restore_current(void); +spinlock_t prom_lock = SPIN_LOCK_UNLOCKED; + /* Reset and reboot the machine with the command 'bcommand'. */ void prom_reboot(char *bcommand) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); (*(romvec->pv_reboot))(bcommand); /* Never get here. */ restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); } /* Forth evaluate the expression contained in 'fstring'. */ @@ -34,13 +36,13 @@ prom_feval(char *fstring) unsigned long flags; if(!fstring || fstring[0] == 0) return; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); if(prom_vers == PROM_V0) (*(romvec->pv_fortheval.v0_eval))(strlen(fstring), fstring); else (*(romvec->pv_fortheval.v2_eval))(fstring); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); } /* We want to do this more nicely some day. */ @@ -66,10 +68,10 @@ prom_cmdline(void) prom_palette (1); #endif install_obp_ticker(); - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); (*(romvec->pv_abort))(); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); install_linux_ticker(); #ifdef CONFIG_SUN_AUXIO TURN_ON_LED; @@ -88,11 +90,11 @@ prom_halt(void) { unsigned long flags; again: - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); (*(romvec->pv_halt))(); /* Never get here. */ restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); goto again; /* PROM is out to get me -DaveM */ } diff --git a/arch/sparc/prom/mp.c b/arch/sparc/prom/mp.c index ba624673f..92fe3739f 100644 --- a/arch/sparc/prom/mp.c +++ b/arch/sparc/prom/mp.c @@ -1,4 +1,4 @@ -/* $Id: mp.c,v 1.11 2000/01/29 01:09:12 anton Exp $ +/* $Id: mp.c,v 1.12 2000/08/26 02:38:03 anton Exp $ * mp.c: OpenBoot Prom Multiprocessor support routines. Don't call * these on a UP or else you will halt and catch fire. ;) * @@ -25,7 +25,7 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha int ret; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_V2: @@ -37,7 +37,7 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -51,7 +51,7 @@ prom_stopcpu(int cpunode) int ret; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_V2: @@ -63,7 +63,7 @@ prom_stopcpu(int cpunode) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -77,7 +77,7 @@ prom_idlecpu(int cpunode) int ret; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_V2: @@ -89,7 +89,7 @@ prom_idlecpu(int cpunode) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -103,7 +103,7 @@ prom_restartcpu(int cpunode) int ret; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: case PROM_V2: @@ -115,7 +115,7 @@ prom_restartcpu(int cpunode) break; }; restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } diff --git a/arch/sparc/prom/segment.c b/arch/sparc/prom/segment.c index 62b3f8542..09d646016 100644 --- a/arch/sparc/prom/segment.c +++ b/arch/sparc/prom/segment.c @@ -1,4 +1,4 @@ -/* $Id: segment.c,v 1.6 1998/03/09 14:04:27 jj Exp $ +/* $Id: segment.c,v 1.7 2000/08/26 02:38:03 anton Exp $ * segment.c: Prom routine to map segments in other contexts before * a standalone is completely mapped. This is for sun4 and * sun4c architectures only. @@ -21,9 +21,9 @@ void prom_putsegment(int ctx, unsigned long vaddr, int segment) { unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); (*(romvec->pv_setctxt))(ctx, (char *) vaddr, segment); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return; } diff --git a/arch/sparc/prom/tree.c b/arch/sparc/prom/tree.c index 2e79057d8..adfe6e75a 100644 --- a/arch/sparc/prom/tree.c +++ b/arch/sparc/prom/tree.c @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.25 1998/09/17 11:04:58 jj Exp $ +/* $Id: tree.c,v 1.26 2000/08/26 02:38:03 anton Exp $ * tree.c: Basic device tree traversal/scanning for the Linux * prom library. * @@ -26,10 +26,10 @@ int __prom_getchild(int node) unsigned long flags; int cnode; - save_and_cli(flags); + spin_lock_irqsave(&prom_lock, flags); cnode = prom_nodeops->no_child(node); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return cnode; } @@ -57,10 +57,10 @@ int __prom_getsibling(int node) unsigned long flags; int cnode; - save_and_cli(flags); + spin_lock_irqsave(&prom_lock, flags); cnode = prom_nodeops->no_nextnode(node); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return cnode; } @@ -93,10 +93,10 @@ int prom_getproplen(int node, char *prop) if((!node) || (!prop)) return -1; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); ret = prom_nodeops->no_proplen(node, prop); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -113,10 +113,10 @@ int prom_getproperty(int node, char *prop, char *buffer, int bufsize) if((plen > bufsize) || (plen == 0) || (plen == -1)) return -1; /* Ok, things seem all right. */ - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); ret = prom_nodeops->no_getprop(node, prop, buffer); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -226,10 +226,10 @@ char * __prom_nextprop(int node, char * oprop) unsigned long flags; char *prop; - save_and_cli(flags); + spin_lock_irqsave(&prom_lock, flags); prop = prom_nodeops->no_nextprop(node, oprop); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return prop; } @@ -325,10 +325,10 @@ int prom_setprop(int node, char *pname, char *value, int size) if(size == 0) return 0; if((pname == 0) || (value == 0)) return 0; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); ret = prom_nodeops->no_setprop(node, pname, value, size); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); return ret; } @@ -337,10 +337,10 @@ int prom_inst2pkg(int inst) int node; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&prom_lock, flags); node = (*romvec->pv_v2devops.v2_inst2pkg)(inst); restore_current(); - restore_flags(flags); + spin_unlock_irqrestore(&prom_lock, flags); if (node == -1) return 0; return node; } diff --git a/arch/sparc64/boot/piggyback.c b/arch/sparc64/boot/piggyback.c index 503b366db..36f907408 100644 --- a/arch/sparc64/boot/piggyback.c +++ b/arch/sparc64/boot/piggyback.c @@ -1,4 +1,4 @@ -/* $Id: piggyback.c,v 1.1 1997/07/11 11:05:26 jj Exp $ +/* $Id: piggyback.c,v 1.2 2000/09/19 14:34:39 anton Exp $ Simple utility to make a single-image install kernel with initial ramdisk for Sparc64 tftpbooting without need to set up nfs. @@ -50,9 +50,9 @@ int main(int argc,char **argv) map = fopen (argv[2], "r"); if (!map) die(argv[2]); while (fgets (buffer, 1024, map)) { - if (!strcmp (buffer + 19, "start\n")) + if (!strcmp (buffer + 19, "_start\n")) start = strtoul (buffer + 8, NULL, 16); - else if (!strcmp (buffer + 19, "end\n")) + else if (!strcmp (buffer + 19, "_end\n")) end = strtoul (buffer + 8, NULL, 16); } fclose (map); diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index bfcb973d7..c49a87ebf 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -94,15 +94,7 @@ dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET # bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y #fi -tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD -dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD -dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD -dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD -#dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD -#if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then -# bool ' Boot support' CONFIG_MD_BOOT -# bool ' Auto Detect support' CONFIG_AUTODETECT_RAID -#fi +include drivers/md/Config.in tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c index 9be09c3b0..cc26817b4 100644 --- a/arch/sparc64/kernel/auxio.c +++ b/arch/sparc64/kernel/auxio.c @@ -18,6 +18,7 @@ #include <asm/sbus.h> #include <asm/ebus.h> #include <asm/fhc.h> +#include <asm/starfire.h> /* Probe and map in the Auxiliary I/O register */ unsigned long auxio_register = 0; @@ -55,7 +56,7 @@ found_sdev: return; } #endif - if(central_bus) { + if(central_bus || this_is_starfire) { auxio_register = 0UL; return; } diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c index 2c4fb1355..dba732a6d 100644 --- a/arch/sparc64/kernel/central.c +++ b/arch/sparc64/kernel/central.c @@ -1,4 +1,4 @@ -/* $Id: central.c,v 1.13 1999/12/01 10:44:43 davem Exp $ +/* $Id: central.c,v 1.14 2000/09/21 06:25:14 anton Exp $ * central.c: Central FHC driver for Sunfire/Starfire/Wildfire. * * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com) @@ -15,6 +15,7 @@ #include <asm/page.h> #include <asm/fhc.h> +#include <asm/starfire.h> struct linux_central *central_bus = NULL; struct linux_fhc *fhc_list = NULL; @@ -254,9 +255,8 @@ void central_probe(void) cnode = prom_finddevice("/central"); if(cnode == 0 || cnode == -1) { - extern void starfire_check(void); - - starfire_check(); + if (this_is_starfire) + starfire_cpu_setup(); return; } diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index e95e0392e..fd6096ec5 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.118 2000/08/01 00:11:31 davem Exp $ +/* $Id: entry.S,v 1.120 2000/09/08 13:58:12 jj Exp $ * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points. * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -911,7 +911,7 @@ sys_fork: clr %o1 mov SIGCHLD, %o0 sys_clone: flushw movrz %o1, %fp, %o1 - nop + mov 0, %o3 ba,pt %xcc, do_fork add %sp, STACK_BIAS + REGWIN_SZ, %o2 ret_from_syscall: @@ -940,8 +940,8 @@ ret_from_syscall: 1: b,pt %xcc, ret_sys_call ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0], %o0 -sparc_exit: rdpr %otherwin, %g1 - wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate +sparc_exit: wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate + rdpr %otherwin, %g1 rdpr %cansave, %g3 add %g3, %g1, %g3 wrpr %g3, 0x0, %cansave diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 7f2e21a51..92bd3ed88 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.91 2000/08/05 10:48:40 davem Exp $ +/* $Id: irq.c,v 1.94 2000/09/21 06:27:10 anton Exp $ * irq.c: UltraSparc IRQ handling/init/registry. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -31,6 +31,7 @@ #include <asm/smp.h> #include <asm/hardirq.h> #include <asm/softirq.h> +#include <asm/starfire.h> /* Internal flag, should not be visible elsewhere at all. */ #define SA_IMAP_MASKED 0x100 @@ -123,7 +124,6 @@ int get_irq_list(char *buf) /* Now these are always passed a true fully specified sun4u INO. */ void enable_irq(unsigned int irq) { - extern int this_is_starfire; struct ino_bucket *bucket = __bucket(irq); unsigned long imap; unsigned long tid; @@ -139,9 +139,6 @@ void enable_irq(unsigned int irq) : "i" (ASI_UPA_CONFIG)); tid = ((tid & UPA_CONFIG_MID) << 9); } else { - extern unsigned int starfire_translate(unsigned long imap, - unsigned int upaid); - tid = (starfire_translate(imap, current->processor) << 26); } @@ -550,7 +547,7 @@ out: #ifdef CONFIG_SMP -/* Who has global_irq_lock. */ +/* Who has the global irq brlock */ unsigned char global_irq_holder = NO_PROC_ID; static void show(char * str) @@ -608,7 +605,7 @@ again: spin_is_locked(lock) || (!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) { if (!--count) { - show("wait_on_irq"); + show("get_irqlock"); count = (~0 >> 1); } __sti(); @@ -715,7 +712,6 @@ void handler_irq(int irq, struct pt_regs *regs) struct ino_bucket *bp, *nbp; int cpu = smp_processor_id(); #ifdef CONFIG_SMP - extern int this_is_starfire; int should_forward = (this_is_starfire == 0 && irq < 10 && current->pid != 0); @@ -1029,7 +1025,6 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *), #ifdef CONFIG_SMP static int retarget_one_irq(struct irqaction *p, int goal_cpu) { - extern int this_is_starfire; struct ino_bucket *bucket = __bucket(p->mask); unsigned long imap = bucket->imap; unsigned int tid; @@ -1041,9 +1036,6 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu) if(this_is_starfire == 0) { tid = __cpu_logical_map[goal_cpu] << 26; } else { - extern unsigned int starfire_translate(unsigned long imap, - unsigned int upaid); - tid = (starfire_translate(imap, __cpu_logical_map[goal_cpu]) << 26); } upa_writel(IMAP_VALID | (tid & IMAP_TID), imap); diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index cd28d9392..24b1a7217 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.16 2000/03/01 02:53:33 davem Exp $ +/* $Id: pci.c,v 1.17 2000/09/05 06:49:44 anton Exp $ * pci.c: UltraSparc PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -24,7 +24,6 @@ unsigned long pci_memspace_mask = 0xffffffffUL; #ifndef CONFIG_PCI /* A "nop" PCI implementation. */ -int pcibios_present(void) { return 0; } asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn, unsigned long off, unsigned long len, unsigned char *buf) @@ -274,7 +273,6 @@ asmlinkage int sys_pciconfig_read(unsigned long bus, goto out; } - lock_kernel(); switch(len) { case 1: pci_read_config_byte(dev, off, &byte); @@ -293,7 +291,6 @@ asmlinkage int sys_pciconfig_read(unsigned long bus, err = -EINVAL; break; }; - unlock_kernel(); out: return err; } @@ -318,7 +315,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus, goto out; } - lock_kernel(); switch(len) { case 1: err = get_user(byte, (u8 *)buf); @@ -346,7 +342,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus, break; }; - unlock_kernel(); out: return err; diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 8d7db0c9b..aff2de594 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1,4 +1,4 @@ -/* $Id: pci_psycho.c,v 1.16 2000/04/15 10:06:16 davem Exp $ +/* $Id: pci_psycho.c,v 1.17 2000/09/21 06:25:14 anton Exp $ * pci_psycho.c: PSYCHO/U2P specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) @@ -15,6 +15,7 @@ #include <asm/pbm.h> #include <asm/iommu.h> #include <asm/irq.h> +#include <asm/starfire.h> #include "pci_impl.h" @@ -1254,8 +1255,6 @@ static void __init psycho_scan_bus(struct pci_controller_info *p) static void __init psycho_iommu_init(struct pci_controller_info *p) { - extern int this_is_starfire; - extern void *starfire_hookup(int); unsigned long tsbbase, i; u64 control; diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 21d43bb1e..1f3386d53 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.111 2000/08/16 11:13:12 davem Exp $ +/* $Id: process.c,v 1.112 2000/09/06 00:45:01 davem Exp $ * arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) @@ -573,6 +573,7 @@ barf: * do_fork(). */ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, + unsigned long unused, struct task_struct *p, struct pt_regs *regs) { struct thread_struct *t = &p->thread; diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 602ee9ca2..7baebc89e 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c @@ -1,4 +1,4 @@ -/* $Id: sbus.c,v 1.11 2000/04/14 09:13:04 davem Exp $ +/* $Id: sbus.c,v 1.12 2000/09/21 06:25:14 anton Exp $ * sbus.c: UltraSparc SBUS controller support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -18,6 +18,7 @@ #include <asm/cache.h> #include <asm/dma.h> #include <asm/irq.h> +#include <asm/starfire.h> #include "iommu_common.h" @@ -1151,15 +1152,10 @@ void __init sbus_iommu_init(int prom_node, struct sbus_bus *sbus) upa_writeq(control, iommu->sbus_control_reg); /* Now some Xfire specific grot... */ - { - extern void *starfire_hookup(int); - extern int this_is_starfire; - - if (this_is_starfire) - sbus->starfire_cookie = starfire_hookup(sbus->portid); - else - sbus->starfire_cookie = NULL; - } + if (this_is_starfire) + sbus->starfire_cookie = starfire_hookup(sbus->portid); + else + sbus->starfire_cookie = NULL; sysio_register_error_handlers(sbus); } diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 486254fb9..84cc201fd 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.55 2000/07/24 14:13:13 anton Exp $ +/* $Id: setup.c,v 1.56 2000/09/21 06:29:01 anton Exp $ * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) @@ -37,6 +37,7 @@ #include <asm/pgtable.h> #include <asm/idprom.h> #include <asm/head.h> +#include <asm/starfire.h> #ifdef CONFIG_IP_PNP #include <net/ipconfig.h> @@ -479,6 +480,9 @@ void __init setup_arch(char **cmdline_p) conswitchp = &prom_con; #endif + /* Work out if we are starfire early on */ + check_if_starfire(); + boot_flags_init(*cmdline_p); idprom_init(); diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index d1e7e4215..c2a7833fb 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.53 2000/07/30 23:12:24 davem Exp $ +/* $Id: signal.c,v 1.54 2000/09/05 21:44:54 davem Exp $ * arch/sparc64/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -784,7 +784,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, #endif /* fall through */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index efad55a1c..6d06328dd 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -1,4 +1,4 @@ -/* $Id: signal32.c,v 1.66 2000/07/27 01:05:15 davem Exp $ +/* $Id: signal32.c,v 1.67 2000/09/05 21:44:54 davem Exp $ * arch/sparc64/kernel/signal32.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -1420,7 +1420,7 @@ asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs * regs, #endif /* fall through */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/sparc64/kernel/starfire.c b/arch/sparc64/kernel/starfire.c index 8ff7ea4d2..dc8f96b7a 100644 --- a/arch/sparc64/kernel/starfire.c +++ b/arch/sparc64/kernel/starfire.c @@ -1,7 +1,8 @@ -/* $Id: starfire.c,v 1.5 2000/01/31 04:59:12 davem Exp $ +/* $Id: starfire.c,v 1.7 2000/09/22 23:02:13 davem Exp $ * starfire.c: Starfire/E10000 support. * * Copyright (C) 1998 David S. Miller (davem@redhat.com) + * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com) */ #include <linux/kernel.h> @@ -11,23 +12,31 @@ #include <asm/oplib.h> #include <asm/smp.h> #include <asm/upa.h> +#include <asm/starfire.h> -/* A few places around the kernel check this to see if +/* + * A few places around the kernel check this to see if * they need to call us to do things in a Starfire specific * way. */ int this_is_starfire = 0; -void starfire_check(void) +void check_if_starfire(void) { int ssnode = prom_finddevice("/ssp-serial"); + if(ssnode != 0 && ssnode != -1) + this_is_starfire = 1; +} - if(ssnode != 0 && ssnode != -1) { +void starfire_cpu_setup(void) +{ + if (this_is_starfire) { +/* We do this in starfire_translate - Anton */ +#if 0 int i; - this_is_starfire = 1; - - /* Now must fixup cpu MIDs. OBP gave us a logical + /* + * Now must fixup cpu MIDs. OBP gave us a logical * linear cpuid number, not the real upaid. */ for(i = 0; i < linux_num_cpus; i++) { @@ -39,6 +48,7 @@ void starfire_check(void) linux_cpus[i].mid = mid; } +#endif } } @@ -47,7 +57,8 @@ int starfire_hard_smp_processor_id(void) return upa_readl(0x1fff40000d0UL); } -/* Each Starfire board has 32 registers which perform translation +/* + * Each Starfire board has 32 registers which perform translation * and delivery of traditional interrupt packets into the extended * Starfire hardware format. Essentially UPAID's now have 2 more * bits than in all previous Sun5 systems. @@ -82,6 +93,9 @@ void *starfire_hookup(int upaid) for(i = 0; i < 32; i++) { p->imap_slots[i] = 0UL; p->tregs[i] = treg_base + (i * 0x10UL); + /* Lets play it safe and not overwrite existing mappings */ + if (upa_readl(p->tregs[i]) != 0) + p->imap_slots[i] = 0xdeadbeaf; } p->upaid = upaid; p->next = sflist; @@ -116,6 +130,12 @@ unsigned int starfire_translate(unsigned long imap, panic("Lucy in the sky...."); } p->imap_slots[i] = imap; + + /* map to real upaid */ + upaid = (((upaid & 0x3c) << 1) | + ((upaid & 0x40) >> 4) | + (upaid & 0x3)); + upa_writel(upaid, p->tregs[i]); return i; diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index e869af4e6..235d34889 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.45 2000/07/30 23:12:24 davem Exp $ +/* $Id: sys_sparc.c,v 1.46 2000/08/29 07:01:54 davem Exp $ * linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that @@ -398,13 +398,18 @@ asmlinkage int sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p, return -EINVAL; if (new_p == (utrap_handler_t)(long)UTH_NOCHANGE) { if (old_p) { - if (!current->thread.utraps) - put_user_ret(NULL, old_p, -EFAULT); - else - put_user_ret((utrap_handler_t)(current->thread.utraps[type]), old_p, -EFAULT); + if (!current->thread.utraps) { + if (put_user(NULL, old_p)) + return -EFAULT; + } else { + if (put_user((utrap_handler_t)(current->thread.utraps[type]), old_p)) + return -EFAULT; + } + } + if (old_d) { + if (put_user(NULL, old_d)) + return -EFAULT; } - if (old_d) - put_user_ret(NULL, old_d, -EFAULT); return 0; } if (!current->thread.utraps) { @@ -431,11 +436,14 @@ asmlinkage int sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p, UT_TRAP_INSTRUCTION_31*sizeof(long)); } } - if (old_p) - put_user_ret((utrap_handler_t)(current->thread.utraps[type]), - old_p, -EFAULT); - if (old_d) - put_user_ret(NULL, old_d, -EFAULT); + if (old_p) { + if (put_user((utrap_handler_t)(current->thread.utraps[type]), old_p)) + return -EFAULT; + } + if (old_d) { + if (put_user(NULL, old_d)) + return -EFAULT; + } current->thread.utraps[type] = (long)new_p; return 0; diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 8683b87d7..071510bbc 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.163 2000/08/22 10:09:10 jj Exp $ +/* $Id: sys_sparc32.c,v 1.164 2000/09/14 10:42:47 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -1621,7 +1621,7 @@ struct ncp_mount_data32 { static void *do_ncp_super_data_conv(void *raw_data) { - struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data; + struct ncp_mount_data news, *n = &news; struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data; n->dir_mode = n32->dir_mode; @@ -1631,6 +1631,7 @@ static void *do_ncp_super_data_conv(void *raw_data) memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int))); n->wdog_pid = n32->wdog_pid; n->mounted_uid = low2highuid(n32->mounted_uid); + memcpy(raw_data, n, sizeof(struct ncp_mount_data)); return raw_data; } @@ -1645,7 +1646,7 @@ struct smb_mount_data32 { static void *do_smb_super_data_conv(void *raw_data) { - struct smb_mount_data *s = (struct smb_mount_data *)raw_data; + struct smb_mount_data news, *s = &news; struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data; s->version = s32->version; @@ -1654,6 +1655,7 @@ static void *do_smb_super_data_conv(void *raw_data) s->gid = low2highgid(s32->gid); s->file_mode = s32->file_mode; s->dir_mode = s32->dir_mode; + memcpy(raw_data, s, sizeof(struct smb_mount_data)); return raw_data; } diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index f229ea988..0264f9418 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.28 2000/07/11 02:21:12 davem Exp $ +/* $Id: time.c,v 1.32 2000/09/22 23:02:13 davem Exp $ * time.c: UltraSparc timer and TOD clock support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -30,6 +30,7 @@ #include <asm/fhc.h> #include <asm/pbm.h> #include <asm/ebus.h> +#include <asm/starfire.h> extern rwlock_t xtime_lock; @@ -177,37 +178,6 @@ void timer_tick_interrupt(struct pt_regs *regs) } #endif -/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. - * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 - * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. - * - * [For the Julian calendar (which was used in Russia before 1917, - * Britain & colonies before 1752, anywhere else before 1582, - * and is still in use by some communities) leave out the - * -year/100+year/400 terms, and add 10.] - * - * This algorithm was first published by Gauss (I think). - * - * WARNING: this function will overflow on 2106-02-07 06:28:16 on - * machines were long is 32-bit! (However, as time_t is signed, we - * will already get problems at other places on 2038-01-19 03:14:08) - */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, - unsigned int day, unsigned int hour, - unsigned int min, unsigned int sec) -{ - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + - year*365 - 719499 - )*24 + hour /* now have hours */ - )*60 + min /* now have minutes */ - )*60 + sec; /* finally seconds */ -} - /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ static void __init kick_start_clock(void) { @@ -336,6 +306,20 @@ void __init clock_probe(void) struct linux_ebus *ebus = NULL; #endif + + if (this_is_starfire) { + /* davem suggests we keep this within the 4M locked kernel image */ + static char obp_gettod[256]; + static u32 unix_tod; + + sprintf(obp_gettod, "h# %08x unix-gettod", + (unsigned int) (long) &unix_tod); + prom_feval(obp_gettod); + xtime.tv_sec = unix_tod; + xtime.tv_usec = 0; + return; + } + __save_and_cli(flags); if(central_bus != NULL) { @@ -504,6 +488,9 @@ static __inline__ unsigned long do_gettimeoffset(void) void do_settimeofday(struct timeval *tv) { + if (this_is_starfire) + return; + write_lock_irq(&xtime_lock); tv->tv_usec -= do_gettimeoffset(); @@ -527,7 +514,10 @@ static int set_rtc_mmss(unsigned long nowtime) unsigned long regs = mstk48t02_regs; u8 tmp; - /* Not having a register set can lead to trouble. */ + /* + * Not having a register set can lead to trouble. + * Also starfire doesnt have a tod clock. + */ if (!regs) return -1; diff --git a/arch/sparc64/lib/rwlock.S b/arch/sparc64/lib/rwlock.S index 03f3bfe59..56edad121 100644 --- a/arch/sparc64/lib/rwlock.S +++ b/arch/sparc64/lib/rwlock.S @@ -1,4 +1,4 @@ -/* $Id: rwlock.S,v 1.3 2000/03/16 16:44:38 davem Exp $ +/* $Id: rwlock.S,v 1.4 2000/09/09 00:00:34 davem Exp $ * rwlocks.S: These things are too big to do inline. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -30,54 +30,38 @@ __read_unlock: /* %o0 = lock_ptr */ cmp %g5, %g7 be,pt %xcc, 99b membar #StoreLoad | #StoreStore - b,a,pt %xcc, __read_unlock + ba,a,pt %xcc, __read_unlock __read_wait_for_writer: ldsw [%o0], %g5 brlz,pt %g5, __read_wait_for_writer membar #LoadLoad - b,a,pt %xcc, 4b -__write_wait_for_writer: - ldsw [%o0], %g5 - brlz,pt %g5, __write_wait_for_writer + ba,a,pt %xcc, 4b +__write_wait_for_any: + lduw [%o0], %g5 + brnz,pt %g5, __write_wait_for_any membar #LoadLoad - b,a,pt %xcc, 4f - - /* Similarly, 2 cache lines for non-contention write locks. */ + ba,a,pt %xcc, 4f .align 64 .globl __write_unlock __write_unlock: /* %o0 = lock_ptr */ - sethi %hi(0x80000000), %g2 -1: lduw [%o0], %g5 - andn %g5, %g2, %g7 - cas [%o0], %g5, %g7 - cmp %g5, %g7 - be,pt %icc, 99b - membar #StoreLoad | #StoreStore - b,a,pt %xcc, 1b + membar #LoadStore | #StoreStore + retl + stw %g0, [%o0] .globl __write_lock __write_lock: /* %o0 = lock_ptr */ sethi %hi(0x80000000), %g2 -1: ldsw [%o0], %g5 -4: brnz,pn %g5, 5f - or %g5, %g2, %g7 + +1: lduw [%o0], %g5 + brnz,pn %g5, __write_wait_for_any +4: or %g5, %g2, %g7 cas [%o0], %g5, %g7 + cmp %g5, %g7 be,pt %icc, 99b membar #StoreLoad | #StoreStore - - b,a,pt %xcc, 1b -5: brlz %g5, __write_wait_for_writer - or %g5, %g2, %g7 - cas [%o0], %g5, %g7 - cmp %g5, %g7 - bne,pn %icc, 5b -8: ldsw [%o0], %g5 - cmp %g5, %g2 - be,pn %icc, 99b - membar #LoadLoad - b,a,pt %xcc, 99b + ba,a,pt %xcc, 1b rwlock_impl_end: diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 9ebe1f494..12006b58a 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.50 2000/08/11 03:00:13 davem Exp $ +/* $Id: fault.c,v 1.51 2000/09/14 06:22:32 anton Exp $ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -145,7 +145,7 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, if (!insn) { if (regs->tstate & TSTATE_PRIV) { - if (regs->tpc & 0x3) + if (!regs->tpc || (regs->tpc & 0x3)) goto cannot_handle; insn = *(unsigned int *)regs->tpc; } else { diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 7eef97836..d694e40f9 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.154 2000/08/09 00:00:15 davem Exp $ +/* $Id: init.c,v 1.156 2000/09/21 06:34:48 anton Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -29,6 +29,7 @@ #include <asm/mmu_context.h> #include <asm/vaddrs.h> #include <asm/dma.h> +#include <asm/starfire.h> extern void device_scan(void); @@ -200,7 +201,7 @@ static void inherit_prom_mappings(void) for (i = 0; i < n; i++) { unsigned long vaddr; - + if (trans[i].virt >= 0xf0000000 && trans[i].virt < 0x100000000) { for (vaddr = trans[i].virt; vaddr < trans[i].virt + trans[i].size; @@ -808,7 +809,6 @@ unsigned long __init bootmem_init(unsigned long *pages_avail) unsigned long bootmap_pfn, bytes_avail, size; int i; - bytes_avail = 0UL; for (i = 0; sp_banks[i].num_bytes != 0; i++) { end_of_phys_memory = sp_banks[i].base_addr + @@ -999,12 +999,7 @@ void __init paging_init(void) */ { extern void setup_tba(int); - int is_starfire = prom_finddevice("/ssp-serial"); - if (is_starfire != 0 && is_starfire != -1) - is_starfire = 1; - else - is_starfire = 0; - setup_tba(is_starfire); + setup_tba(this_is_starfire); } inherit_locked_prom_mappings(1); @@ -1029,7 +1024,7 @@ void __init paging_init(void) zones_size[ZONE_DMA] = npages; zholes_size[ZONE_DMA] = npages - pages_avail; - free_area_init_node(0, NULL, zones_size, + free_area_init_node(0, NULL, NULL, zones_size, phys_base, zholes_size); } diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c index 3cf5b6883..e80d6b13f 100644 --- a/arch/sparc64/solaris/fs.c +++ b/arch/sparc64/solaris/fs.c @@ -1,4 +1,4 @@ -/* $Id: fs.c,v 1.22 2000/07/28 12:15:02 davem Exp $ +/* $Id: fs.c,v 1.23 2000/08/29 07:01:54 davem Exp $ * fs.c: fs related syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -612,20 +612,25 @@ asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg) case SOL_F_SETLKW: cmd = F_SETLKW; break; } - get_user_ret (f.l_type, &((struct sol_flock *)A(arg))->l_type, -EFAULT); - __get_user_ret (f.l_whence, &((struct sol_flock *)A(arg))->l_whence, -EFAULT); - __get_user_ret (f.l_start, &((struct sol_flock *)A(arg))->l_start, -EFAULT); - __get_user_ret (f.l_len, &((struct sol_flock *)A(arg))->l_len, -EFAULT); - __get_user_ret (f.l_pid, &((struct sol_flock *)A(arg))->l_sysid, -EFAULT); + if (get_user (f.l_type, &((struct sol_flock *)A(arg))->l_type) || + __get_user (f.l_whence, &((struct sol_flock *)A(arg))->l_whence) || + __get_user (f.l_start, &((struct sol_flock *)A(arg))->l_start) || + __get_user (f.l_len, &((struct sol_flock *)A(arg))->l_len) || + __get_user (f.l_pid, &((struct sol_flock *)A(arg))->l_sysid)) + return -EFAULT; + set_fs(KERNEL_DS); ret = sys_fcntl(fd, cmd, (unsigned long)&f); set_fs(old_fs); - __put_user_ret (f.l_type, &((struct sol_flock *)A(arg))->l_type, -EFAULT); - __put_user_ret (f.l_whence, &((struct sol_flock *)A(arg))->l_whence, -EFAULT); - __put_user_ret (f.l_start, &((struct sol_flock *)A(arg))->l_start, -EFAULT); - __put_user_ret (f.l_len, &((struct sol_flock *)A(arg))->l_len, -EFAULT); - __put_user_ret (f.l_pid, &((struct sol_flock *)A(arg))->l_pid, -EFAULT); - __put_user_ret (0, &((struct sol_flock *)A(arg))->l_sysid, -EFAULT); + + if (__put_user (f.l_type, &((struct sol_flock *)A(arg))->l_type) || + __put_user (f.l_whence, &((struct sol_flock *)A(arg))->l_whence) || + __put_user (f.l_start, &((struct sol_flock *)A(arg))->l_start) || + __put_user (f.l_len, &((struct sol_flock *)A(arg))->l_len) || + __put_user (f.l_pid, &((struct sol_flock *)A(arg))->l_pid) || + __put_user (0, &((struct sol_flock *)A(arg))->l_sysid)) + return -EFAULT; + return ret; } case SOL_F_FREESP: @@ -634,7 +639,9 @@ asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg) int (*sys_newftruncate)(unsigned int, unsigned long)= (int (*)(unsigned int, unsigned long))SYS(ftruncate); - get_user_ret(length, &((struct sol_flock*)A(arg))->l_start, -EFAULT); + if (get_user(length, &((struct sol_flock*)A(arg))->l_start)) + return -EFAULT; + return sys_newftruncate(fd, length); } }; diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index a7edd1876..ca8bf25f3 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.29 2000/08/14 23:50:31 anton Exp $ +/* $Id: misc.c,v 1.30 2000/08/29 07:01:54 davem Exp $ * misc.c: Miscelaneous syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -139,12 +139,14 @@ asmlinkage int solaris_brk(u32 brk) int i, len = (countfrom) ? \ ((sizeof(to) > sizeof(from) ? \ sizeof(from) : sizeof(to))) : sizeof(to); \ - copy_to_user_ret(to, from, len, -EFAULT); \ + if (copy_to_user(to, from, len)) \ + return -EFAULT; \ if (dotchop) \ for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \ else \ i = len - 1; \ - __put_user_ret('\0', (char *)(to+i), -EFAULT); \ + if (__put_user('\0', (char *)(to+i))) \ + return -EFAULT; \ } struct sol_uname { @@ -297,10 +299,13 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count) } len = strlen(r) + 1; if (count < len) { - copy_to_user_ret((char *)A(buf), r, count - 1, -EFAULT); - __put_user_ret(0, (char *)A(buf) + count - 1, -EFAULT); - } else - copy_to_user_ret((char *)A(buf), r, len, -EFAULT); + if (copy_to_user((char *)A(buf), r, count - 1) || + __put_user(0, (char *)A(buf) + count - 1)) + return -EFAULT; + } else { + if (copy_to_user((char *)A(buf), r, len)) + return -EFAULT; + } return len; } diff --git a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c index 7105bc05c..8a6ecd916 100644 --- a/arch/sparc64/solaris/signal.c +++ b/arch/sparc64/solaris/signal.c @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.5 1997/12/15 15:04:59 jj Exp $ +/* $Id: signal.c,v 1.7 2000/09/05 21:44:54 davem Exp $ * signal.c: Signal emulation for Solaris * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -311,7 +311,7 @@ asmlinkage int solaris_sigpending(int which, u32 set) switch (which) { case 1: /* sigpending */ spin_lock_irq(¤t->sigmask_lock); - sigandsets(&s, ¤t->blocked, ¤t->signal); + sigandsets(&s, ¤t->blocked, ¤t->pending.signal); recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); break; @@ -368,9 +368,13 @@ asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options) if (info) { struct sol_siginfo *s = (struct sol_siginfo *)A(info); - if (get_user (status, (unsigned int *)A(info))) return -EFAULT; - __put_user_ret (SOLARIS_SIGCLD, &s->si_signo, -EFAULT); - __put_user_ret (ret, &s->_data._proc._pid, -EFAULT); + if (get_user (status, (unsigned int *)A(info))) + return -EFAULT; + + if (__put_user (SOLARIS_SIGCLD, &s->si_signo) || + __put_user (ret, &s->_data._proc._pid)) + return -EFAULT; + switch (status & 0xff) { case 0: ret = SOLARIS_CLD_EXITED; status = (status >> 8) & 0xff; @@ -390,8 +394,10 @@ asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options) status = linux_to_solaris_signals[status & 0x7f]; break; } - __put_user_ret (ret, &s->si_code, -EFAULT); - __put_user_ret (status, &s->_data._proc._pdata._cld._status, -EFAULT); + + if (__put_user (ret, &s->si_code) || + __put_user (status, &s->_data._proc._pdata._cld._status)) + return -EFAULT; } return 0; } |