summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-04-05 04:55:58 +0000
commit74a9f2e1b4d3ab45a9f72cb5b556c9f521524ab3 (patch)
tree7c4cdb103ab1b388c9852a88bd6fb1e73eba0b5c /arch
parentee6374c8b0d333c08061c6a97bc77090d7461225 (diff)
Merge with Linux 2.4.3.
Note that mingetty does no longer work with serial console, you have to switch to another getty like getty_ps. This commit also includes a fix for a setitimer bug which did prevent getty_ps from working on older kernels.
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/defconfig6
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c1
-rw-r--r--arch/alpha/kernel/console.c8
-rw-r--r--arch/alpha/kernel/core_apecs.c6
-rw-r--r--arch/alpha/kernel/core_cia.c12
-rw-r--r--arch/alpha/kernel/core_irongate.c4
-rw-r--r--arch/alpha/kernel/core_lca.c6
-rw-r--r--arch/alpha/kernel/core_mcpcia.c28
-rw-r--r--arch/alpha/kernel/core_polaris.c4
-rw-r--r--arch/alpha/kernel/core_t2.c4
-rw-r--r--arch/alpha/kernel/core_titan.c10
-rw-r--r--arch/alpha/kernel/core_tsunami.c8
-rw-r--r--arch/alpha/kernel/core_wildfire.c8
-rw-r--r--arch/alpha/kernel/osf_sys.c4
-rw-r--r--arch/alpha/kernel/pci-noop.c14
-rw-r--r--arch/alpha/kernel/pci.c30
-rw-r--r--arch/alpha/kernel/pci_impl.h13
-rw-r--r--arch/alpha/kernel/pci_iommu.c12
-rw-r--r--arch/alpha/kernel/proto.h16
-rw-r--r--arch/alpha/kernel/setup.c2
-rw-r--r--arch/alpha/kernel/sys_dp264.c8
-rw-r--r--arch/alpha/kernel/sys_eiger.c2
-rw-r--r--arch/alpha/kernel/sys_jensen.c4
-rw-r--r--arch/alpha/kernel/sys_nautilus.c2
-rw-r--r--arch/alpha/kernel/sys_rawhide.c4
-rw-r--r--arch/alpha/kernel/sys_titan.c6
-rw-r--r--arch/alpha/kernel/sys_wildfire.c2
-rw-r--r--arch/alpha/mm/fault.c6
-rw-r--r--arch/arm/kernel/entry-armo.S5
-rw-r--r--arch/arm/kernel/entry-armv.S10
-rw-r--r--arch/arm/kernel/entry-common.S2
-rw-r--r--arch/arm/kernel/sys_arm.c4
-rw-r--r--arch/arm/lib/Makefile6
-rw-r--r--arch/arm/lib/copy_page.S2
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S2
-rw-r--r--arch/arm/lib/extractconstants.pl46
-rw-r--r--arch/arm/lib/getconsdata.c95
-rw-r--r--arch/arm/lib/memcpy.S1
-rw-r--r--arch/arm/mach-integrator/Makefile24
-rw-r--r--arch/arm/mach-integrator/arch.c70
-rw-r--r--arch/arm/mach-integrator/dma.c36
-rw-r--r--arch/arm/mach-integrator/irq.c71
-rw-r--r--arch/arm/mach-integrator/leds.c94
-rw-r--r--arch/arm/mach-integrator/mm.c78
-rw-r--r--arch/arm/mach-integrator/pci.c119
-rw-r--r--arch/arm/mach-integrator/pci_v3.c460
-rw-r--r--arch/arm/mach-integrator/time.c45
-rw-r--r--arch/arm/mach-sa1100/arch.c2
-rw-r--r--arch/arm/mm/fault-common.c4
-rw-r--r--arch/arm/mm/mm-rpc.c1
-rw-r--r--arch/arm/mm/mm-sa1100.c2
-rw-r--r--arch/arm/mm/proc-arm2,3.S2
-rw-r--r--arch/arm/mm/proc-arm6,7.S18
-rw-r--r--arch/arm/mm/proc-arm720.S2
-rw-r--r--arch/arm/mm/proc-arm920.S2
-rw-r--r--arch/arm/mm/proc-sa110.S2
-rw-r--r--arch/arm/nwfpe/entry26.S2
-rw-r--r--arch/arm/tools/Makefile36
-rw-r--r--arch/arm/tools/constants-hdr5
-rw-r--r--arch/arm/tools/getconstants.c72
-rw-r--r--arch/arm/tools/mach-types16
-rw-r--r--arch/arm/vmlinux-armv.lds.in18
-rw-r--r--arch/cris/drivers/serial.c4
-rw-r--r--arch/cris/kernel/entry.S2
-rw-r--r--arch/cris/kernel/sys_cris.c8
-rw-r--r--arch/cris/mm/fault.c14
-rw-r--r--arch/i386/boot/Makefile8
-rw-r--r--arch/i386/defconfig7
-rw-r--r--arch/i386/kernel/head.S17
-rw-r--r--arch/i386/kernel/i386_ksyms.c4
-rw-r--r--arch/i386/kernel/i387.c2
-rw-r--r--arch/i386/kernel/ldt.c4
-rw-r--r--arch/i386/kernel/pci-pc.c90
-rw-r--r--arch/i386/kernel/ptrace.c6
-rw-r--r--arch/i386/kernel/setup.c55
-rw-r--r--arch/i386/kernel/sys_i386.c4
-rw-r--r--arch/i386/kernel/traps.c2
-rw-r--r--arch/i386/lib/mmx.c11
-rw-r--r--arch/i386/mm/extable.c2
-rw-r--r--arch/i386/mm/fault.c10
-rw-r--r--arch/i386/mm/init.c139
-rw-r--r--arch/i386/mm/ioremap.c15
-rw-r--r--arch/ia64/ia32/binfmt_elf32.c5
-rw-r--r--arch/ia64/ia32/sys_ia32.c16
-rw-r--r--arch/ia64/kernel/sys_ia64.c8
-rw-r--r--arch/ia64/lib/copy_user.S2
-rw-r--r--arch/ia64/lib/strlen.S2
-rw-r--r--arch/ia64/lib/strlen_user.S2
-rw-r--r--arch/ia64/mm/fault.c8
-rw-r--r--arch/ia64/sn/io/l1.c2
-rw-r--r--arch/ia64/sn/io/pcibr.c6
-rw-r--r--arch/m68k/apollo/dn_ints.c2
-rw-r--r--arch/m68k/ifpsp060/src/fpsp.S4
-rw-r--r--arch/m68k/ifpsp060/src/ilsp.S4
-rw-r--r--arch/m68k/ifpsp060/src/isp.S2
-rw-r--r--arch/m68k/ifpsp060/src/pfpsp.S4
-rw-r--r--arch/m68k/kernel/bios32.c2
-rw-r--r--arch/m68k/kernel/head.S2
-rw-r--r--arch/m68k/kernel/ints.c2
-rw-r--r--arch/m68k/kernel/sys_m68k.c8
-rw-r--r--arch/m68k/mm/fault.c6
-rw-r--r--arch/m68k/q40/README2
-rw-r--r--arch/m68k/q40/config.c2
-rw-r--r--arch/mips/defconfig1
-rw-r--r--arch/mips/defconfig-atlas1
-rw-r--r--arch/mips/defconfig-ddb54764
-rw-r--r--arch/mips/defconfig-decstation1
-rw-r--r--arch/mips/defconfig-ev641204
-rw-r--r--arch/mips/defconfig-ev961004
-rw-r--r--arch/mips/defconfig-ip221
-rw-r--r--arch/mips/defconfig-it81724
-rw-r--r--arch/mips/defconfig-malta5
-rw-r--r--arch/mips/defconfig-ocelot4
-rw-r--r--arch/mips/kernel/irixelf.c20
-rw-r--r--arch/mips/kernel/syscall.c4
-rw-r--r--arch/mips/kernel/sysirix.c16
-rw-r--r--arch/mips/mm/extable.c2
-rw-r--r--arch/mips/mm/fault.c10
-rw-r--r--arch/mips/mm/init.c110
-rw-r--r--arch/mips/mm/umap.c8
-rw-r--r--arch/mips/sgi/kernel/setup.c16
-rw-r--r--arch/mips64/defconfig1
-rw-r--r--arch/mips64/defconfig-ip221
-rw-r--r--arch/mips64/defconfig-ip271
-rw-r--r--arch/mips64/kernel/head.S2
-rw-r--r--arch/mips64/kernel/linux32.c14
-rw-r--r--arch/mips64/kernel/syscall.c4
-rw-r--r--arch/mips64/mm/fault.c10
-rw-r--r--arch/mips64/mm/init.c118
-rw-r--r--arch/mips64/mm/umap.c4
-rw-r--r--arch/mips64/sgi-ip27/ip27-memory.c2
-rw-r--r--arch/parisc/kernel/sys_parisc.c4
-rw-r--r--arch/parisc/mm/fault.c8
-rw-r--r--arch/ppc/8xx_io/Config.in19
-rw-r--r--arch/ppc/8xx_io/commproc.c39
-rw-r--r--arch/ppc/8xx_io/commproc.h156
-rw-r--r--arch/ppc/8xx_io/enet.c71
-rw-r--r--arch/ppc/8xx_io/fec.c401
-rw-r--r--arch/ppc/8xx_io/uart.c52
-rw-r--r--arch/ppc/config.in28
-rw-r--r--arch/ppc/configs/IVMS8_defconfig452
-rw-r--r--arch/ppc/configs/SM850_defconfig420
-rw-r--r--arch/ppc/configs/SPD823TS_defconfig416
-rw-r--r--arch/ppc/configs/TQM823L_defconfig419
-rw-r--r--arch/ppc/configs/TQM850L_defconfig419
-rw-r--r--arch/ppc/configs/TQM860L_defconfig419
-rw-r--r--arch/ppc/configs/common_defconfig10
-rw-r--r--arch/ppc/defconfig7
-rw-r--r--arch/ppc/kernel/Makefile1
-rw-r--r--arch/ppc/kernel/chrp_pci.c36
-rw-r--r--arch/ppc/kernel/chrp_setup.c4
-rw-r--r--arch/ppc/kernel/head.S2
-rw-r--r--arch/ppc/kernel/head_8xx.S20
-rw-r--r--arch/ppc/kernel/irq.c15
-rw-r--r--arch/ppc/kernel/m8260_setup.c4
-rw-r--r--arch/ppc/kernel/m8xx_setup.c300
-rw-r--r--arch/ppc/kernel/open_pic.c121
-rw-r--r--arch/ppc/kernel/open_pic_defs.h36
-rw-r--r--arch/ppc/kernel/pci.c118
-rw-r--r--arch/ppc/kernel/pmac_pci.c27
-rw-r--r--arch/ppc/kernel/pmac_setup.c10
-rw-r--r--arch/ppc/kernel/ppc8xx_pic.c16
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c20
-rw-r--r--arch/ppc/kernel/prep_pci.c274
-rw-r--r--arch/ppc/kernel/prep_setup.c3
-rw-r--r--arch/ppc/kernel/prom.c7
-rw-r--r--arch/ppc/kernel/setup.c4
-rw-r--r--arch/ppc/kernel/smp.c61
-rw-r--r--arch/ppc/kernel/softemu8xx.c10
-rw-r--r--arch/ppc/kernel/syscalls.c4
-rw-r--r--arch/ppc/kernel/time.c6
-rw-r--r--arch/ppc/kernel/traps.c4
-rw-r--r--arch/ppc/mm/fault.c12
-rw-r--r--arch/ppc/mm/init.c83
-rw-r--r--arch/ppc/treeboot/mkevimg2
-rw-r--r--arch/s390/kernel/entry.S2
-rw-r--r--arch/s390/kernel/sys_s390.c4
-rw-r--r--arch/s390/mm/fault.c10
-rw-r--r--arch/s390/tools/dasdfmt/dasdfmt.c2
-rw-r--r--arch/s390x/kernel/binfmt_elf32.c4
-rw-r--r--arch/s390x/kernel/entry.S2
-rw-r--r--arch/s390x/kernel/exec32.c5
-rw-r--r--arch/s390x/kernel/linux32.c4
-rw-r--r--arch/s390x/kernel/sys_s390.c4
-rw-r--r--arch/s390x/mm/fault.c10
-rw-r--r--arch/s390x/tools/dasdfmt/dasdfmt.c2
-rw-r--r--arch/sh/kernel/sh_ksyms.c1
-rw-r--r--arch/sh/kernel/sys_sh.c4
-rw-r--r--arch/sh/mm/fault.c10
-rw-r--r--arch/sparc/defconfig5
-rw-r--r--arch/sparc/kernel/ptrace.c73
-rw-r--r--arch/sparc/kernel/sys_sparc.c10
-rw-r--r--arch/sparc/kernel/sys_sunos.c10
-rw-r--r--arch/sparc/mm/fault.c20
-rw-r--r--arch/sparc/mm/init.c230
-rw-r--r--arch/sparc/mm/srmmu.c40
-rw-r--r--arch/sparc/mm/sun4c.c32
-rw-r--r--arch/sparc64/config.in27
-rw-r--r--arch/sparc64/defconfig124
-rw-r--r--arch/sparc64/kernel/Makefile4
-rw-r--r--arch/sparc64/kernel/auxio.c3
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c15
-rw-r--r--arch/sparc64/kernel/cpu.c6
-rw-r--r--arch/sparc64/kernel/devices.c11
-rw-r--r--arch/sparc64/kernel/dtlb_base.S6
-rw-r--r--arch/sparc64/kernel/ebus.c52
-rw-r--r--arch/sparc64/kernel/entry.S196
-rw-r--r--arch/sparc64/kernel/etrap.S4
-rw-r--r--arch/sparc64/kernel/head.S298
-rw-r--r--arch/sparc64/kernel/ioctl32.c117
-rw-r--r--arch/sparc64/kernel/irq.c79
-rw-r--r--arch/sparc64/kernel/pci.c9
-rw-r--r--arch/sparc64/kernel/pci_common.c40
-rw-r--r--arch/sparc64/kernel/pci_iommu.c6
-rw-r--r--arch/sparc64/kernel/pci_psycho.c22
-rw-r--r--arch/sparc64/kernel/pci_sabre.c20
-rw-r--r--arch/sparc64/kernel/pci_schizo.c1664
-rw-r--r--arch/sparc64/kernel/process.c12
-rw-r--r--arch/sparc64/kernel/ptrace.c186
-rw-r--r--arch/sparc64/kernel/rtrap.S4
-rw-r--r--arch/sparc64/kernel/setup.c24
-rw-r--r--arch/sparc64/kernel/signal.c43
-rw-r--r--arch/sparc64/kernel/signal32.c67
-rw-r--r--arch/sparc64/kernel/smp.c278
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c7
-rw-r--r--arch/sparc64/kernel/sys_sparc.c26
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c6
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c14
-rw-r--r--arch/sparc64/kernel/time.c286
-rw-r--r--arch/sparc64/kernel/trampoline.S349
-rw-r--r--arch/sparc64/kernel/traps.c99
-rw-r--r--arch/sparc64/kernel/ttable.S4
-rw-r--r--arch/sparc64/kernel/unaligned.c6
-rw-r--r--arch/sparc64/lib/U3copy_in_user.S18
-rw-r--r--arch/sparc64/lib/VISbzero.S6
-rw-r--r--arch/sparc64/lib/VISsave.S10
-rw-r--r--arch/sparc64/lib/blockops.S146
-rw-r--r--arch/sparc64/mm/fault.c26
-rw-r--r--arch/sparc64/mm/generic.c17
-rw-r--r--arch/sparc64/mm/init.c718
-rw-r--r--arch/sparc64/mm/ultra.S199
-rw-r--r--arch/sparc64/solaris/misc.c6
242 files changed, 9966 insertions, 2769 deletions
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig
index 702778091..feb49e997 100644
--- a/arch/alpha/defconfig
+++ b/arch/alpha/defconfig
@@ -285,10 +285,8 @@ CONFIG_SR_EXTRA_DEVS=2
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
CONFIG_SCSI_AIC7XXX=y
-CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT=y
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
-CONFIG_AIC7XXX_PROC_STATS=y
-CONFIG_AIC7XXX_RESET_DELAY=5
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
+CONFIG_AIC7XXX_RESET_DELAY=5000
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index d7bf13ec3..997cc772d 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -235,3 +235,4 @@ EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL(get_wchan);
+EXPORT_SYMBOL(flush_tlb_page);
diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c
index b946ce0ed..254ab65d3 100644
--- a/arch/alpha/kernel/console.c
+++ b/arch/alpha/kernel/console.c
@@ -21,8 +21,8 @@
unsigned long __vga_hose_io_base = 0; /* base for default hose */
unsigned long __vga_hose_mem_base = 0; /* base for default hose */
-static struct pci_controler * __init
-default_vga_hose_select(struct pci_controler *h1, struct pci_controler *h2)
+static struct pci_controller * __init
+default_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2)
{
if (h2->index < h1->index)
return h2;
@@ -31,7 +31,7 @@ default_vga_hose_select(struct pci_controler *h1, struct pci_controler *h2)
}
void __init
-set_vga_hose(struct pci_controler *hose)
+set_vga_hose(struct pci_controller *hose)
{
if (hose) {
__vga_hose_io_base = hose->io_space->start;
@@ -42,7 +42,7 @@ set_vga_hose(struct pci_controler *hose)
void __init
locate_and_init_vga(void *(*sel_func)(void *, void *))
{
- struct pci_controler *hose = NULL;
+ struct pci_controller *hose = NULL;
struct pci_dev *dev = NULL;
if (!sel_func) sel_func = (void *)default_vga_hose_select;
diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c
index 41143ff99..a44d941c0 100644
--- a/arch/alpha/kernel/core_apecs.c
+++ b/arch/alpha/kernel/core_apecs.c
@@ -357,7 +357,7 @@ struct pci_ops apecs_pci_ops =
};
void
-apecs_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
+apecs_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
{
wmb();
*(vip)APECS_IOC_TBIA = 0;
@@ -367,13 +367,13 @@ apecs_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
void __init
apecs_init_arch(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
/*
* Create our single hose.
*/
- pci_isa_hose = hose = alloc_pci_controler();
+ pci_isa_hose = hose = alloc_pci_controller();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->index = 0;
diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
index 6203b0247..e2d957c98 100644
--- a/arch/alpha/kernel/core_cia.c
+++ b/arch/alpha/kernel/core_cia.c
@@ -299,7 +299,7 @@ struct pci_ops cia_pci_ops =
*/
void
-cia_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
+cia_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
{
wmb();
*(vip)CIA_IOC_PCI_TBIA = 3; /* Flush all locked and unlocked. */
@@ -314,7 +314,7 @@ cia_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
*/
static void
-cia_pci_tbi_try1(struct pci_controler *hose,
+cia_pci_tbi_try1(struct pci_controller *hose,
dma_addr_t start, dma_addr_t end)
{
wmb();
@@ -359,7 +359,7 @@ cia_enable_broken_tbi_try2(void)
}
static void
-cia_pci_tbi_try2(struct pci_controler *hose,
+cia_pci_tbi_try2(struct pci_controller *hose,
dma_addr_t start, dma_addr_t end)
{
unsigned long flags;
@@ -595,7 +595,7 @@ failed:
static void __init
do_init_arch(int is_pyxis)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
int temp;
int cia_rev;
@@ -628,7 +628,7 @@ do_init_arch(int is_pyxis)
*(vip)CIA_IOC_HAE_IO = 0;
/* For PYXIS, we always use BWX bus and i/o accesses. To that end,
- make sure they're enabled on the controler. */
+ make sure they're enabled on the controller. */
if (is_pyxis) {
temp = *(vip)CIA_IOC_CIA_CNFG;
temp |= CIA_CNFG_IOA_BWEN;
@@ -643,7 +643,7 @@ do_init_arch(int is_pyxis)
* Create our single hose.
*/
- pci_isa_hose = hose = alloc_pci_controler();
+ pci_isa_hose = hose = alloc_pci_controller();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->index = 0;
diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c
index 030348747..709e8bab2 100644
--- a/arch/alpha/kernel/core_irongate.c
+++ b/arch/alpha/kernel/core_irongate.c
@@ -367,7 +367,7 @@ again:
void __init
irongate_init_arch(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100;
irongate_pci_clr_err();
@@ -377,7 +377,7 @@ irongate_init_arch(void)
* Create our single hose.
*/
- pci_isa_hose = hose = alloc_pci_controler();
+ pci_isa_hose = hose = alloc_pci_controller();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->index = 0;
diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c
index 5329acfac..28d743dd5 100644
--- a/arch/alpha/kernel/core_lca.c
+++ b/arch/alpha/kernel/core_lca.c
@@ -279,7 +279,7 @@ struct pci_ops lca_pci_ops =
};
void
-lca_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
+lca_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
{
wmb();
*(vip)LCA_IOC_TBIA = 0;
@@ -289,13 +289,13 @@ lca_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
void __init
lca_init_arch(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
/*
* Create our single hose.
*/
- pci_isa_hose = hose = alloc_pci_controler();
+ pci_isa_hose = hose = alloc_pci_controller();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->index = 0;
diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
index f114ab24f..94eec6988 100644
--- a/arch/alpha/kernel/core_mcpcia.c
+++ b/arch/alpha/kernel/core_mcpcia.c
@@ -89,7 +89,7 @@
static unsigned int
conf_read(unsigned long addr, unsigned char type1,
- struct pci_controler *hose)
+ struct pci_controller *hose)
{
unsigned long flags;
unsigned long mid = MCPCIA_HOSE2MID(hose->index);
@@ -137,7 +137,7 @@ conf_read(unsigned long addr, unsigned char type1,
static void
conf_write(unsigned long addr, unsigned int value, unsigned char type1,
- struct pci_controler *hose)
+ struct pci_controller *hose)
{
unsigned long flags;
unsigned long mid = MCPCIA_HOSE2MID(hose->index);
@@ -171,7 +171,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1,
}
static int
-mk_conf_addr(struct pci_dev *dev, int where, struct pci_controler *hose,
+mk_conf_addr(struct pci_dev *dev, int where, struct pci_controller *hose,
unsigned long *pci_addr, unsigned char *type1)
{
u8 bus = dev->bus->number;
@@ -199,7 +199,7 @@ mk_conf_addr(struct pci_dev *dev, int where, struct pci_controler *hose,
static int
mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
unsigned long addr, w;
unsigned char type1;
@@ -215,7 +215,7 @@ mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
static int
mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
unsigned long addr, w;
unsigned char type1;
@@ -231,7 +231,7 @@ mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
static int
mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
unsigned long addr;
unsigned char type1;
@@ -246,7 +246,7 @@ mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
static int
mcpcia_write_config(struct pci_dev *dev, int where, u32 value, long mask)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
unsigned long addr;
unsigned char type1;
@@ -288,7 +288,7 @@ struct pci_ops mcpcia_pci_ops =
};
void
-mcpcia_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
+mcpcia_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
{
wmb();
*(vuip)MCPCIA_SG_TBIA(MCPCIA_HOSE2MID(hose->index)) = 0;
@@ -333,11 +333,11 @@ mcpcia_probe_hose(int h)
static void __init
mcpcia_new_hose(int h)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
struct resource *io, *mem, *hae_mem;
int mid = MCPCIA_HOSE2MID(h);
- hose = alloc_pci_controler();
+ hose = alloc_pci_controller();
if (h == 0)
pci_isa_hose = hose;
io = alloc_resource();
@@ -386,7 +386,7 @@ mcpcia_pci_clr_err(int mid)
}
static void __init
-mcpcia_startup_hose(struct pci_controler *hose)
+mcpcia_startup_hose(struct pci_controller *hose)
{
int mid = MCPCIA_HOSE2MID(hose->index);
unsigned int tmp;
@@ -464,7 +464,7 @@ mcpcia_init_arch(void)
void __init
mcpcia_init_hoses(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
int hose_count;
int h;
@@ -561,7 +561,7 @@ static void
mcpcia_print_system_area(unsigned long la_ptr)
{
struct el_common *frame;
- struct pci_controler *hose;
+ struct pci_controller *hose;
struct IOD_subpacket {
unsigned long base;
@@ -638,7 +638,7 @@ mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
{
/* FIXME: how do we figure out which hose the
error was on? */
- struct pci_controler *hose;
+ struct pci_controller *hose;
for (hose = hose_head; hose; hose = hose->next)
mcpcia_pci_clr_err(MCPCIA_HOSE2MID(hose->index));
break;
diff --git a/arch/alpha/kernel/core_polaris.c b/arch/alpha/kernel/core_polaris.c
index 56601c4c5..2eb147c54 100644
--- a/arch/alpha/kernel/core_polaris.c
+++ b/arch/alpha/kernel/core_polaris.c
@@ -178,7 +178,7 @@ struct pci_ops polaris_pci_ops =
void __init
polaris_init_arch(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
/* May need to initialize error reporting (see PCICTL0/1), but
* for now assume that the firmware has done the right thing
@@ -192,7 +192,7 @@ polaris_init_arch(void)
* Create our single hose.
*/
- pci_isa_hose = hose = alloc_pci_controler();
+ pci_isa_hose = hose = alloc_pci_controller();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->index = 0;
diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c
index 26aac4a38..1fd7d1266 100644
--- a/arch/alpha/kernel/core_t2.c
+++ b/arch/alpha/kernel/core_t2.c
@@ -324,7 +324,7 @@ struct pci_ops t2_pci_ops =
void __init
t2_init_arch(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
unsigned int i;
for (i = 0; i < NR_CPUS; i++) {
@@ -384,7 +384,7 @@ t2_init_arch(void)
* Create our single hose.
*/
- pci_isa_hose = hose = alloc_pci_controler();
+ pci_isa_hose = hose = alloc_pci_controller();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->index = 0;
diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
index 5e53d091c..350b106b3 100644
--- a/arch/alpha/kernel/core_titan.c
+++ b/arch/alpha/kernel/core_titan.c
@@ -83,7 +83,7 @@ static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
unsigned long addr;
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
@@ -200,7 +200,7 @@ struct pci_ops titan_pci_ops =
void
-titan_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
+titan_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
{
titan_pachip *pachip =
(hose->index & 1) ? TITAN_pachip1 : TITAN_pachip0;
@@ -243,7 +243,7 @@ titan_query_agp(titan_pachip_port *port)
}
static void __init
-titan_init_agp(titan_pachip_port *port, struct pci_controler *hose)
+titan_init_agp(titan_pachip_port *port, struct pci_controller *hose)
{
union TPAchipPCTL pctl;
@@ -276,9 +276,9 @@ titan_init_agp(titan_pachip_port *port, struct pci_controler *hose)
static void __init
titan_init_one_pachip_port(titan_pachip_port *port, int index)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
- hose = alloc_pci_controler();
+ hose = alloc_pci_controller();
if (index == 0)
pci_isa_hose = hose;
hose->io_space = alloc_resource();
diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c
index 45ff9bb12..282eb0347 100644
--- a/arch/alpha/kernel/core_tsunami.c
+++ b/arch/alpha/kernel/core_tsunami.c
@@ -90,7 +90,7 @@ static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
unsigned long addr;
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
@@ -206,7 +206,7 @@ struct pci_ops tsunami_pci_ops =
};
void
-tsunami_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
+tsunami_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
{
tsunami_pchip *pchip = hose->index ? TSUNAMI_pchip1 : TSUNAMI_pchip0;
volatile unsigned long *csr;
@@ -280,12 +280,12 @@ tsunami_probe_write(volatile unsigned long *vaddr)
static void __init
tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
if (tsunami_probe_read(&pchip->pctl.csr) == 0)
return;
- hose = alloc_pci_controler();
+ hose = alloc_pci_controller();
if (index == 0)
pci_isa_hose = hose;
hose->io_space = alloc_resource();
diff --git a/arch/alpha/kernel/core_wildfire.c b/arch/alpha/kernel/core_wildfire.c
index 9b4f28c10..cf27355f9 100644
--- a/arch/alpha/kernel/core_wildfire.c
+++ b/arch/alpha/kernel/core_wildfire.c
@@ -64,10 +64,10 @@ unsigned long wildfire_mem_mask;
void __init
wildfire_init_hose(int qbbno, int hoseno)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
wildfire_pci *pci;
- hose = alloc_pci_controler();
+ hose = alloc_pci_controller();
hose->io_space = alloc_resource();
hose->mem_space = alloc_resource();
@@ -346,7 +346,7 @@ wildfire_kill_arch(int mode)
}
void
-wildfire_pci_tbi(struct pci_controler *hose, dma_addr_t start, dma_addr_t end)
+wildfire_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
{
int qbbno = hose->index >> 3;
int hoseno = hose->index & 7;
@@ -360,7 +360,7 @@ static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
unsigned long addr;
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 6159457d9..109de59a2 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -242,9 +242,9 @@ asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
goto out;
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
ret = do_mmap(file, addr, len, prot, flags, off);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
out:
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index d530ebb82..7beed3ab1 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -14,17 +14,17 @@
/*
- * The PCI controler list.
+ * The PCI controller list.
*/
-struct pci_controler *hose_head, **hose_tail = &hose_head;
-struct pci_controler *pci_isa_hose;
+struct pci_controller *hose_head, **hose_tail = &hose_head;
+struct pci_controller *pci_isa_hose;
-struct pci_controler * __init
-alloc_pci_controler(void)
+struct pci_controller * __init
+alloc_pci_controller(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
hose = alloc_bootmem(sizeof(*hose));
@@ -47,7 +47,7 @@ alloc_resource(void)
asmlinkage long
sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
struct pci_dev *dev;
/* from hose or from bus.devfn */
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index ddf3d9755..e473d21a2 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -43,11 +43,11 @@ const char pci_hae0_name[] = "HAE0";
/*
- * The PCI controler list.
+ * The PCI controller list.
*/
-struct pci_controler *hose_head, **hose_tail = &hose_head;
-struct pci_controler *pci_isa_hose;
+struct pci_controller *hose_head, **hose_tail = &hose_head;
+struct pci_controller *pci_isa_hose;
/*
* Quirks.
@@ -136,7 +136,7 @@ void
pcibios_align_resource(void *data, struct resource *res, unsigned long size)
{
struct pci_dev *dev = data;
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
unsigned long alignto;
unsigned long start = res->start;
@@ -224,7 +224,7 @@ void __init
pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
{
/* Update device resources. */
- struct pci_controler *hose = (struct pci_controler *)bus->sysdata;
+ struct pci_controller *hose = (struct pci_controller *)bus->sysdata;
int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -244,7 +244,7 @@ pcibios_fixup_bus(struct pci_bus *bus)
{
/* Propogate hose info into the subordinate devices. */
- struct pci_controler *hose = bus->sysdata;
+ struct pci_controller *hose = bus->sysdata;
struct list_head *ln;
struct pci_dev *dev = bus->self;
@@ -284,7 +284,7 @@ void
pcibios_update_resource(struct pci_dev *dev, struct resource *root,
struct resource *res, int resource)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
int where;
u32 reg;
@@ -328,7 +328,7 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
u8 __init
common_swizzle(struct pci_dev *dev, u8 *pinp)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
if (dev->bus->number != hose->first_busno) {
u8 pin = *pinp;
@@ -349,7 +349,7 @@ void __init
pcibios_fixup_pbus_ranges(struct pci_bus * bus,
struct pbus_set_ranges_data * ranges)
{
- struct pci_controler *hose = (struct pci_controler *)bus->sysdata;
+ struct pci_controller *hose = (struct pci_controller *)bus->sysdata;
ranges->io_start -= hose->io_space->start;
ranges->io_end -= hose->io_space->start;
@@ -383,11 +383,11 @@ pcibios_set_master(struct pci_dev *dev)
void __init
common_init_pci(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
struct pci_bus *bus;
int next_busno;
- /* Scan all of the recorded PCI controlers. */
+ /* Scan all of the recorded PCI controllers. */
for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
hose->first_busno = next_busno;
hose->last_busno = 0xff;
@@ -402,10 +402,10 @@ common_init_pci(void)
}
-struct pci_controler * __init
-alloc_pci_controler(void)
+struct pci_controller * __init
+alloc_pci_controller(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
hose = alloc_bootmem(sizeof(*hose));
@@ -432,7 +432,7 @@ alloc_resource(void)
asmlinkage long
sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
struct pci_dev *dev;
/* from hose or from bus.devfn */
diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
index f434b329d..19fe6eea4 100644
--- a/arch/alpha/kernel/pci_impl.h
+++ b/arch/alpha/kernel/pci_impl.h
@@ -6,7 +6,7 @@
*/
struct pci_dev;
-struct pci_controler;
+struct pci_controller;
struct pci_iommu_arena;
/*
@@ -68,6 +68,7 @@ struct pci_iommu_arena;
/* ??? Experimenting with no HAE for CIA. */
#define CIA_DEFAULT_MEM_BASE ((32+2)*1024*1024)
+#define IRONGATE_DEFAULT_MEM_BASE ((256*8-16)*1024*1024)
/*
* A small note about bridges and interrupts. The DECchip 21050 (and
@@ -133,7 +134,7 @@ static inline u8 bridge_swizzle(u8 pin, u8 slot)
struct pci_iommu_arena
{
spinlock_t lock;
- struct pci_controler *hose;
+ struct pci_controller *hose;
unsigned long *ptes;
dma_addr_t dma_base;
unsigned int size;
@@ -143,15 +144,15 @@ struct pci_iommu_arena
/* The hose list. */
-extern struct pci_controler *hose_head, **hose_tail;
-extern struct pci_controler *pci_isa_hose;
+extern struct pci_controller *hose_head, **hose_tail;
+extern struct pci_controller *pci_isa_hose;
extern void common_init_pci(void);
extern u8 common_swizzle(struct pci_dev *, u8 *);
-extern struct pci_controler *alloc_pci_controler(void);
+extern struct pci_controller *alloc_pci_controller(void);
extern struct resource *alloc_resource(void);
-extern struct pci_iommu_arena *iommu_arena_new(struct pci_controler *,
+extern struct pci_iommu_arena *iommu_arena_new(struct pci_controller *,
dma_addr_t, unsigned long,
unsigned long);
extern long iommu_arena_alloc(struct pci_iommu_arena *arena, long n);
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index d4eb6a5d9..13e2eab4e 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -43,7 +43,7 @@ calc_npages(long bytes)
}
struct pci_iommu_arena *
-iommu_arena_new(struct pci_controler *hose, dma_addr_t base,
+iommu_arena_new(struct pci_controller *hose, dma_addr_t base,
unsigned long window_size, unsigned long align)
{
unsigned long mem_size;
@@ -147,7 +147,7 @@ iommu_arena_free(struct pci_iommu_arena *arena, long ofs, long n)
dma_addr_t
pci_map_single(struct pci_dev *pdev, void *cpu_addr, long size, int direction)
{
- struct pci_controler *hose = pdev ? pdev->sysdata : pci_isa_hose;
+ struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
dma_addr_t max_dma = pdev ? pdev->dma_mask : 0x00ffffff;
struct pci_iommu_arena *arena;
long npages, dma_ofs, i;
@@ -215,7 +215,7 @@ void
pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, long size,
int direction)
{
- struct pci_controler *hose = pdev ? pdev->sysdata : pci_isa_hose;
+ struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
struct pci_iommu_arena *arena;
long dma_ofs, npages;
@@ -454,7 +454,7 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
int direction)
{
struct scatterlist *start, *end, *out;
- struct pci_controler *hose;
+ struct pci_controller *hose;
struct pci_iommu_arena *arena;
dma_addr_t max_dma;
@@ -528,7 +528,7 @@ void
pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
int direction)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
struct pci_iommu_arena *arena;
struct scatterlist *end;
dma_addr_t max_dma;
@@ -596,7 +596,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
int
pci_dma_supported(struct pci_dev *pdev, dma_addr_t mask)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
struct pci_iommu_arena *arena;
#if !DEBUG_NODIRECT
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index 5463c9fec..7be5f6dc8 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -10,14 +10,14 @@
struct pt_regs;
struct task_struct;
struct pci_dev;
-struct pci_controler;
+struct pci_controller;
/* core_apecs.c */
extern struct pci_ops apecs_pci_ops;
extern void apecs_init_arch(void);
extern void apecs_pci_clr_err(void);
extern void apecs_machine_check(u64, u64, struct pt_regs *);
-extern void apecs_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t);
+extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_cia.c */
extern struct pci_ops cia_pci_ops;
@@ -25,7 +25,7 @@ extern void cia_init_pci(void);
extern void cia_init_arch(void);
extern void pyxis_init_arch(void);
extern void cia_machine_check(u64, u64, struct pt_regs *);
-extern void cia_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t);
+extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_irongate.c */
extern struct pci_ops irongate_pci_ops;
@@ -38,14 +38,14 @@ extern void irongate_machine_check(u64, u64, struct pt_regs *);
extern struct pci_ops lca_pci_ops;
extern void lca_init_arch(void);
extern void lca_machine_check(u64, u64, struct pt_regs *);
-extern void lca_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t);
+extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_mcpcia.c */
extern struct pci_ops mcpcia_pci_ops;
extern void mcpcia_init_arch(void);
extern void mcpcia_init_hoses(void);
extern void mcpcia_machine_check(u64, u64, struct pt_regs *);
-extern void mcpcia_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t);
+extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_polaris.c */
extern struct pci_ops polaris_pci_ops;
@@ -66,21 +66,21 @@ extern struct pci_ops titan_pci_ops;
extern void titan_init_arch(void);
extern void titan_kill_arch(int);
extern void titan_machine_check(u64, u64, struct pt_regs *);
-extern void titan_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t);
+extern void titan_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_tsunami.c */
extern struct pci_ops tsunami_pci_ops;
extern void tsunami_init_arch(void);
extern void tsunami_kill_arch(int);
extern void tsunami_machine_check(u64, u64, struct pt_regs *);
-extern void tsunami_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t);
+extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_wildfire.c */
extern struct pci_ops wildfire_pci_ops;
extern void wildfire_init_arch(void);
extern void wildfire_kill_arch(int);
extern void wildfire_machine_check(u64, u64, struct pt_regs *);
-extern void wildfire_pci_tbi(struct pci_controler *, dma_addr_t, dma_addr_t);
+extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* setup.c */
extern unsigned long srm_hae;
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index a6443da53..cf5f62dee 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -201,7 +201,7 @@ reserve_std_resources(void)
long i;
if (hose_head) {
- struct pci_controler *hose;
+ struct pci_controller *hose;
for (hose = hose_head; hose; hose = hose->next)
if (hose->index == 0) {
io = hose->io_space;
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index 6197a6a14..c41daf689 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -404,13 +404,13 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
};
const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
if (irq > 0) {
irq += 16 * hose->index;
} else {
- /* ??? The Contaq IDE controler on the ISA bridge uses
+ /* ??? The Contaq IDE controller on the ISA bridge uses
"legacy" interrupts 14 and 15. I don't know if anything
can wind up at the same slot+pin on hose1, so we'll
just have to trust whatever value the console might
@@ -455,7 +455,7 @@ monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
static u8 __init
monet_swizzle(struct pci_dev *dev, u8 *pinp)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
int slot, pin = *pinp;
if (hose->first_busno == dev->bus->number) {
@@ -521,7 +521,7 @@ clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
};
const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
if (irq > 0)
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c
index 4545ff0e2..06ad658d4 100644
--- a/arch/alpha/kernel/sys_eiger.c
+++ b/arch/alpha/kernel/sys_eiger.c
@@ -177,7 +177,7 @@ eiger_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
static u8 __init
eiger_swizzle(struct pci_dev *dev, u8 *pinp)
{
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
int slot, pin = *pinp;
int bridge_count = 0;
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index ae09ecbd1..ea7a104db 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -124,12 +124,12 @@ jensen_init_irq(void)
static void __init
jensen_init_arch(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
/* Create a hose so that we can report i/o base addresses to
userland. */
- pci_isa_hose = hose = alloc_pci_controler();
+ pci_isa_hose = hose = alloc_pci_controller();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->index = 0;
diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
index 2115b8d2c..2964ab56c 100644
--- a/arch/alpha/kernel/sys_nautilus.c
+++ b/arch/alpha/kernel/sys_nautilus.c
@@ -518,7 +518,7 @@ struct alpha_machine_vector nautilus_mv __initmv = {
machine_check: nautilus_machine_check,
max_dma_address: ALPHA_NAUTILUS_MAX_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
- min_mem_address: DEFAULT_MEM_BASE,
+ min_mem_address: IRONGATE_DEFAULT_MEM_BASE,
nr_irqs: 16,
device_interrupt: isa_device_interrupt,
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
index b18c148d1..681c76ea6 100644
--- a/arch/alpha/kernel/sys_rawhide.c
+++ b/arch/alpha/kernel/sys_rawhide.c
@@ -139,7 +139,7 @@ rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
static void __init
rawhide_init_irq(void)
{
- struct pci_controler *hose;
+ struct pci_controller *hose;
long i;
mcpcia_init_hoses();
@@ -204,7 +204,7 @@ rawhide_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
};
const long min_idsel = 1, max_idsel = 5, irqs_per_slot = 5;
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
if (irq >= 0)
irq += 24 * hose->index;
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 190b76bd9..9024644c1 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -321,10 +321,10 @@ privateer_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
}
#ifdef CONFIG_VGA_HOSE
-static struct pci_controler * __init
-privateer_vga_hose_select(struct pci_controler *h1, struct pci_controler *h2)
+static struct pci_controller * __init
+privateer_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2)
{
- struct pci_controler *hose = h1;
+ struct pci_controller *hose = h1;
int agp1, agp2;
/* which hose(s) are agp? */
diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c
index 8a7ad55c4..dbc4bee48 100644
--- a/arch/alpha/kernel/sys_wildfire.c
+++ b/arch/alpha/kernel/sys_wildfire.c
@@ -315,7 +315,7 @@ wildfire_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
};
const long min_idsel = 0, max_idsel = 7, irqs_per_slot = 5;
- struct pci_controler *hose = dev->sysdata;
+ struct pci_controller *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
if (irq > 0) {
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index ddc677339..f27f0a9f2 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -113,7 +113,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
goto vmalloc_fault;
#endif
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
@@ -146,7 +146,7 @@ good_area:
* the fault.
*/
fault = handle_mm_fault(mm, vma, address, cause > 0);
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
if (fault < 0)
goto out_of_memory;
@@ -160,7 +160,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
if (user_mode(regs)) {
force_sig(SIGSEGV, current);
diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S
index 65f70c727..dacad00b5 100644
--- a/arch/arm/kernel/entry-armo.S
+++ b/arch/arm/kernel/entry-armo.S
@@ -29,13 +29,12 @@
#include <linux/config.h>
#include <asm/assembler.h>
+#include <asm/constants.h>
#include <asm/errno.h>
#include <asm/hardware.h>
-#include "../lib/constants.h"
-
.macro zero_fp
-#ifdef CONFIG_FRAME_POINTER
+#ifndef CONFIG_NO_FRAME_POINTER
mov fp, #0
#endif
.endm
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index e659b966d..145420266 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -17,19 +17,19 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/constants.h>
#include <asm/errno.h>
#include <asm/hardware.h>
#include <asm/arch/irqs.h>
#include <asm/proc-fns.h>
-#include "../lib/constants.h"
#ifndef MODE_SVC
#define MODE_SVC 0x13
#endif
.macro zero_fp
-#ifdef CONFIG_FRAME_POINTER
+#ifndef CONFIG_NO_FRAME_POINTER
mov fp, #0
#endif
.endm
@@ -611,9 +611,9 @@ __und_invalid: sub sp, sp, #S_FRAME_SIZE
#else
wfs_mask_data: .word 0x0e200110 @ WFS/RFS
.word 0x0fef0fff
- .word 0x0d0d0100 @ LDF [sp]/STF [sp]
- .word 0x0d0b0100 @ LDF [fp]/STF [fp]
- .word 0x0f0f0f00
+ .word 0x0d000100 @ LDF [sp]/STF [sp]
+ .word 0x0d000100 @ LDF [fp]/STF [fp]
+ .word 0x0f000f00
/* We get here if an undefined instruction happens and the floating
* point emulator is not present. If the offending instruction was
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 8fe41f38c..1f295c8b3 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -215,7 +215,7 @@ sys_sigaltstack_wrapper:
sys_mmap2:
#if PAGE_SHIFT > 12
tst r5, #PGOFF_MASK
- moveq r5, r5, lsr #PGOFF_SHIFT
+ moveq r5, r5, lsr #PAGE_SHIFT - 12
streq r5, [sp, #4]
beq do_mmap2
mov r0, #-EINVAL
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 16b8e59ea..7cbec1406 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -65,9 +65,9 @@ inline long do_mmap2(
goto out;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index ee111801f..58106bff6 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -54,9 +54,3 @@ ifneq ($(MACHINE),ebsa110)
endif
include $(TOPDIR)/Rules.make
-
-constants.h: getconsdata.o extractconstants.pl
- $(PERL) extractconstants.pl $(OBJDUMP) > $@
-
-getconsdata.o: getconsdata.c
- $(CC) $(CFLAGS) -c getconsdata.c
diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
index d7cf6fe45..b930b613d 100644
--- a/arch/arm/lib/copy_page.S
+++ b/arch/arm/lib/copy_page.S
@@ -11,7 +11,7 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
+#include <asm/constants.h>
.text
.align 5
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index 3799ccaec..9b5af1409 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -11,7 +11,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/errno.h>
-#include "constants.h"
+#include <asm/constants.h>
.text
diff --git a/arch/arm/lib/extractconstants.pl b/arch/arm/lib/extractconstants.pl
deleted file mode 100644
index 8c96b3f28..000000000
--- a/arch/arm/lib/extractconstants.pl
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/perl
-
-$OBJDUMP=$ARGV[0];
-
-sub swapdata {
- local ($num) = @_;
-
- return substr($num, 6, 2).substr($num, 4, 2).substr ($num, 2, 2).substr ($num, 0, 2);
-}
-
-open (DATA, $OBJDUMP.' --full-contents --section=.data getconsdata.o | grep \'^ 00\' |') ||
- die ('Cant objdump!');
-while (<DATA>) {
- ($addr, $data0, $data1, $data2, $data3) = split (' ');
- $dat[hex($addr)] = hex(&swapdata($data0));
- $dat[hex($addr)+4] = hex(&swapdata($data1));
- $dat[hex($addr)+8] = hex(&swapdata($data2));
- $dat[hex($addr)+12] = hex(&swapdata($data3));
-}
-close (DATA);
-
-open (DATA, $OBJDUMP.' --syms getconsdata.o |') || die ('Cant objdump!');
-while (<DATA>) {
- /elf32/ && ( $elf = 1 );
- /a.out/ && ( $aout = 1 );
- next if ($aout && ! / 07 /);
- next if ($elf && ! (/^0*0...... g/ && /.data/));
- next if (!$aout && !$elf);
-
- if ($aout) {
- ($addr, $flags, $sect, $a1, $a2, $a3, $name) = split (' ');
- $nam[hex($addr)] = substr($name, 1);
- }
- if ($elf) {
- chomp;
- $addr = substr ($_, 0, index($_, " "));
- $name = substr ($_, rindex($_, " ") + 1);
- $nam[hex($addr)] = $name;
- }
-}
-close (DATA);
-
-print "/*\n * *** This file is automatically generated from getconsdata.c. Do not edit! ***\n */\n";
-for ($i = 0; $i < hex($addr)+4; $i += 4) {
- print "#define $nam[$i] $dat[$i]\n";
-}
diff --git a/arch/arm/lib/getconsdata.c b/arch/arm/lib/getconsdata.c
deleted file mode 100644
index ee8040be7..000000000
--- a/arch/arm/lib/getconsdata.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * linux/arch/arm/lib/getconsdata.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/sched.h>
-#include <linux/mm.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-
-/*
- * Make sure that the compiler and target are compatible
- */
-#if (defined(__APCS_32__) && defined(CONFIG_CPU_26))
-#error Your compiler targets APCS-32 but this kernel requires APCS-26.
-#endif
-#if (defined(__APCS_26__) && defined(CONFIG_CPU_32))
-#error Your compiler targets APCS-26 but this kernel requires APCS-32.
-#endif
-
-#undef PAGE_READONLY
-
-#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
-#define OFF_MM(n) (unsigned long)&(((struct mm_struct *)0)->n)
-
-unsigned long TSK_SIGPENDING = OFF_TSK(sigpending);
-unsigned long TSK_ADDR_LIMIT = OFF_TSK(addr_limit);
-unsigned long TSK_NEED_RESCHED = OFF_TSK(need_resched);
-unsigned long TSK_PTRACE = OFF_TSK(ptrace);
-unsigned long TSK_USED_MATH = OFF_TSK(used_math);
-
-unsigned long TSS_SAVE = OFF_TSK(thread.save);
-unsigned long TSS_FPESAVE = OFF_TSK(thread.fpstate.soft.save);
-#ifdef CONFIG_CPU_32
-unsigned long TSS_DOMAIN = OFF_TSK(thread.domain);
-#endif
-
-#ifdef _PAGE_PRESENT
-unsigned long PAGE_PRESENT = _PAGE_PRESENT;
-#endif
-#ifdef _PAGE_RW
-unsigned long PAGE_RW = _PAGE_RW;
-#endif
-#ifdef _PAGE_USER
-unsigned long PAGE_USER = _PAGE_USER;
-#endif
-#ifdef _PAGE_ACCESSED
-unsigned long PAGE_ACCESSED = _PAGE_ACCESSED;
-#endif
-#ifdef _PAGE_DIRTY
-unsigned long PAGE_DIRTY = _PAGE_DIRTY;
-#endif
-#ifdef _PAGE_READONLY
-unsigned long PAGE_READONLY = _PAGE_READONLY;
-#endif
-#ifdef _PAGE_NOT_USER
-unsigned long PAGE_NOT_USER = _PAGE_NOT_USER;
-#endif
-#ifdef _PAGE_OLD
-unsigned long PAGE_OLD = _PAGE_OLD;
-#endif
-#ifdef _PAGE_CLEAN
-unsigned long PAGE_CLEAN = _PAGE_CLEAN;
-#endif
-
-#ifdef PTE_TYPE_SMALL
-unsigned long HPTE_TYPE_SMALL = PTE_TYPE_SMALL;
-unsigned long HPTE_AP_READ = PTE_AP_READ;
-unsigned long HPTE_AP_WRITE = PTE_AP_WRITE;
-#endif
-
-#ifdef L_PTE_PRESENT
-unsigned long LPTE_PRESENT = L_PTE_PRESENT;
-unsigned long LPTE_YOUNG = L_PTE_YOUNG;
-unsigned long LPTE_BUFFERABLE = L_PTE_BUFFERABLE;
-unsigned long LPTE_CACHEABLE = L_PTE_CACHEABLE;
-unsigned long LPTE_USER = L_PTE_USER;
-unsigned long LPTE_WRITE = L_PTE_WRITE;
-unsigned long LPTE_EXEC = L_PTE_EXEC;
-unsigned long LPTE_DIRTY = L_PTE_DIRTY;
-#endif
-
-unsigned long PAGE_SZ = PAGE_SIZE;
-
-unsigned long KSWI_BASE = 0x900000;
-unsigned long KSWI_SYS_BASE = 0x9f0000;
-unsigned long SYS_ERROR0 = 0x9f0000;
-unsigned long PGOFF_SHIFT = PAGE_SHIFT - 12;
-unsigned long PGOFF_MASK = (1 << (PAGE_SHIFT - 12)) - 1;
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index e652b5276..87342f299 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -11,7 +11,6 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
.text
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
new file mode 100644
index 000000000..0b6166c87
--- /dev/null
+++ b/arch/arm/mach-integrator/Makefile
@@ -0,0 +1,24 @@
+#
+# 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 := integrator.o
+
+# Object file lists.
+
+obj-y := arch.o irq.o mm.o time.o
+obj-m :=
+obj-n :=
+obj- :=
+
+export-objs := leds.o
+
+obj-$(CONFIG_LEDS) += leds.o
+obj-$(CONFIG_PCI) += pci_v3.o pci.o
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/arm/mach-integrator/arch.c b/arch/arm/mach-integrator/arch.c
new file mode 100644
index 000000000..a31549c07
--- /dev/null
+++ b/arch/arm/mach-integrator/arch.c
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/arm/mach-integrator/arch.c
+ *
+ * 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
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/amba_kmi.h>
+
+extern void integrator_map_io(void);
+extern void integrator_init_irq(void);
+
+#ifdef CONFIG_KMI_KEYB
+static struct kmi_info integrator_keyboard __initdata = {
+ base: IO_ADDRESS(KMI0_BASE),
+ irq: IRQ_KMIINT0,
+ divisor: 24 / 8 - 1,
+ type: KMI_KEYBOARD,
+};
+
+static struct kmi_info integrator_mouse __initdata = {
+ base: IO_ADDRESS(KMI1_BASE),
+ irq: IRQ_KMIINT1,
+ divisor: 24 / 8 - 1,
+ type: KMI_MOUSE,
+};
+#endif
+
+static void __init
+integrator_fixup(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline, struct meminfo *mi)
+{
+#ifdef CONFIG_KMI_KEYB
+ register_kmi(&integrator_keyboard);
+ register_kmi(&integrator_mouse);
+#endif
+}
+
+MACHINE_START(INTEGRATOR, "ARM-Integrator")
+ MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
+ BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
+ BOOT_PARAMS(0x00000100)
+ FIXUP(integrator_fixup)
+ MAPIO(integrator_map_io)
+ INITIRQ(integrator_init_irq)
+MACHINE_END
diff --git a/arch/arm/mach-integrator/dma.c b/arch/arm/mach-integrator/dma.c
new file mode 100644
index 000000000..aa5ba5a43
--- /dev/null
+++ b/arch/arm/mach-integrator/dma.c
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-integrator/dma.c
+ *
+ * Copyright (C) 1999 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
+ */
+#include <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+}
diff --git a/arch/arm/mach-integrator/irq.c b/arch/arm/mach-integrator/irq.c
new file mode 100644
index 000000000..546ade980
--- /dev/null
+++ b/arch/arm/mach-integrator/irq.c
@@ -0,0 +1,71 @@
+/*
+ * linux/arch/arm/mach-integrator/irq.c
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+/*
+ * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
+ * is the (PA >> 12).
+ *
+ * Setup a VA for the Integrator interrupt controller (for header #0,
+ * just for now).
+ */
+#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
+#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
+
+#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) )
+
+static void sc_mask_irq(unsigned int irq)
+{
+ __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+}
+
+static void sc_unmask_irq(unsigned int irq)
+{
+ __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET);
+}
+
+void __init integrator_init_irq(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < NR_IRQS; i++) {
+ if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) {
+ irq_desc[i].valid = 1;
+ irq_desc[i].probe_ok = 1;
+ irq_desc[i].mask_ack = sc_mask_irq;
+ irq_desc[i].mask = sc_mask_irq;
+ irq_desc[i].unmask = sc_unmask_irq;
+ }
+ }
+
+ /* Disable all interrupts initially. */
+ /* Do the core module ones */
+ __raw_writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+
+ /* do the header card stuff next */
+ __raw_writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+ __raw_writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+}
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c
new file mode 100644
index 000000000..8fe7df14a
--- /dev/null
+++ b/arch/arm/mach-integrator/leds.c
@@ -0,0 +1,94 @@
+/*
+ * linux/arch/arm/mach-integrator/leds.c
+ *
+ * Integrator LED control routines
+ *
+ * Copyright (C) 1999 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
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+static int saved_leds;
+
+static void integrator_leds_event(led_event_t ledevt)
+{
+ unsigned long flags;
+ const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE);
+ const unsigned int hdr_ctrl = IO_ADDRESS(INTEGRATOR_HDR_BASE) +
+ INTEGRATOR_HDR_CTRL_OFFSET;
+ unsigned int ctrl;
+ unsigned int update_alpha_leds;
+
+ // yup, change the LEDs
+ local_irq_save(flags);
+ update_alpha_leds = 0;
+
+ switch(ledevt) {
+ case led_idle_start:
+ ctrl = __raw_readl(hdr_ctrl);
+ ctrl &= ~INTEGRATOR_HDR_CTRL_LED;
+ __raw_writel(ctrl, hdr_ctrl);
+ break;
+
+ case led_idle_end:
+ ctrl = __raw_readl(hdr_ctrl);
+ ctrl |= INTEGRATOR_HDR_CTRL_LED;
+ __raw_writel(ctrl, hdr_ctrl);
+ break;
+
+ case led_timer:
+ saved_leds ^= GREEN_LED;
+ update_alpha_leds = 1;
+ break;
+
+ case led_red_on:
+ saved_leds |= RED_LED;
+ update_alpha_leds = 1;
+ break;
+
+ case led_red_off:
+ saved_leds &= ~RED_LED;
+ update_alpha_leds = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ if (update_alpha_leds) {
+ while (__raw_readl(dbg_base + INTEGRATOR_DBG_ALPHA_OFFSET) & 1);
+ __raw_writel(saved_leds, dbg_base + INTEGRATOR_DBG_LEDS_OFFSET);
+ }
+ local_irq_restore(flags);
+}
+
+static int __init leds_init(void)
+{
+ if (machine_is_integrator())
+ leds_event = integrator_leds_event;
+
+ return 0;
+}
+
+__initcall(leds_init);
diff --git a/arch/arm/mach-integrator/mm.c b/arch/arm/mach-integrator/mm.c
new file mode 100644
index 000000000..234228c45
--- /dev/null
+++ b/arch/arm/mach-integrator/mm.c
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/arm/mach-integrator/mm.c
+ *
+ * Extra MM routines for the ARM Integrator board
+ *
+ * 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
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+
+/*
+ * Logical Physical
+ * e8000000 40000000 PCI memory
+ * ec000000 62000000 PCI config space
+ * ed000000 61000000 PCI V3 regs
+ * ee000000 60000000 PCI IO
+ * ef000000 Cache flush
+ * f1000000 10000000 Core module registers
+ * f1100000 11000000 System controller registers
+ * f1200000 12000000 EBI registers
+ * f1300000 13000000 Counter/Timer
+ * f1400000 14000000 Interrupt controller
+ * f1500000 15000000 RTC
+ * f1600000 16000000 UART 0
+ * f1700000 17000000 UART 1
+ * f1800000 18000000 Keyboard
+ * f1900000 19000000 Mouse
+ * f1a00000 1a000000 Debug LEDs
+ * f1b00000 1b000000 GPIO
+ */
+
+static struct map_desc integrator_io_desc[] __initdata = {
+ { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_RTC_BASE), INTEGRATOR_RTC_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_KBD_BASE), INTEGRATOR_KBD_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_MOUSE_BASE), INTEGRATOR_MOUSE_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K , DOMAIN_IO, 0, 1},
+ { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M , DOMAIN_IO, 0, 1},
+ { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M , DOMAIN_IO, 0, 1},
+ { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_512K , DOMAIN_IO, 0, 1},
+ { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K , DOMAIN_IO, 0, 1},
+ LAST_DESC
+};
+
+void __init integrator_map_io(void)
+{
+ iotable_init(integrator_io_desc);
+}
diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c
new file mode 100644
index 000000000..9339ceb1b
--- /dev/null
+++ b/arch/arm/mach-integrator/pci.c
@@ -0,0 +1,119 @@
+/*
+ * linux/arch/arm/mach-integrator/pci-integrator.c
+ *
+ * Copyright (C) 1999 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
+ *
+ *
+ * PCI functions for Integrator
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+
+/*
+ * A small note about bridges and interrupts. The DECchip 21050 (and
+ * later) adheres to the PCI-PCI bridge specification. This says that
+ * the interrupts on the other side of a bridge are swizzled in the
+ * following manner:
+ *
+ * Dev Interrupt Interrupt
+ * Pin on Pin on
+ * Device Connector
+ *
+ * 4 A A
+ * B B
+ * C C
+ * D D
+ *
+ * 5 A B
+ * B C
+ * C D
+ * D A
+ *
+ * 6 A C
+ * B D
+ * C A
+ * D B
+ *
+ * 7 A D
+ * B A
+ * C B
+ * D C
+ *
+ * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
+ * Thus, each swizzle is ((pin-1) + (device#-4)) % 4
+ *
+ * The following code swizzles for exactly one bridge.
+ */
+static inline int bridge_swizzle(int pin, unsigned int slot)
+{
+ return (pin + slot) & 3;
+}
+
+/*
+ * This routine handles multiple bridges.
+ */
+static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+ int pin = *pinp;
+
+ if (pin == 0)
+ pin = 1;
+
+ pin -= 1;
+ while (dev->bus->self) {
+ pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+ /*
+ * move up the chain of bridges, swizzling as we go.
+ */
+ dev = dev->bus->self;
+ }
+ *pinp = pin + 1;
+
+ return PCI_SLOT(dev->devfn);
+}
+
+static int irq_tab[4] __initdata = {
+ IRQ_PCIINT0, IRQ_PCIINT1, IRQ_PCIINT2, IRQ_PCIINT3
+};
+
+/*
+ * map the specified device/slot/pin to an IRQ. This works out such
+ * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
+ */
+static int __init integrator_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int intnr = ((slot - 9) + (pin - 1)) & 3;
+
+ return irq_tab[intnr];
+}
+
+extern void pci_v3_init(struct arm_pci_sysdata *);
+
+struct hw_pci integrator_pci __initdata = {
+ init: pci_v3_init,
+ swizzle: integrator_swizzle,
+ map_irq: integrator_map_irq,
+};
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
new file mode 100644
index 000000000..1046e2826
--- /dev/null
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -0,0 +1,460 @@
+/*
+ * linux/arch/arm/mach-integrator/pci_v3.c
+ *
+ * PCI functions for V3 host PCI bridge
+ *
+ * Copyright (C) 1999 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
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+
+#include <asm/hardware/pci_v3.h>
+
+/*
+ * The V3 PCI interface chip in Integrator provides several windows from
+ * local bus memory into the PCI memory areas. Unfortunately, there
+ * are not really enough windows for our usage, therefore we reuse
+ * one of the windows for access to PCI configuration space. The
+ * memory map is as follows:
+ *
+ * Local Bus Memory Usage
+ *
+ * 40000000 - 4FFFFFFF PCI memory. 256M non-prefetchable
+ * 50000000 - 5FFFFFFF PCI memory. 256M prefetchable
+ * 60000000 - 60FFFFFF PCI IO. 16M
+ * 68000000 - 68FFFFFF PCI Configuration. 16M
+ *
+ * There are three V3 windows, each described by a pair of V3 registers.
+ * These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2.
+ * Base0 and Base1 can be used for any type of PCI memory access. Base2
+ * can be used either for PCI I/O or for I20 accesses. By default, uHAL
+ * uses this only for PCI IO space.
+ *
+ * PCI Memory is mapped so that assigned addresses in PCI Memory match
+ * local bus memory addresses. In other words, if a PCI device is assigned
+ * address 80200000 then that address is a valid local bus address as well
+ * as a valid PCI Memory address. PCI IO addresses are mapped to start
+ * at zero. This means that local bus address 60000000 maps to PCI IO address
+ * 00000000 and so on. Device driver writers need to be aware of this
+ * distinction.
+ *
+ * Normally these spaces are mapped using the following base registers:
+ *
+ * Usage Local Bus Memory Base/Map registers used
+ *
+ * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0
+ * Mem 50000000 - 5FFFFFFF LB_BASE1/LB_MAP1
+ * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2
+ * Cfg 68000000 - 68FFFFFF
+ *
+ * This means that I20 and PCI configuration space accesses will fail.
+ * When PCI configuration accesses are needed (via the uHAL PCI
+ * configuration space primitives) we must remap the spaces as follows:
+ *
+ * Usage Local Bus Memory Base/Map registers used
+ *
+ * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0
+ * Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0
+ * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2
+ * Cfg 68000000 - 68FFFFFF LB_BASE1/LB_MAP1
+ *
+ * To make this work, the code depends on overlapping windows working.
+ * The V3 chip translates an address by checking its range within
+ * each of the BASE/MAP pairs in turn (in ascending register number
+ * order). It will use the first matching pair. So, for example,
+ * if the same address is mapped by both LB_BASE0/LB_MAP0 and
+ * LB_BASE1/LB_MAP1, the V3 will use the translation from
+ * LB_BASE0/LB_MAP0.
+ *
+ * To allow PCI Configuration space access, the code enlarges the
+ * window mapped by LB_BASE0/LB_MAP0 from 256M to 512M. This occludes
+ * the windows currently mapped by LB_BASE1/LB_MAP1 so that it can
+ * be remapped for use by configuration cycles.
+ *
+ * At the end of the PCI Configuration space accesses,
+ * LB_BASE1/LB_MAP1 is reset to map PCI Memory. Finally the window
+ * mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to
+ * reveal the now restored LB_BASE1/LB_MAP1 window.
+ *
+ * NOTE: We do not set up I2O mapping. I suspect that this is only
+ * for an intelligent (target) device. Using I2O disables most of
+ * the mappings into PCI memory.
+ */
+
+// V3 access routines
+#define _V3Write16(o,v) __raw_writew(v, PCI_V3_VADDR + (unsigned int)(o))
+#define _V3Read16(o) (__raw_readw(PCI_V3_VADDR + (unsigned int)(o)))
+
+#define _V3Write32(o,v) __raw_writel(v, PCI_V3_VADDR + (unsigned int)(o))
+#define _V3Read32(o) (__raw_readl(PCI_V3_VADDR + (unsigned int)(o)))
+
+/*============================================================================
+ *
+ * routine: uHALir_PCIMakeConfigAddress()
+ *
+ * parameters: bus = which bus
+ * device = which device
+ * function = which function
+ * offset = configuration space register we are interested in
+ *
+ * description: this routine will generate a platform dependant config
+ * address.
+ *
+ * calls: none
+ *
+ * returns: configuration address to play on the PCI bus
+ *
+ * To generate the appropriate PCI configuration cycles in the PCI
+ * configuration address space, you present the V3 with the following pattern
+ * (which is very nearly a type 1 (except that the lower two bits are 00 and
+ * not 01). In order for this mapping to work you need to set up one of
+ * the local to PCI aperatures to 16Mbytes in length translating to
+ * PCI configuration space starting at 0x0000.0000.
+ *
+ * PCI configuration cycles look like this:
+ *
+ * Type 0:
+ *
+ * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
+ * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * 31:11 Device select bit.
+ * 10:8 Function number
+ * 7:2 Register number
+ *
+ * Type 1:
+ *
+ * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
+ * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * 31:24 reserved
+ * 23:16 bus number (8 bits = 128 possible buses)
+ * 15:11 Device number (5 bits)
+ * 10:8 function number
+ * 7:2 register number
+ *
+ */
+static spinlock_t v3_lock = SPIN_LOCK_UNLOCKED;
+
+#define PCI_BUS_NONMEM_START 0x00000000
+#define PCI_BUS_NONMEM_SIZE 0x10000000
+
+#define PCI_BUS_PREMEM_START 0x10000000
+#define PCI_BUS_PREMEM_SIZE 0x10000000
+
+#if PCI_BUS_NONMEM_START & 0x000fffff
+#error PCI_BUS_NONMEM_START must be megabyte aligned
+#endif
+#if PCI_BUS_PREMEM_START & 0x000fffff
+#error PCI_BUS_PREMEM_START must be megabyte aligned
+#endif
+
+static unsigned long v3_open_config_window(struct pci_dev *dev, int offset)
+{
+ unsigned int address, mapaddress, busnr;
+
+ busnr = dev->bus->number;
+
+ /*
+ * Trap out illegal values
+ */
+ if (offset > 255)
+ BUG();
+ if (busnr > 255)
+ BUG();
+ if (dev->devfn > 255)
+ BUG();
+
+ if (busnr == 0) {
+ int slot = PCI_SLOT(dev->devfn);
+
+ /*
+ * local bus segment so need a type 0 config cycle
+ *
+ * build the PCI configuration "address" with one-hot in
+ * A31-A11
+ *
+ * mapaddress:
+ * 3:1 = config cycle (101)
+ * 0 = PCI A1 & A0 are 0 (0)
+ */
+ address = PCI_FUNC(dev->devfn) << 8;
+ mapaddress = 0x0a;
+
+ if (slot > 12)
+ /*
+ * high order bits are handled by the MAP register
+ */
+ mapaddress |= 1 << (slot - 4);
+ else
+ /*
+ * low order bits handled directly in the address
+ */
+ address |= 1 << (slot + 11);
+ } else {
+ /*
+ * not the local bus segment so need a type 1 config cycle
+ *
+ * address:
+ * 23:16 = bus number
+ * 15:11 = slot number (7:3 of devfn)
+ * 10:8 = func number (2:0 of devfn)
+ *
+ * mapaddress:
+ * 3:1 = config cycle (101)
+ * 0 = PCI A1 & A0 from host bus (1)
+ */
+ mapaddress = 0x0b;
+ address = (busnr << 16) | (dev->devfn << 8);
+ }
+
+ /*
+ * Set up base0 to see all 512Mbytes of memory space (not prefetchable), this
+ * frees up base1 for re-use by configuration memory
+ */
+ _V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xFFF00000) | 0x90 | V3_LB_BASE_M_ENABLE);
+
+ /*
+ * Set up base1/map1 to point into configuration space.
+ */
+ _V3Write32(V3_LB_BASE1, (PHYS_PCI_CONFIG_BASE & 0xFFF00000) | 0x40 | V3_LB_BASE_M_ENABLE);
+ _V3Write16(V3_LB_MAP1, mapaddress);
+
+ return PCI_CONFIG_VADDR + address + offset;
+}
+
+static void v3_close_config_window(void)
+{
+ /*
+ * Reassign base1 for use by prefetchable PCI memory
+ */
+ _V3Write32(V3_LB_BASE1, ((PHYS_PCI_MEM_BASE + SZ_256M) & 0xFFF00000) | 0x84 | V3_LB_BASE_M_ENABLE);
+ _V3Write16(V3_LB_MAP1, ((PCI_BUS_PREMEM_START & 0xFFF00000) >> 16) | 0x0006);
+
+ /*
+ * And shrink base0 back to a 256M window (NOTE: MAP0 already correct)
+ */
+ _V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xFFF00000) | 0x80 | V3_LB_BASE_M_ENABLE);
+}
+
+static int v3_read_config_byte(struct pci_dev *dev, int where, u8 *val)
+{
+ unsigned long addr;
+ unsigned long flags;
+ u8 v;
+
+ spin_lock_irqsave(&v3_lock, flags);
+ addr = v3_open_config_window(dev, where);
+
+ v = __raw_readb(addr);
+
+ v3_close_config_window();
+ spin_unlock_irqrestore(&v3_lock, flags);
+
+ *val = v;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_read_config_word(struct pci_dev *dev, int where, u16 *val)
+{
+ unsigned long addr;
+ unsigned long flags;
+ u16 v;
+
+ spin_lock_irqsave(&v3_lock, flags);
+ addr = v3_open_config_window(dev, where);
+
+ v = __raw_readw(addr);
+
+ v3_close_config_window();
+ spin_unlock_irqrestore(&v3_lock, flags);
+
+ *val = v;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_read_config_dword(struct pci_dev *dev, int where, u32 *val)
+{
+ unsigned long addr;
+ unsigned long flags;
+ u32 v;
+
+ spin_lock_irqsave(&v3_lock, flags);
+ addr = v3_open_config_window(dev, where);
+
+ v = __raw_readl(addr);
+
+ v3_close_config_window();
+ spin_unlock_irqrestore(&v3_lock, flags);
+
+ *val = v;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_write_config_byte(struct pci_dev *dev, int where, u8 val)
+{
+ unsigned long addr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&v3_lock, flags);
+ addr = v3_open_config_window(dev, where);
+
+ __raw_writeb(val, addr);
+ __raw_readb(addr);
+
+ v3_close_config_window();
+ spin_unlock_irqrestore(&v3_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_write_config_word(struct pci_dev *dev, int where, u16 val)
+{
+ unsigned long addr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&v3_lock, flags);
+ addr = v3_open_config_window(dev, where);
+
+ __raw_writew(val, addr);
+ __raw_readw(addr);
+
+ v3_close_config_window();
+ spin_unlock_irqrestore(&v3_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+ unsigned long addr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&v3_lock, flags);
+ addr = v3_open_config_window(dev, where);
+
+ __raw_writel(val, addr);
+ __raw_readl(addr);
+
+ v3_close_config_window();
+ spin_unlock_irqrestore(&v3_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_v3_ops = {
+ read_byte: v3_read_config_byte,
+ read_word: v3_read_config_word,
+ read_dword: v3_read_config_dword,
+ write_byte: v3_write_config_byte,
+ write_word: v3_write_config_word,
+ write_dword: v3_write_config_dword,
+};
+
+static struct resource non_mem = {
+ name: "PCI non-prefetchable",
+ start: PCI_BUS_NONMEM_START,
+ end: PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
+ flags: IORESOURCE_MEM,
+};
+
+static struct resource pre_mem = {
+ name: "PCI prefetchable",
+ start: PCI_BUS_PREMEM_START,
+ end: PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
+ flags: IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+/*
+ * V3_LB_BASE? - local bus address
+ * V3_LB_MAP? - pci bus address
+ */
+void __init pci_v3_init(struct arm_pci_sysdata *sysdata)
+{
+ struct pci_bus *bus;
+ unsigned int pci_cmd;
+ unsigned long flags;
+
+ spin_lock_irqsave(&v3_lock, flags);
+
+ /*
+ * Setup window 0 - PCI non-prefetchable memory
+ * Local: 0x40000000 Bus: 0x00000000 Size: 256MB
+ */
+ _V3Write32(V3_LB_BASE0, (PHYS_PCI_MEM_BASE & 0xfff00000) | 0x80 | V3_LB_BASE_M_ENABLE);
+ _V3Write16(V3_LB_MAP0, (PCI_BUS_NONMEM_START >> 16) | 0x0006);
+
+ /*
+ * Setup window 1 - PCI prefetchable memory
+ * Local: 0x50000000 Bus: 0x10000000 Size: 256MB
+ */
+ _V3Write32(V3_LB_BASE1, ((PHYS_PCI_MEM_BASE + SZ_256M) & 0xFFF00000) | 0x84 | V3_LB_BASE_M_ENABLE);
+ _V3Write16(V3_LB_MAP1, (PCI_BUS_PREMEM_START >> 16) | 0x0006);
+
+ /*
+ * Setup window 2 - PCI IO
+ */
+// _V3Write32(V3_LB_BASE2, (PHYS_PCI_IO_BASE & 0xff000000) | V3_LB_BASE_M_ENABLE);
+// _V3Write16(V3_LB_MAP2, 0);
+
+ spin_unlock_irqrestore(&v3_lock, flags);
+
+ bus = pci_scan_bus(0, &pci_v3_ops, sysdata);
+
+ if (request_resource(&iomem_resource, &non_mem))
+ printk("PCI: unable to allocate non-prefetchable memory region");
+ if (request_resource(&iomem_resource, &pre_mem))
+ printk("PCI: unable to allocate prefetchable memory region");
+
+ /*
+ * 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] = &non_mem;
+ bus->resource[2] = &pre_mem;
+
+ pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+
+ pci_cmd |= sysdata->bus[0].features;
+
+ _V3Write16(V3_PCI_CMD, pci_cmd);
+
+ printk("PCI: Fast back to back transfers %sabled\n",
+ (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ?
+ "en" : "dis");
+}
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
new file mode 100644
index 000000000..11dbd96e5
--- /dev/null
+++ b/arch/arm/mach-integrator/time.c
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/arm/mach-integrator/time.c
+ *
+ * Copyright (C) 2000 Deep Blue Solutions
+ *
+ * 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/init.h>
+
+#include <asm/hardware.h>
+
+#define RTC_DR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 0))
+#define RTC_MR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 4))
+#define RTC_STAT (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8))
+#define RTC_EOI (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 8))
+#define RTC_LR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 12))
+#define RTC_CR (*(unsigned long *)(IO_ADDRESS(INTEGRATOR_RTC_BASE) + 16))
+
+#define RTC_CR_MIE 0x00000001
+
+extern int (*set_rtc)(void);
+
+static int integrator_set_rtc(void)
+{
+ RTC_LR = xtime.tv_sec;
+ return 1;
+}
+
+static int integrator_rtc_init(void)
+{
+ RTC_CR = 0;
+ RTC_EOI = 0;
+
+ xtime.tv_sec = RTC_DR;
+
+ set_rtc = integrator_set_rtc;
+
+ return 0;
+}
+
+__initcall(integrator_rtc_init);
diff --git a/arch/arm/mach-sa1100/arch.c b/arch/arm/mach-sa1100/arch.c
index 32ac72379..89123d122 100644
--- a/arch/arm/mach-sa1100/arch.c
+++ b/arch/arm/mach-sa1100/arch.c
@@ -54,7 +54,7 @@ fixup_sa1100(struct machine_desc *desc, struct param_struct *params,
if (machine_is_assabet()) {
/*
* On Assabet, we must probe for the Neponset board *before*
- * paging_init() has occured to actually determine the amount
+ * paging_init() has occurred to actually determine the amount
* of RAM available.
*/
extern void map_sa1100_gpio_regs(void);
diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c
index f79b618a2..b836cfe89 100644
--- a/arch/arm/mm/fault-common.c
+++ b/arch/arm/mm/fault-common.c
@@ -223,9 +223,9 @@ int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
if (in_interrupt() || !mm)
goto no_context;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
fault = __do_page_fault(mm, addr, mode, tsk);
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
ret:
/*
diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c
index 023fee8e0..5695b2ede 100644
--- a/arch/arm/mm/mm-rpc.c
+++ b/arch/arm/mm/mm-rpc.c
@@ -9,6 +9,7 @@
*
* Extra MM routines for RiscPC architecture
*/
+#include <linux/types.h>
#include <linux/init.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c
index 54fe435c6..01e3725c8 100644
--- a/arch/arm/mm/mm-sa1100.c
+++ b/arch/arm/mm/mm-sa1100.c
@@ -199,7 +199,7 @@ pg_data_t sa1100_node_data[4] =
/*
* On Assabet, we must probe for the Neponset board *before* paging_init()
- * has occured to actually determine the amount of RAM available. To do so,
+ * has occurred to actually determine the amount of RAM available. To do so,
* we map the appropriate IO section in the page table here in order to
* access GPIO registers.
*/
diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S
index 76377cf9c..a550ac9d8 100644
--- a/arch/arm/mm/proc-arm2,3.S
+++ b/arch/arm/mm/proc-arm2,3.S
@@ -14,8 +14,8 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/constants.h>
#include <asm/procinfo.h>
-#include "../lib/constants.h"
/*
* MEMC workhorse code. It's both a horse which things it's a pig.
diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S
index d26a98f75..a9a682b5f 100644
--- a/arch/arm/mm/proc-arm6,7.S
+++ b/arch/arm/mm/proc-arm6,7.S
@@ -12,8 +12,8 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/constants.h>
#include <asm/procinfo.h>
-#include "../lib/constants.h"
/*
* Function: arm6_7_cache_clean_invalidate_all (void)
@@ -29,10 +29,10 @@ 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_icache_invalidate_range)
+ENTRY(cpu_arm7_icache_invalidate_range)
+ENTRY(cpu_arm6_icache_invalidate_page)
+ENTRY(cpu_arm7_icache_invalidate_page)
ENTRY(cpu_arm6_dcache_clean_range)
ENTRY(cpu_arm7_dcache_clean_range)
ENTRY(cpu_arm6_dcache_invalidate_range)
@@ -410,8 +410,8 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_dcache_clean_entry
/* icache */
- .word cpu_arm6_invalidate_icache_range
- .word cpu_arm6_invalidate_icache_page
+ .word cpu_arm6_icache_invalidate_range
+ .word cpu_arm6_icache_invalidate_page
/* tlb */
.word cpu_arm6_tlb_invalidate_all
@@ -449,8 +449,8 @@ ENTRY(arm7_processor_functions)
.word cpu_arm7_dcache_clean_entry
/* icache */
- .word cpu_arm7_invalidate_icache_range
- .word cpu_arm7_invalidate_icache_page
+ .word cpu_arm7_icache_invalidate_range
+ .word cpu_arm7_icache_invalidate_page
/* tlb */
.word cpu_arm7_tlb_invalidate_all
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 77b689bdf..4cc7509c4 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -32,9 +32,9 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/constants.h>
#include <asm/procinfo.h>
#include <asm/hardware.h>
-#include "../lib/constants.h"
/*
* Function: arm720_cache_clean_invalidate_all (void)
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 6f1f11601..d3643c400 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -25,9 +25,9 @@
#include <linux/linkage.h>
#include <linux/config.h>
#include <asm/assembler.h>
+#include <asm/constants.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
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 45b0a31fe..3d75d7489 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -19,9 +19,9 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/constants.h>
#include <asm/procinfo.h>
#include <asm/hardware.h>
-#include "../lib/constants.h"
/* This is the maximum size of an area which will be flushed. If the area
* is larger than this, then we flush the whole cache
diff --git a/arch/arm/nwfpe/entry26.S b/arch/arm/nwfpe/entry26.S
index 5108ce63d..d96deaae2 100644
--- a/arch/arm/nwfpe/entry26.S
+++ b/arch/arm/nwfpe/entry26.S
@@ -20,7 +20,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "../lib/constants.h"
+#include <asm/constants.h>
/* This is the kernel's entry point into the floating point emulator.
It is called from the kernel with code similar to this:
diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
new file mode 100644
index 000000000..698083c67
--- /dev/null
+++ b/arch/arm/tools/Makefile
@@ -0,0 +1,36 @@
+#
+# linux/arch/arm/tools/Makefile
+#
+# Copyright (C) 2001 Russell King
+#
+
+all: $(TOPDIR)/include/asm-arm/mach-types.h \
+ $(TOPDIR)/include/asm-arm/constants.h
+
+$(TOPDIR)/include/asm-arm/mach-types.h: mach-types gen-mach-types
+ awk -f gen-mach-types mach-types > $@
+
+# Generate the constants.h header file using the compiler. We get
+# the compiler to spit out assembly code, and then mundge it into
+# what we want.
+
+$(TOPDIR)/include/asm-arm/constants.h: constants-hdr getconstants.c
+ $(CC) $(CFLAGS) -S -o - getconstants.c | \
+ sed 's/^\(#define .* \)#\(.*\)/\1\2/;/^#define/!d' | \
+ cat constants-hdr - > $@.tmp
+ cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@; $(RM) $@.tmp
+
+# Build our dependencies, and then generate the constants and
+# mach-types header files. If we do it now, mkdep will pick
+# the dependencies up later on when it runs through the other
+# directories
+
+dep:
+ $(TOPDIR)/scripts/mkdep getconstants.c | sed s,getconstants.o,$(TOPDIR)/include/asm-arm/constants.h, > .depend
+ $(MAKE) all
+
+.PHONY: all dep
+
+ifneq ($(wildcard .depend),)
+include .depend
+endif
diff --git a/arch/arm/tools/constants-hdr b/arch/arm/tools/constants-hdr
new file mode 100644
index 000000000..fd18d7cb8
--- /dev/null
+++ b/arch/arm/tools/constants-hdr
@@ -0,0 +1,5 @@
+/*
+ * This file is automatically generated from arch/arm/tools/getconstants.c.
+ * Do not edit! Only include this file in assembly (.S) files!
+ */
+
diff --git a/arch/arm/tools/getconstants.c b/arch/arm/tools/getconstants.c
new file mode 100644
index 000000000..3fd2d3e7c
--- /dev/null
+++ b/arch/arm/tools/getconstants.c
@@ -0,0 +1,72 @@
+/*
+ * linux/arch/arm/tools/getconsdata.c
+ *
+ * Copyright (C) 1995-2001 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>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+
+/*
+ * Make sure that the compiler and target are compatible
+ */
+#if (defined(__APCS_32__) && defined(CONFIG_CPU_26))
+#error Your compiler targets APCS-32 but this kernel requires APCS-26.
+#endif
+#if (defined(__APCS_26__) && defined(CONFIG_CPU_32))
+#error Your compiler targets APCS-26 but this kernel requires APCS-32.
+#endif
+
+#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
+
+#define DEFN(name,off) asm("\n#define "name" %0" :: "I" (off))
+
+void func(void)
+{
+DEFN("TSK_SIGPENDING", OFF_TSK(sigpending));
+DEFN("TSK_ADDR_LIMIT", OFF_TSK(addr_limit));
+DEFN("TSK_NEED_RESCHED", OFF_TSK(need_resched));
+DEFN("TSK_PTRACE", OFF_TSK(ptrace));
+DEFN("TSK_USED_MATH", OFF_TSK(used_math));
+
+DEFN("TSS_SAVE", OFF_TSK(thread.save));
+DEFN("TSS_FPESAVE", OFF_TSK(thread.fpstate.soft.save));
+
+#ifdef CONFIG_CPU_32
+DEFN("TSS_DOMAIN", OFF_TSK(thread.domain));
+
+DEFN("HPTE_TYPE_SMALL", PTE_TYPE_SMALL);
+DEFN("HPTE_AP_READ", PTE_AP_READ);
+DEFN("HPTE_AP_WRITE", PTE_AP_WRITE);
+
+DEFN("LPTE_PRESENT", L_PTE_PRESENT);
+DEFN("LPTE_YOUNG", L_PTE_YOUNG);
+DEFN("LPTE_BUFFERABLE", L_PTE_BUFFERABLE);
+DEFN("LPTE_CACHEABLE", L_PTE_CACHEABLE);
+DEFN("LPTE_USER", L_PTE_USER);
+DEFN("LPTE_WRITE", L_PTE_WRITE);
+DEFN("LPTE_EXEC", L_PTE_EXEC);
+DEFN("LPTE_DIRTY", L_PTE_DIRTY);
+#endif
+
+#ifdef CONFIG_CPU_26
+DEFN("PAGE_PRESENT", _PAGE_PRESENT);
+DEFN("PAGE_READONLY", _PAGE_READONLY);
+DEFN("PAGE_NOT_USER", _PAGE_NOT_USER);
+DEFN("PAGE_OLD", _PAGE_OLD);
+DEFN("PAGE_CLEAN", _PAGE_CLEAN);
+#endif
+
+DEFN("PAGE_SZ", PAGE_SIZE);
+
+DEFN("KSWI_BASE", 0x900000);
+DEFN("KSWI_SYS_BASE", 0x9f0000);
+DEFN("SYS_ERROR0", 0x9f0000);
+}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index ff7ccec77..c4f540a25 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -4,7 +4,7 @@
# To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk
#
-# Last update: Mon Nov 20 22:59:11 2000
+# Last update: Fri Feb 9 22:27:32 2001
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -48,13 +48,23 @@ accelent_l7200 ARCH_L7200_ACCELENT ACCELENT_L7200 37
netport SA1100_NETPORT NETPORT 38
pangolin SA1100_PANGOLIN PANGOLIN 39
yopy SA1100_YOPY YOPY 40
-sa1100 SA1100_SA1100 SA1100 41
-huw_webpanel ARCH_HUW_WEBPANEL HUW_WEBPANEL 42
+coolidge SA1100_COOLIDGE coolidge 41
+huw_webpanel SA1100_HUW_WEBPANEL HUW_WEBPANEL 42
spotme ARCH_SPOTME SPOTME 43
freebird ARCH_FREEBIRD FREEBIRD 44
ti925 ARCH_TI925 TI925 45
riscstation ARCH_RISCSTATION RISCSTATION 46
cavy SA1100_CAVY CAVY 47
+jornada720 SA1100_JORNADA720 JORNADA720 48
+omnimeter SA1100_OMNIMETER OMNIMETER 49
+edb7211 ARCH_EDB7211 EDB7211 50
+citygo SA1100_CITYGO CITYGO 51
+pfs168 SA1100_PFS168 PFS168 52
+spot SA1100_SPOT SPOT 53
+flexanet ARCH_FLEXANET FLEXANET 54
+webpal ARCH_WEBPAL WEBPAL 55
+linpda SA1100_LINPDA LINPDA 56
+anakin ARCH_ANAKIN ANAKIN 57
# The following are unallocated
empeg SA1100_EMPEG EMPEG
diff --git a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in
index 10661f414..08544b314 100644
--- a/arch/arm/vmlinux-armv.lds.in
+++ b/arch/arm/vmlinux-armv.lds.in
@@ -45,18 +45,22 @@ SECTIONS
*(.glue_7)
*(.glue_7t)
*(.kstrtab)
- . = ALIGN(16);
- __start___ex_table = .; /* Exception table */
+ *(.got) /* Global offset table */
+
+ _etext = .; /* End of text section */
+ }
+
+ . = ALIGN(16);
+ __ex_table : { /* Exception table */
+ __start___ex_table = .;
*(__ex_table)
__stop___ex_table = .;
+ }
- __start___ksymtab = .; /* Kernel symbol table */
+ __ksymtab : { /* Kernel symbol table */
+ __start___ksymtab = .;
*(__ksymtab)
__stop___ksymtab = .;
-
- *(.got) /* Global offset table */
-
- _etext = .; /* End of text section */
}
. = ALIGN(8192);
diff --git a/arch/cris/drivers/serial.c b/arch/cris/drivers/serial.c
index 2dcb17a5e..feda9a0e0 100644
--- a/arch/cris/drivers/serial.c
+++ b/arch/cris/drivers/serial.c
@@ -146,7 +146,7 @@
*
* Revision 1.24 2000/02/09 18:02:28 bjornw
* * Clear serial errors (overrun, framing, parity) correctly. Before, the
- * receiver would get stuck if an error occured and we did not restart
+ * receiver would get stuck if an error occurred and we did not restart
* the input DMA.
* * Cosmetics (indentation, some code made into inlines)
* * Some more debug options
@@ -1371,7 +1371,7 @@ ser_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
else { /* it was a valid byte, now let the dma do the rest */
#ifdef SERIAL_DEBUG_INTR
- printk("** OK, disabling ser_interupts\n");
+ printk("** OK, disabling ser_interrupts\n");
#endif
e100_disable_serial_data_irq(info);
}
diff --git a/arch/cris/kernel/entry.S b/arch/cris/kernel/entry.S
index 1af62eb2c..65a70922e 100644
--- a/arch/cris/kernel/entry.S
+++ b/arch/cris/kernel/entry.S
@@ -23,7 +23,7 @@
* Revision 1.8 2000/11/17 16:53:35 bjornw
* Added detection of frame-type in Rexit, so that mmu_bus_fault can
* use ret_from_intr in the return-path to check for signals (like SEGV)
- * and other foul things that might have occured during the fault.
+ * and other foul things that might have occurred during the fault.
*
* Revision 1.7 2000/10/06 15:04:28 bjornw
* Include mof in register savings
diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c
index cfcb097f9..94ef1c698 100644
--- a/arch/cris/kernel/sys_cris.c
+++ b/arch/cris/kernel/sys_cris.c
@@ -62,9 +62,9 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
ret = do_mmap(file, addr, len, prot, flags, offset);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
out:
@@ -87,9 +87,9 @@ do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
goto out;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index a4bb237b4..b1493b2d2 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -146,7 +146,7 @@ handle_mmu_bus_fault(struct pt_regs *regs)
* routines.
*
* Notice that the address we're given is aligned to the page the fault
- * occured in, since we only get the PFN in R_MMU_CAUSE not the complete
+ * occurred in, since we only get the PFN in R_MMU_CAUSE not the complete
* address.
*
* error_code:
@@ -212,7 +212,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
if (in_interrupt() || !mm)
goto no_context;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
@@ -270,7 +270,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
/*
@@ -280,7 +280,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
bad_area_nosemaphore:
DPG(show_registers(regs));
@@ -334,14 +334,14 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if(user_mode(regs))
do_exit(SIGKILL);
goto no_context;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/*
* Send a sigbus, regardless of whether we were in kernel
@@ -381,7 +381,7 @@ vmalloc_fault:
pmd = pmd_offset(pgd, address);
pmd_k = pmd_offset(pgd_k, address);
- if (pmd_present(*pmd) || !pmd_present(*pmd_k))
+ if (!pmd_present(*pmd_k))
goto bad_area_nosemaphore;
set_pmd(pmd, *pmd_k);
return;
diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile
index e75eb2fdf..f238d05c5 100644
--- a/arch/i386/boot/Makefile
+++ b/arch/i386/boot/Makefile
@@ -43,7 +43,7 @@ tools/build: tools/build.c
$(HOSTCC) $(HOSTCFLAGS) -o $@ $< -I$(TOPDIR)/include
bootsect: bootsect.o
- $(LD) -Ttext 0x0 -s -oformat binary -o $@ $<
+ $(LD) -Ttext 0x0 -s --oformat binary -o $@ $<
bootsect.o: bootsect.s
$(AS) -o $@ $<
@@ -52,7 +52,7 @@ bootsect.s: bootsect.S Makefile $(BOOT_INCL)
$(CPP) $(CPPFLAGS) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
bbootsect: bbootsect.o
- $(LD) -Ttext 0x0 -s -oformat binary $< -o $@
+ $(LD) -Ttext 0x0 -s --oformat binary $< -o $@
bbootsect.o: bbootsect.s
$(AS) -o $@ $<
@@ -61,7 +61,7 @@ bbootsect.s: bootsect.S Makefile $(BOOT_INCL)
$(CPP) $(CPPFLAGS) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
setup: setup.o
- $(LD) -Ttext 0x0 -s -oformat binary -e begtext -o $@ $<
+ $(LD) -Ttext 0x0 -s --oformat binary -e begtext -o $@ $<
setup.o: setup.s
$(AS) -o $@ $<
@@ -70,7 +70,7 @@ setup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h
$(CPP) $(CPPFLAGS) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
bsetup: bsetup.o
- $(LD) -Ttext 0x0 -s -oformat binary -e begtext -o $@ $<
+ $(LD) -Ttext 0x0 -s --oformat binary -e begtext -o $@ $<
bsetup.o: bsetup.s
$(AS) -o $@ $<
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 875a84bf9..5b62d741c 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -280,6 +280,7 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
@@ -382,7 +383,6 @@ CONFIG_EEPRO100=y
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
# CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
@@ -434,6 +434,7 @@ CONFIG_PCMCIA_PCNET=y
# CONFIG_PCMCIA_XIRTULIP is not set
CONFIG_NET_PCMCIA_RADIO=y
CONFIG_PCMCIA_RAYCS=y
+# CONFIG_PCMCIA_HERMES is not set
# CONFIG_PCMCIA_NETWAVE is not set
# CONFIG_PCMCIA_WAVELAN is not set
# CONFIG_AIRONET4500_CS is not set
@@ -529,13 +530,11 @@ CONFIG_DRM_TDFX=y
CONFIG_DRM_RADEON=y
# CONFIG_DRM_I810 is not set
# CONFIG_DRM_MGA is not set
-CONFIG_PCMCIA_SERIAL=y
#
-# PCMCIA character device support
+# PCMCIA character devices
#
# CONFIG_PCMCIA_SERIAL_CS is not set
-# CONFIG_PCMCIA_SERIAL_CB is not set
#
# Multimedia devices
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index 400216f37..01b4cf8a2 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -415,23 +415,6 @@ ENTRY(pg1)
ENTRY(empty_zero_page)
.org 0x5000
-ENTRY(empty_bad_page)
-
-.org 0x6000
-ENTRY(empty_bad_pte_table)
-
-#if CONFIG_X86_PAE
-
- .org 0x7000
- ENTRY(empty_bad_pmd_table)
-
- .org 0x8000
-
-#else
-
- .org 0x7000
-
-#endif
/*
* This starts the data section. Note that the above is all
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 20bc14fc6..52eb1c79a 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -27,6 +27,7 @@
#include <asm/mmx.h>
#include <asm/desc.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
extern void dump_thread(struct pt_regs *, struct user *);
extern spinlock_t rtc_lock;
@@ -134,6 +135,9 @@ EXPORT_SYMBOL(__global_sti);
EXPORT_SYMBOL(__global_save_flags);
EXPORT_SYMBOL(__global_restore_flags);
EXPORT_SYMBOL(smp_call_function);
+
+/* TLB flushing */
+EXPORT_SYMBOL(flush_tlb_page);
#endif
#ifdef CONFIG_MCA
diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c
index ba97ca4bc..0a2973cfa 100644
--- a/arch/i386/kernel/i387.c
+++ b/arch/i386/kernel/i387.c
@@ -179,7 +179,7 @@ unsigned short get_fpu_twd( struct task_struct *tsk )
unsigned short get_fpu_mxcsr( struct task_struct *tsk )
{
- if ( cpu_has_fxsr ) {
+ if ( cpu_has_xmm ) {
return tsk->thread.i387.fxsave.mxcsr;
} else {
return 0x1f80;
diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
index e94cbfbdc..b50d366af 100644
--- a/arch/i386/kernel/ldt.c
+++ b/arch/i386/kernel/ldt.c
@@ -86,7 +86,7 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
* the GDT index of the LDT is allocated dynamically, and is
* limited by MAX_LDT_DESCRIPTORS.
*/
- down(&mm->mmap_sem);
+ down_write(&mm->mmap_sem);
if (!mm->context.segments) {
error = -ENOMEM;
mm->context.segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
@@ -141,7 +141,7 @@ install:
error = 0;
out_unlock:
- up(&mm->mmap_sem);
+ up_write(&mm->mmap_sem);
out:
return error;
}
diff --git a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c
index d2a8afbbb..18696dedc 100644
--- a/arch/i386/kernel/pci-pc.c
+++ b/arch/i386/kernel/pci-pc.c
@@ -861,6 +861,8 @@ static void __init pci_fixup_serverworks(struct pci_dev *d)
}
}
+#if 0
+/* Our bus code shouldnt need this fixup any more. Delete once verified */
/*
* Compaq host bridges -- Find and scan all secondary buses.
* This time registers 0xc8 and 0xc9.
@@ -878,6 +880,7 @@ static void __init pci_fixup_compaq(struct pci_dev *d)
printk("PCI: Compaq host bridge: last bus %02x\n", busno2);
}
}
+#endif
static void __init pci_fixup_umc_ide(struct pci_dev *d)
{
@@ -934,35 +937,106 @@ static void __init pci_fixup_latency(struct pci_dev *d)
pcibios_max_latency = 32;
}
+static void __init pci_fixup_via_acpi(struct pci_dev *d)
+{
+ /*
+ * VIA ACPI device: IRQ line in PCI config byte 0x42
+ */
+ u8 irq;
+ pci_read_config_byte(d, 0x42, &irq);
+ irq &= 0x0f;
+ if (irq && (irq != 2))
+ d->irq = irq;
+}
+
+static void __init pci_fixup_piix4_acpi(struct pci_dev *d)
+{
+ /*
+ * PIIX4 ACPI device: hardwired IRQ9
+ */
+ d->irq = 9;
+}
+
static void __init pci_fixup_vt8363(struct pci_dev *d)
{
/*
- * VIA VT8363 host bridge has broken feature 'PCI Master Read
- * Caching'. It caches more than is good for it, sometimes
- * serving the bus master with stale data. Some BIOSes enable
- * it by default, so we disable it.
+ * The VIA bridge will corrupt disks without these settings.
+ */
+ u8 tmp;
+ pci_read_config_byte(d, 0x54, &tmp);
+ if(tmp & (1<<2)) {
+ printk("PCI: Bus master Pipeline request disabled\n");
+ pci_write_config_byte(d, 0x54, tmp & ~(1<<2));
+ }
+ pci_read_config_byte(d, 0x70, &tmp);
+ if(tmp & (1<<3)) {
+ printk("PCI: Disabled enhanced CPU to PCI writes\n");
+ pci_write_config_byte(d, 0x70, tmp & ~(1<<3));
+ }
+ pci_read_config_byte(d, 0x71, &tmp);
+ if((tmp & (1<<3)) == 0) {
+ printk("PCI: Bursting cornercase bug worked around\n");
+ pci_write_config_byte(d, 0x71, tmp | (1<<3));
+ }
+ pci_read_config_byte(d, 0x76, &tmp);
+ if(tmp & (1<<7)) {
+ printk("PCI: Post Write Fail set to Retry\n");
+ pci_write_config_byte(d, 0x76, tmp & ~(1<<7));
+ }
+}
+
+static void __init pci_fixup_via691(struct pci_dev *d)
+{
+ /*
+ * The VIA bridge corrupts with Posting enabled
*/
u8 tmp;
+
pci_read_config_byte(d, 0x70, &tmp);
- if(tmp & 4) {
- printk("PCI: Bus master read caching disabled\n");
- pci_write_config_byte(d, 0x70, tmp & ~4);
+ if(tmp & (1<<7)) {
+ printk("PCI: Disabled enhanced CPU to PCI posting\n");
+ pci_write_config_byte(d, 0x70, tmp & ~(1<<7));
}
}
+static void __init pci_fixup_via691_2(struct pci_dev *d)
+{
+ /*
+ * The VIA bridge corrupts with Posting enabled
+ */
+ u8 tmp;
+
+ pci_read_config_byte(d, 0x40, &tmp);
+ if(tmp & (1<<7)) {
+ printk("PCI: Disabled enhanced CPU to PCI posting #2\n");
+ pci_write_config_byte(d, 0x40, tmp & ~(1<<7));
+ }
+}
+
struct pci_fixup pcibios_fixups[] = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx },
+#if 0
+/* Until we get proper handling pray the BIOS gets it right */
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HE, pci_fixup_serverworks },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE, pci_fixup_serverworks },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CMIC_HE, pci_fixup_serverworks },
+#endif
+#if 0
+/* Our bus code shouldnt need this fixup any more. Delete once verified */
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_6010, pci_fixup_compaq },
+#endif
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, pci_fixup_umc_ide },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash },
{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5598, pci_fixup_latency },
- { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_vt8363 },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, pci_fixup_via_acpi },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, pci_fixup_via_acpi },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_vt8363 },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C691, pci_fixup_via691 },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, pci_fixup_via691_2 },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci_fixup_piix4_acpi },
{ 0 }
};
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index b374f8e99..2065727ae 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -167,8 +167,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if (request == PTRACE_ATTACH) {
if (child == current)
goto out_tsk;
- if ((!child->dumpable ||
- (current->uid != child->euid) ||
+ if(((current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
@@ -176,6 +175,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
+ rmb();
+ if (!child->dumpable && !capable(CAP_SYS_PTRACE))
+ goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 03eeabc2f..9c0033110 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -294,7 +294,7 @@ visws_get_board_type_and_rev(void)
visws_board_rev = raw;
}
- printk("Silicon Graphics %s (rev %d)\n",
+ printk(KERN_INFO "Silicon Graphics %s (rev %d)\n",
visws_board_type == VISWS_320 ? "320" :
(visws_board_type == VISWS_540 ? "540" :
"unknown"),
@@ -401,7 +401,7 @@ void __init add_memory_region(unsigned long long start,
int x = e820.nr_map;
if (x == E820MAX) {
- printk("Ooops! Too many entries in the memory map!\n");
+ printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
return;
}
@@ -418,8 +418,9 @@ static void __init print_memory_map(char *who)
int i;
for (i = 0; i < e820.nr_map; i++) {
- printk(" %s: %016Lx @ %016Lx ", who,
- e820.map[i].size, e820.map[i].addr);
+ printk(" %s: %016Lx - %016Lx ", who,
+ e820.map[i].addr,
+ e820.map[i].addr + e820.map[i].size);
switch (e820.map[i].type) {
case E820_RAM: printk("(usable)\n");
break;
@@ -521,7 +522,7 @@ void __init setup_memory_region(void)
add_memory_region(0, LOWMEMSIZE(), E820_RAM);
add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
}
- printk("BIOS-provided physical RAM map:\n");
+ printk(KERN_INFO "BIOS-provided physical RAM map:\n");
print_memory_map(who);
} /* setup_memory_region */
@@ -591,7 +592,7 @@ static inline void parse_mem_cmdline (char ** cmdline_p)
*to = '\0';
*cmdline_p = command_line;
if (usermem) {
- printk("user-defined physical RAM map:\n");
+ printk(KERN_INFO "user-defined physical RAM map:\n");
print_memory_map("user");
}
}
@@ -798,7 +799,7 @@ void __init setup_arch(char **cmdline_p)
initrd_end = initrd_start+INITRD_SIZE;
}
else {
- printk("initrd extends beyond end of memory "
+ printk(KERN_ERR "initrd extends beyond end of memory "
"(0x%08lx > 0x%08lx)\ndisabling initrd\n",
INITRD_START + INITRD_SIZE,
max_low_pfn << PAGE_SHIFT);
@@ -902,7 +903,7 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
if (n >= 0x80000005) {
cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
- printk("CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
+ printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
c->x86_cache_size=(ecx>>24)+(edx>>24);
}
@@ -926,7 +927,7 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
c->x86_cache_size = l2size;
- printk("CPU: L2 Cache: %dK (%d bytes/line)\n",
+ printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
l2size, ecx & 0xFF);
}
@@ -1339,7 +1340,7 @@ static void __init init_centaur(struct cpuinfo_x86 *c)
name="C6";
fcr_set=ECX8|DSMC|EDCTLB|EMMX|ERETSTK;
fcr_clr=DPDC;
- printk("Disabling bugged TSC.\n");
+ printk(KERN_NOTICE "Disabling bugged TSC.\n");
clear_bit(X86_FEATURE_TSC, &c->x86_capability);
break;
case 8:
@@ -1376,10 +1377,10 @@ static void __init init_centaur(struct cpuinfo_x86 *c)
newlo=(lo|fcr_set) & (~fcr_clr);
if (newlo!=lo) {
- printk("Centaur FCR was 0x%X now 0x%X\n", lo, newlo );
+ printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n", lo, newlo );
wrmsr(0x107, newlo, hi );
} else {
- printk("Centaur FCR is 0x%X\n",lo);
+ printk(KERN_INFO "Centaur FCR is 0x%X\n",lo);
}
/* Emulate MTRRs using Centaur's MCR. */
set_bit(X86_FEATURE_CENTAUR_MCR, &c->x86_capability);
@@ -1432,7 +1433,7 @@ static void __init init_transmeta(struct cpuinfo_x86 *c)
max = cpuid_eax(0x80860000);
if ( max >= 0x80860001 ) {
cpuid(0x80860001, &dummy, &cpu_rev, &cpu_freq, &cpu_flags);
- printk("CPU: Processor revision %u.%u.%u.%u, %u MHz\n",
+ printk(KERN_INFO "CPU: Processor revision %u.%u.%u.%u, %u MHz\n",
(cpu_rev >> 24) & 0xff,
(cpu_rev >> 16) & 0xff,
(cpu_rev >> 8) & 0xff,
@@ -1441,7 +1442,7 @@ static void __init init_transmeta(struct cpuinfo_x86 *c)
}
if ( max >= 0x80860002 ) {
cpuid(0x80860002, &dummy, &cms_rev1, &cms_rev2, &dummy);
- printk("CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n",
+ printk(KERN_INFO "CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n",
(cms_rev1 >> 24) & 0xff,
(cms_rev1 >> 16) & 0xff,
(cms_rev1 >> 8) & 0xff,
@@ -1470,7 +1471,7 @@ static void __init init_transmeta(struct cpuinfo_x86 *c)
(void *)&cpu_info[56],
(void *)&cpu_info[60]);
cpu_info[64] = '\0';
- printk("CPU: %s\n", cpu_info);
+ printk(KERN_INFO "CPU: %s\n", cpu_info);
}
/* Unhide possibly hidden capability flags */
@@ -1502,7 +1503,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
c->f00f_bug = 1;
if ( !f00f_workaround_enabled ) {
trap_init_f00f_bug();
- printk(KERN_INFO "Intel Pentium with F0 0F bug - workaround enabled.\n");
+ printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
f00f_workaround_enabled = 1;
}
}
@@ -1610,12 +1611,12 @@ static void __init init_intel(struct cpuinfo_x86 *c)
}
}
if ( l1i || l1d )
- printk("CPU: L1 I cache: %dK, L1 D cache: %dK\n",
+ printk(KERN_INFO "CPU: L1 I cache: %dK, L1 D cache: %dK\n",
l1i, l1d);
if ( l2 )
- printk("CPU: L2 cache: %dK\n", l2);
+ printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
if ( l3 )
- printk("CPU: L3 cache: %dK\n", l3);
+ printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
/*
* This assumes the L3 cache is shared; it typically lives in
@@ -1785,7 +1786,7 @@ static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
rdmsr(0x119,lo,hi);
lo |= 0x200000;
wrmsr(0x119,lo,hi);
- printk(KERN_INFO "CPU serial number disabled.\n");
+ printk(KERN_NOTICE "CPU serial number disabled.\n");
clear_bit(X86_FEATURE_PN, &c->x86_capability);
}
}
@@ -1976,7 +1977,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
}
}
- printk("CPU: Before vendor init, caps: %08x %08x %08x, vendor = %d\n",
+ printk(KERN_DEBUG "CPU: Before vendor init, caps: %08x %08x %08x, vendor = %d\n",
c->x86_capability[0],
c->x86_capability[1],
c->x86_capability[2],
@@ -2023,7 +2024,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
break;
}
- printk("CPU: After vendor init, caps: %08x %08x %08x %08x\n",
+ printk(KERN_DEBUG "CPU: After vendor init, caps: %08x %08x %08x %08x\n",
c->x86_capability[0],
c->x86_capability[1],
c->x86_capability[2],
@@ -2063,7 +2064,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
/* Now the feature flags better reflect actual CPU features! */
- printk("CPU: After generic, caps: %08x %08x %08x %08x\n",
+ printk(KERN_DEBUG "CPU: After generic, caps: %08x %08x %08x %08x\n",
c->x86_capability[0],
c->x86_capability[1],
c->x86_capability[2],
@@ -2081,7 +2082,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
}
- printk("CPU: Common caps: %08x %08x %08x %08x\n",
+ printk(KERN_DEBUG "CPU: Common caps: %08x %08x %08x %08x\n",
boot_cpu_data.x86_capability[0],
boot_cpu_data.x86_capability[1],
boot_cpu_data.x86_capability[2],
@@ -2249,16 +2250,16 @@ void __init cpu_init (void)
struct tss_struct * t = &init_tss[nr];
if (test_and_set_bit(nr, &cpu_initialized)) {
- printk("CPU#%d already initialized!\n", nr);
+ printk(KERN_WARNING "CPU#%d already initialized!\n", nr);
for (;;) __sti();
}
- printk("Initializing CPU#%d\n", nr);
+ printk(KERN_INFO "Initializing CPU#%d\n", nr);
if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
#ifndef CONFIG_X86_TSC
if (tsc_disable && cpu_has_tsc) {
- printk("Disabling TSC...\n");
+ printk(KERN_NOTICE "Disabling TSC...\n");
/**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/
clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability);
set_in_cr4(X86_CR4_TSD);
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
index 21a941be6..5fd6910b9 100644
--- a/arch/i386/kernel/sys_i386.c
+++ b/arch/i386/kernel/sys_i386.c
@@ -55,9 +55,9 @@ static inline long do_mmap2(
goto out;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 6fa43476a..b8cc4fad4 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -388,7 +388,7 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
#if CONFIG_X86_IO_APIC
-int nmi_watchdog = 1;
+int nmi_watchdog = 0;
static int __init setup_nmi_watchdog(char *str)
{
diff --git a/arch/i386/lib/mmx.c b/arch/i386/lib/mmx.c
index dfbf7ba8e..d9301040b 100644
--- a/arch/i386/lib/mmx.c
+++ b/arch/i386/lib/mmx.c
@@ -3,6 +3,7 @@
#include <linux/sched.h>
#include <asm/i387.h>
+#include <asm/hardirq.h>
/*
* MMX 3DNow! library helper functions
@@ -25,8 +26,14 @@
void *_mmx_memcpy(void *to, const void *from, size_t len)
{
- void *p=to;
- int i= len >> 6; /* len/64 */
+ void *p;
+ int i;
+
+ if (in_interrupt())
+ return __memcpy(to, from, len);
+
+ p = to;
+ i = len >> 6; /* len/64 */
kernel_fpu_begin();
diff --git a/arch/i386/mm/extable.c b/arch/i386/mm/extable.c
index 2eb7ca6aa..223d05af4 100644
--- a/arch/i386/mm/extable.c
+++ b/arch/i386/mm/extable.c
@@ -49,7 +49,7 @@ search_exception_table(unsigned long addr)
spin_lock_irqsave(&modlist_lock, flags);
for (mp = module_list; mp != NULL; mp = mp->next) {
- if (mp->ex_table_start == NULL)
+ if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index ccbc5dce1..18ae8b950 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -141,7 +141,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
if (in_interrupt() || !mm)
goto no_context;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
@@ -214,7 +214,7 @@ good_area:
if (bit < 32)
tsk->thread.screen_bitmap |= 1 << bit;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
/*
@@ -222,7 +222,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
bad_area_nosemaphore:
/* User mode accesses just cause a SIGSEGV */
@@ -290,14 +290,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (error_code & 4)
do_exit(SIGKILL);
goto no_context;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/*
* Send a sigbus, regardless of whether we were in kernel
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 6414b508c..202a42b69 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -40,132 +40,23 @@ unsigned long highstart_pfn, highend_pfn;
static unsigned long totalram_pages;
static unsigned long totalhigh_pages;
-/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving an inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- *
- * ZERO_PAGE is a special page that is used for zero-initialized
- * data and COW.
- */
-
-/*
- * These are allocated in head.S so that we get proper page alignment.
- * If you change the size of these then change head.S as well.
- */
-extern char empty_bad_page[PAGE_SIZE];
-#if CONFIG_X86_PAE
-extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD];
-#endif
-extern pte_t empty_bad_pte_table[PTRS_PER_PTE];
-
-/*
- * We init them before every return and make them writable-shared.
- * This guarantees we get out of the kernel in some more or less sane
- * way.
- */
-#if CONFIG_X86_PAE
-static pmd_t * get_bad_pmd_table(void)
-{
- pmd_t v;
- int i;
-
- set_pmd(&v, __pmd(_PAGE_TABLE + __pa(empty_bad_pte_table)));
-
- for (i = 0; i < PAGE_SIZE/sizeof(pmd_t); i++)
- empty_bad_pmd_table[i] = v;
-
- return empty_bad_pmd_table;
-}
-#endif
-
-static pte_t * get_bad_pte_table(void)
-{
- pte_t v;
- int i;
-
- v = pte_mkdirty(mk_pte_phys(__pa(empty_bad_page), PAGE_SHARED));
-
- for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++)
- empty_bad_pte_table[i] = v;
-
- return empty_bad_pte_table;
-}
-
-
-
-void __handle_bad_pmd(pmd_t *pmd)
-{
- pmd_ERROR(*pmd);
- set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(get_bad_pte_table())));
-}
-
-void __handle_bad_pmd_kernel(pmd_t *pmd)
-{
- pmd_ERROR(*pmd);
- set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table())));
-}
-
-pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
-{
- pte_t *pte;
-
- pte = (pte_t *) __get_free_page(GFP_KERNEL);
- if (pmd_none(*pmd)) {
- if (pte) {
- clear_page(pte);
- set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
- return pte + offset;
- }
- set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table())));
- return NULL;
- }
- free_page((unsigned long)pte);
- if (pmd_bad(*pmd)) {
- __handle_bad_pmd_kernel(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
-{
- unsigned long pte;
-
- pte = (unsigned long) __get_free_page(GFP_KERNEL);
- if (pmd_none(*pmd)) {
- if (pte) {
- clear_page((void *)pte);
- set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));
- return (pte_t *)pte + offset;
- }
- set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(get_bad_pte_table())));
- return NULL;
- }
- free_page(pte);
- if (pmd_bad(*pmd)) {
- __handle_bad_pmd(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + offset;
-}
-
int do_check_pgt_cache(int low, int high)
{
int freed = 0;
if(pgtable_cache_size > high) {
do {
- if(pgd_quicklist)
- free_pgd_slow(get_pgd_fast()), freed++;
- if(pmd_quicklist)
- free_pmd_slow(get_pmd_fast()), freed++;
- if(pte_quicklist)
- free_pte_slow(get_pte_fast()), freed++;
+ if (pgd_quicklist) {
+ free_pgd_slow(get_pgd_fast());
+ freed++;
+ }
+ if (pmd_quicklist) {
+ pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
+ freed++;
+ }
+ if (pte_quicklist) {
+ pte_free_slow(pte_alloc_one_fast(NULL, 0));
+ freed++;
+ }
} while(pgtable_cache_size > low);
}
return freed;
@@ -327,10 +218,8 @@ static void __init pagetable_init (void)
pgd_base = swapper_pg_dir;
#if CONFIG_X86_PAE
- for (i = 0; i < PTRS_PER_PGD; i++) {
- pgd = pgd_base + i;
- __pgd_clear(pgd);
- }
+ for (i = 0; i < PTRS_PER_PGD; i++)
+ set_pgd(pgd_base + i, __pgd(1 + __pa(empty_zero_page)));
#endif
i = __pgd_offset(PAGE_OFFSET);
pgd = pgd_base + i;
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index bb72da8c8..55b8b3fcf 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -49,7 +49,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
if (address >= end)
BUG();
do {
- pte_t * pte = pte_alloc_kernel(pmd, address);
+ pte_t * pte = pte_alloc(&init_mm, pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -62,6 +62,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
static int remap_area_pages(unsigned long address, unsigned long phys_addr,
unsigned long size, unsigned long flags)
{
+ int error;
pgd_t * dir;
unsigned long end = address + size;
@@ -70,19 +71,23 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr,
flush_cache_all();
if (address >= end)
BUG();
+ spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
- pmd = pmd_alloc_kernel(dir, address);
+ pmd = pmd_alloc(&init_mm, dir, address);
+ error = -ENOMEM;
if (!pmd)
- return -ENOMEM;
+ break;
if (remap_area_pmd(pmd, address, end - address,
phys_addr + address, flags))
- return -ENOMEM;
+ break;
+ error = 0;
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
+ spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
- return 0;
+ return error;
}
/*
diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index aab0db860..8ae1e84e6 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -204,7 +204,6 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm)
for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
if (bprm->page[i]) {
- current->mm->rss++;
put_dirty_page(current,bprm->page[i],stack_base);
}
stack_base += PAGE_SIZE;
@@ -260,11 +259,11 @@ elf_map32 (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int p
# define IA32_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
# define IA32_PAGEALIGN(_v) (((_v) + ELF_EXEC_PAGESIZE - 1) & ~(ELF_EXEC_PAGESIZE - 1))
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
retval = ia32_do_mmap(filep, IA32_PAGESTART(addr),
eppnt->p_filesz + IA32_PAGEOFFSET(eppnt->p_vaddr), prot, type,
eppnt->p_offset - IA32_PAGEOFFSET(eppnt->p_vaddr));
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
#endif
return retval;
}
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 555c6097e..425e8f5ac 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -120,12 +120,12 @@ int stack)
* `execve' frees all current memory we only have to do an
* `munmap' if the `execve' failes.
*/
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
av = (char **) do_mmap_pgoff(0, 0UL, len, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (IS_ERR(av))
return (long)av;
@@ -247,9 +247,9 @@ do_mmap_fake(struct file *file, unsigned long addr, unsigned long len,
back = kmalloc(PAGE_SIZE - ((addr + len) & ~PAGE_MASK), GFP_KERNEL);
__copy_user(back, (char *)addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
r = do_mmap(0, baddr, len + (addr - baddr), prot, flags | MAP_ANONYMOUS, 0);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (r < 0)
return(r);
if (addr == 0)
@@ -293,9 +293,9 @@ ia32_do_mmap (struct file *file, unsigned int addr, unsigned int len, unsigned i
poff = offset & PAGE_MASK;
len += offset - poff;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, poff >> PAGE_SHIFT);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (!IS_ERR((void *) error))
error += offset - poff;
@@ -2573,7 +2573,7 @@ sys_iopl (int level, long arg1, long arg2, long arg3)
return(-EFAULT);
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
lock_kernel();
addr = do_mmap_pgoff(file, IA32_IOBASE,
@@ -2581,7 +2581,7 @@ sys_iopl (int level, long arg1, long arg2, long arg3)
(ia64_iobase & ~PAGE_OFFSET) >> PAGE_SHIFT);
unlock_kernel();
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (addr >= 0) {
__asm__ __volatile__("mov ar.k0=%0 ;;" :: "r"(addr));
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index 2713d7fd9..8cf1b3aa6 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -102,7 +102,7 @@ ia64_brk (unsigned long brk, long arg1, long arg2, long arg3,
* check and the clearing of r8. However, we can't call sys_brk() because we need
* to acquire the mmap_sem before we can do the test...
*/
- down(&mm->mmap_sem);
+ down_write(&mm->mmap_sem);
if (brk < mm->end_code)
goto out;
@@ -142,7 +142,7 @@ set_brk:
mm->brk = brk;
out:
retval = mm->brk;
- up(&mm->mmap_sem);
+ up_write(&mm->mmap_sem);
regs->r8 = 0; /* ensure large retval isn't mistaken as error code */
return retval;
}
@@ -200,9 +200,9 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un
if (flags & MAP_SHARED)
current->thread.flags |= IA64_THREAD_MAP_SHARED;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
current->thread.flags &= ~IA64_THREAD_MAP_SHARED;
diff --git a/arch/ia64/lib/copy_user.S b/arch/ia64/lib/copy_user.S
index ec9e2bf0a..135158d7a 100644
--- a/arch/ia64/lib/copy_user.S
+++ b/arch/ia64/lib/copy_user.S
@@ -16,7 +16,7 @@
* in2 number of bytes to copy
*
* Outputs:
- * ret0 0 in case of sucess. The number of bytes NOT copied in
+ * ret0 0 in case of success. The number of bytes NOT copied in
* case of error.
*
* Copyright (C) 2000 Hewlett-Packard Co
diff --git a/arch/ia64/lib/strlen.S b/arch/ia64/lib/strlen.S
index fbc786b41..3e7dd1e16 100644
--- a/arch/ia64/lib/strlen.S
+++ b/arch/ia64/lib/strlen.S
@@ -198,5 +198,5 @@ recover:
;;
sub ret0=ret0,tmp // length=now - back -1
mov ar.pfs=saved_pfs // because of ar.ec, restore no matter what
- br.ret.sptk.few rp // end of sucessful recovery code
+ br.ret.sptk.few rp // end of successful recovery code
END(strlen)
diff --git a/arch/ia64/lib/strlen_user.S b/arch/ia64/lib/strlen_user.S
index 7f222bb13..4f3715d55 100644
--- a/arch/ia64/lib/strlen_user.S
+++ b/arch/ia64/lib/strlen_user.S
@@ -204,7 +204,7 @@ recover:
;;
sub ret0=ret0,tmp // length=now - back -1
mov ar.pfs=saved_pfs // because of ar.ec, restore no matter what
- br.ret.sptk.few rp // end of sucessful recovery code
+ br.ret.sptk.few rp // end of successful recovery code
//
// We failed even on the normal load (called from exception handler)
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 1a2438917..6f0b8f28b 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -60,7 +60,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
if (in_interrupt() || !mm)
goto no_context;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma_prev(mm, address, &prev_vma);
if (!vma)
@@ -112,7 +112,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
default:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
check_expansion:
@@ -135,7 +135,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
goto good_area;
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
if (isr & IA64_ISR_SP) {
/*
* This fault was due to a speculative load set the "ed" bit in the psr to
@@ -185,7 +185,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
return;
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", current->comm);
if (user_mode(regs))
do_exit(SIGKILL);
diff --git a/arch/ia64/sn/io/l1.c b/arch/ia64/sn/io/l1.c
index 6f4bf9f47..2bd1edc0a 100644
--- a/arch/ia64/sn/io/l1.c
+++ b/arch/ia64/sn/io/l1.c
@@ -2788,7 +2788,7 @@ _elscuart_getc( l1sc_t *sc )
while( (r = _elscuart_poll( sc )) == 0 );
if( r < 0 ) {
- /* some error occured */
+ /* some error occurred */
return r;
}
diff --git a/arch/ia64/sn/io/pcibr.c b/arch/ia64/sn/io/pcibr.c
index 9c71b8569..6a3409b89 100644
--- a/arch/ia64/sn/io/pcibr.c
+++ b/arch/ia64/sn/io/pcibr.c
@@ -3925,7 +3925,7 @@ pcibr_attach(devfs_handle_t xconn_vhdl)
* above.
*
* Need to set the D_INTR_ISERR flag
- * in the dev_desc used for alocating the
+ * in the dev_desc used for allocating the
* error interrupt, so our interrupt will
* be properly routed and prioritized.
*
@@ -5540,7 +5540,7 @@ pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap,
} else
xio_port = pcibr_dmamap->bd_xio_port;
- /* If this DMA is to an addres that
+ /* If this DMA is to an address that
* refers back to this Bridge chip,
* reduce it back to the correct
* PCI MEM address.
@@ -8540,7 +8540,7 @@ pcibr_pioerror(
*
* CAUTION: Resetting bit BRIDGE_IRR_PCI_GRP_CLR, acknowledges
* a group of interrupts. If while handling this error,
- * some other error has occured, that would be
+ * some other error has occurred, that would be
* implicitly cleared by this write.
* Need a way to ensure we don't inadvertently clear some
* other errors.
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
index d46ba0852..0f5c012c3 100644
--- a/arch/m68k/apollo/dn_ints.c
+++ b/arch/m68k/apollo/dn_ints.c
@@ -24,7 +24,7 @@ void dn_process_int(int irq, struct pt_regs *fp) {
dn_irqs[irq-160].handler(irq,dn_irqs[irq-160].dev_id,fp);
}
else {
- printk("spurious irq %d occured\n",irq);
+ printk("spurious irq %d occurred\n",irq);
}
*(volatile unsigned char *)(pica)=0x20;
diff --git a/arch/m68k/ifpsp060/src/fpsp.S b/arch/m68k/ifpsp060/src/fpsp.S
index 400d556c1..d3c78c8c0 100644
--- a/arch/m68k/ifpsp060/src/fpsp.S
+++ b/arch/m68k/ifpsp060/src/fpsp.S
@@ -23523,7 +23523,7 @@ no_exc:
# in INEX2. #
# #
# A10. Or in INEX. #
-# If INEX is set, round error occured. This is #
+# If INEX is set, round error occurred. This is #
# compensated for by 'or-ing' in the INEX2 flag to #
# the lsb of Y. #
# #
@@ -23989,7 +23989,7 @@ A9_con:
fmul.x %fp1,%fp0 # calculate X * SCALE -> Y to fp0
# A10. Or in INEX.
-# If INEX is set, round error occured. This is compensated
+# If INEX is set, round error occurred. This is compensated
# for by 'or-ing' in the INEX2 flag to the lsb of Y.
#
# Register usage:
diff --git a/arch/m68k/ifpsp060/src/ilsp.S b/arch/m68k/ifpsp060/src/ilsp.S
index cd09bc7b9..43d220fc4 100644
--- a/arch/m68k/ifpsp060/src/ilsp.S
+++ b/arch/m68k/ifpsp060/src/ilsp.S
@@ -514,7 +514,7 @@ _060LSP__imulu64_:
# fmovm.l &0x0,-(%sp) # save no fpregs
# PROLOGUE END ##########################################################
- mov.w %cc,MUL64_CC(%a6) # save incomming ccodes
+ mov.w %cc,MUL64_CC(%a6) # save incoming ccodes
mov.l 0x8(%a6),%d0 # store multiplier in d0
beq.w mulu64_zero # handle zero separately
@@ -625,7 +625,7 @@ _060LSP__imuls64_:
# fmovm.l &0x0,-(%sp) # save no fpregs
# PROLOGUE END ##########################################################
- mov.w %cc,MUL64_CC(%a6) # save incomming ccodes
+ mov.w %cc,MUL64_CC(%a6) # save incoming ccodes
mov.l 0x8(%a6),%d0 # store multiplier in d0
beq.b mulu64_zero # handle zero separately
diff --git a/arch/m68k/ifpsp060/src/isp.S b/arch/m68k/ifpsp060/src/isp.S
index f779e2c8f..2dc40bbc2 100644
--- a/arch/m68k/ifpsp060/src/isp.S
+++ b/arch/m68k/ifpsp060/src/isp.S
@@ -3835,7 +3835,7 @@ CAS2W2_FILLER:
# assert LOCKE* for the final write operation. #
# (13)Exit. #
# #
-# The algorithm is actually implemented slightly diferently #
+# The algorithm is actually implemented slightly differently #
# depending on the size of the operation and the misalignment of the #
# operand. A misaligned operand must be written in aligned chunks or #
# else the BUSCR register control gets confused. #
diff --git a/arch/m68k/ifpsp060/src/pfpsp.S b/arch/m68k/ifpsp060/src/pfpsp.S
index d175f7af0..21d2c507d 100644
--- a/arch/m68k/ifpsp060/src/pfpsp.S
+++ b/arch/m68k/ifpsp060/src/pfpsp.S
@@ -13483,7 +13483,7 @@ no_exc:
# in INEX2. #
# #
# A10. Or in INEX. #
-# If INEX is set, round error occured. This is #
+# If INEX is set, round error occurred. This is #
# compensated for by 'or-ing' in the INEX2 flag to #
# the lsb of Y. #
# #
@@ -13949,7 +13949,7 @@ A9_con:
fmul.x %fp1,%fp0 # calculate X * SCALE -> Y to fp0
# A10. Or in INEX.
-# If INEX is set, round error occured. This is compensated
+# If INEX is set, round error occurred. This is compensated
# for by 'or-ing' in the INEX2 flag to the lsb of Y.
#
# Register usage:
diff --git a/arch/m68k/kernel/bios32.c b/arch/m68k/kernel/bios32.c
index d9cf9d9b8..a70bb6b89 100644
--- a/arch/m68k/kernel/bios32.c
+++ b/arch/m68k/kernel/bios32.c
@@ -444,7 +444,7 @@ static void __init pcibios_claim_resources(struct pci_bus *bus)
* dev - device.
* i - resource.
*
- * Result: 0 if successfull.
+ * Result: 0 if successful.
*/
int __init pcibios_assign_resource(struct pci_dev *dev, int i)
diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S
index 461bf9c9b..9f385103a 100644
--- a/arch/m68k/kernel/head.S
+++ b/arch/m68k/kernel/head.S
@@ -840,7 +840,7 @@ L(getvmetype):
#ifdef CONFIG_MVME16x
is_not_mvme16x(L(gvtdone))
- /* Need to get the BRD_ID info to diferentiate between 162, 167,
+ /* Need to get the BRD_ID info to differentiate between 162, 167,
* etc. This is available as a BI_VME_BRDINFO tag with later
* versions of VMELILO and TFTPLILO, otherwise we call the Bug.
*/
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index 805ce9b83..240bb3c7c 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -184,7 +184,7 @@ void sys_free_irq(unsigned int irq, void *dev_id)
/*
* Do we need these probe functions on the m68k?
*
- * ... may be usefull with ISA devices
+ * ... may be useful with ISA devices
*/
unsigned long probe_irq_on (void)
{
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index f7386cbc6..3d3f94062 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -59,9 +59,9 @@ static inline long do_mmap2(
goto out;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
@@ -146,9 +146,9 @@ asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
}
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
out:
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index bc27a1722..bbea6ea2d 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -101,7 +101,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
if (in_interrupt() || !mm)
goto no_context;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
@@ -168,7 +168,7 @@ good_area:
#warning should be obsolete now...
if (CPU_IS_040_OR_060)
flush_tlb_page(vma, address);
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return 0;
/*
@@ -203,6 +203,6 @@ acc_err:
current->thread.faddr = address;
send_sig:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return send_fault_sig(regs);
}
diff --git a/arch/m68k/q40/README b/arch/m68k/q40/README
index b61ee9c6a..8c93eb160 100644
--- a/arch/m68k/q40/README
+++ b/arch/m68k/q40/README
@@ -127,7 +127,7 @@ problems, email me idealy this:
- exact keypress/release sequence
- 'showkey -s' run on q40, non-X session
- 'showkey -s' run on a PC, non-X session
- - AT codes as displayed by the q40 debuging ROM
+ - AT codes as displayed by the q40 debugging ROM
btw if the showkey output from PC and Q40 doesn't differ then you have some
classic configuration problem - don't send me anything in this case
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
index 294765dd2..1063bf5e5 100644
--- a/arch/m68k/q40/config.c
+++ b/arch/m68k/q40/config.c
@@ -238,7 +238,7 @@ void __init config_q40(void)
mach_max_dma_address = 32*1024*1024; /* no DMA at all, but ide-scsi requires it.. */
-/* userfull for early debuging stages writes kernel messages into SRAM */
+/* userfull for early debugging stages writes kernel messages into SRAM */
if (!strncmp( m68k_debug_device,"mem",3 ))
{
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 7fb774003..fc2f0a391 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -206,6 +206,7 @@ CONFIG_SGIWD93_SCSI=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
diff --git a/arch/mips/defconfig-atlas b/arch/mips/defconfig-atlas
index 70cfecd43..ba8632bd9 100644
--- a/arch/mips/defconfig-atlas
+++ b/arch/mips/defconfig-atlas
@@ -206,6 +206,7 @@ CONFIG_SD_EXTRA_DEVS=40
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
diff --git a/arch/mips/defconfig-ddb5476 b/arch/mips/defconfig-ddb5476
index d8e786b14..4e821708a 100644
--- a/arch/mips/defconfig-ddb5476
+++ b/arch/mips/defconfig-ddb5476
@@ -305,7 +305,9 @@ CONFIG_NE2K_PCI=y
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
# CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
diff --git a/arch/mips/defconfig-decstation b/arch/mips/defconfig-decstation
index 7d19c59db..f6ac3193d 100644
--- a/arch/mips/defconfig-decstation
+++ b/arch/mips/defconfig-decstation
@@ -199,6 +199,7 @@ CONFIG_SCSI_DECNCR=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
diff --git a/arch/mips/defconfig-ev64120 b/arch/mips/defconfig-ev64120
index e2487dd19..aa209c1e1 100644
--- a/arch/mips/defconfig-ev64120
+++ b/arch/mips/defconfig-ev64120
@@ -238,7 +238,9 @@ CONFIG_NE2K_PCI=y
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
# CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
diff --git a/arch/mips/defconfig-ev96100 b/arch/mips/defconfig-ev96100
index b112acd86..d3300ed4a 100644
--- a/arch/mips/defconfig-ev96100
+++ b/arch/mips/defconfig-ev96100
@@ -235,7 +235,9 @@ CONFIG_TULIP=y
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
# CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22
index 7fb774003..fc2f0a391 100644
--- a/arch/mips/defconfig-ip22
+++ b/arch/mips/defconfig-ip22
@@ -206,6 +206,7 @@ CONFIG_SGIWD93_SCSI=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
diff --git a/arch/mips/defconfig-it8172 b/arch/mips/defconfig-it8172
index 59330e6ce..3881cd44f 100644
--- a/arch/mips/defconfig-it8172
+++ b/arch/mips/defconfig-it8172
@@ -365,7 +365,9 @@ CONFIG_TULIP=y
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
CONFIG_8139TOO=y
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
diff --git a/arch/mips/defconfig-malta b/arch/mips/defconfig-malta
index 01fe15970..1e02a2837 100644
--- a/arch/mips/defconfig-malta
+++ b/arch/mips/defconfig-malta
@@ -205,6 +205,7 @@ CONFIG_SD_EXTRA_DEVS=40
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
@@ -294,7 +295,9 @@ CONFIG_PCNET32=y
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
# CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
diff --git a/arch/mips/defconfig-ocelot b/arch/mips/defconfig-ocelot
index c93bb6685..22f0adcf7 100644
--- a/arch/mips/defconfig-ocelot
+++ b/arch/mips/defconfig-ocelot
@@ -232,7 +232,9 @@ CONFIG_EEPRO100=y
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
# CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 8daf876c1..684e435fc 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -314,12 +314,12 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
(unsigned long) elf_prot, (unsigned long) elf_type,
(unsigned long) (eppnt->p_offset & 0xfffff000));
#endif
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(interpreter, vaddr,
eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
elf_prot, elf_type,
eppnt->p_offset & 0xfffff000);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if(error < 0 && error > -1024) {
printk("Aieee IRIX interp mmap error=%d\n", error);
@@ -498,12 +498,12 @@ static inline void map_executable(struct file *fp, struct elf_phdr *epp, int pnu
prot = (epp->p_flags & PF_R) ? PROT_READ : 0;
prot |= (epp->p_flags & PF_W) ? PROT_WRITE : 0;
prot |= (epp->p_flags & PF_X) ? PROT_EXEC : 0;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
(void) do_mmap(fp, (epp->p_vaddr & 0xfffff000),
(epp->p_filesz + (epp->p_vaddr & 0xfff)),
prot, EXEC_MAP_FLAGS,
(epp->p_offset & 0xfffff000));
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
/* Fixup location tracking vars. */
if((epp->p_vaddr & 0xfffff000) < *estack)
@@ -762,10 +762,10 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
* Since we do not have the power to recompile these, we
* emulate the SVr4 behavior. Sigh.
*/
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
(void) do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, 0);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
#endif
start_thread(regs, elf_entry, bprm->p);
@@ -837,14 +837,14 @@ static int load_irix_library(struct file *file)
while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
/* Now use mmap to map the library into memory. */
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(file,
elf_phdata->p_vaddr & 0xfffff000,
elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
elf_phdata->p_offset & 0xfffff000);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
if (k > elf_bss) elf_bss = k;
@@ -916,12 +916,12 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
prot = (hp->p_flags & PF_R) ? PROT_READ : 0;
prot |= (hp->p_flags & PF_W) ? PROT_WRITE : 0;
prot |= (hp->p_flags & PF_X) ? PROT_EXEC : 0;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
retval = do_mmap(filp, (hp->p_vaddr & 0xfffff000),
(hp->p_filesz + (hp->p_vaddr & 0xfff)),
prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
(hp->p_offset & 0xfffff000));
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if(retval != (hp->p_vaddr & 0xfffff000)) {
printk("irix_mapelf: do_mmap fails with %d!\n", retval);
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 229ce8d12..0a8f79664 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -69,9 +69,9 @@ do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
goto out;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index ab051858e..18ec04e23 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -471,7 +471,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
if (retval)
return retval;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
pgdp = pgd_offset(mm, addr);
pmdp = pmd_offset(pgdp, addr);
ptep = pte_offset(pmdp, addr);
@@ -484,7 +484,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
PAGE_SHIFT, pageno);
}
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
break;
}
@@ -534,7 +534,7 @@ asmlinkage int irix_brk(unsigned long brk)
struct mm_struct *mm = current->mm;
int ret;
- down(&mm->mmap_sem);
+ down_write(&mm->mmap_sem);
if (brk < mm->end_code) {
ret = -ENOMEM;
goto out;
@@ -592,7 +592,7 @@ asmlinkage int irix_brk(unsigned long brk)
ret = 0;
out:
- up(&mm->mmap_sem);
+ up_write(&mm->mmap_sem);
return ret;
}
@@ -1082,9 +1082,9 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
retval = do_mmap(file, addr, len, prot, flags, offset);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
@@ -1642,9 +1642,9 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
diff --git a/arch/mips/mm/extable.c b/arch/mips/mm/extable.c
index e563e8267..4c2cf3b43 100644
--- a/arch/mips/mm/extable.c
+++ b/arch/mips/mm/extable.c
@@ -49,7 +49,7 @@ search_exception_table(unsigned long addr)
spin_lock_irqsave(&modlist_lock, flags);
for (mp = module_list; mp != NULL; mp = mp->next) {
- if (mp->ex_table_start == NULL)
+ if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index ed3d2a2ac..6820df7c5 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -72,7 +72,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid,
address, write, regs->cp0_epc);
#endif
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
@@ -115,7 +115,7 @@ good_area:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
/*
@@ -123,7 +123,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
bad_area_nosemaphore:
/* User mode accesses just cause a SIGSEGV */
@@ -177,14 +177,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (user_mode(regs))
do_exit(SIGKILL);
goto no_context;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/*
* Send a sigbus, regardless of whether we were in kernel
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 7fa5c9582..8d6c9a9f2 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -5,15 +5,10 @@
*
* Copyright (C) 1994 - 2000 by Ralf Baechle
* Copyright (C) 2000 Silicon Graphics, Inc.
- */
-/**************************************************************************
- * 9 Nov, 2000.
- * Use mips_cpu structure.
*
- * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- *************************************************************************/
-
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ */
#include <linux/config.h>
#include <linux/init.h>
#include <linux/signal.h>
@@ -52,63 +47,6 @@ static unsigned long totalram_pages;
extern void prom_free_prom_memory(void);
-void __bad_pte_kernel(pmd_t *pmd)
-{
- printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
- pmd_set(pmd, BAD_PAGETABLE);
-}
-
-void __bad_pte(pmd_t *pmd)
-{
- printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
- pmd_set(pmd, BAD_PAGETABLE);
-}
-
-pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
-{
- pte_t *page;
-
- page = (pte_t *) __get_free_page(GFP_USER);
- if (pmd_none(*pmd)) {
- if (page) {
- clear_page(page);
- pmd_val(*pmd) = (unsigned long)page;
- return page + offset;
- }
- pmd_set(pmd, BAD_PAGETABLE);
- return NULL;
- }
- free_page((unsigned long)page);
- if (pmd_bad(*pmd)) {
- __bad_pte_kernel(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
-{
- pte_t *page;
-
- page = (pte_t *) __get_free_page(GFP_KERNEL);
- if (pmd_none(*pmd)) {
- if (page) {
- clear_page(page);
- pmd_val(*pmd) = (unsigned long)page;
- return page + offset;
- }
- pmd_set(pmd, BAD_PAGETABLE);
- return NULL;
- }
- free_page((unsigned long)page);
- if (pmd_bad(*pmd)) {
- __bad_pte(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-
asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
{
/* This should flush more selectivly ... */
@@ -170,48 +108,6 @@ int do_check_pgt_cache(int low, int high)
return freed;
}
-/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving a inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- *
- * ZERO_PAGE is a special page that is used for zero-initialized
- * data and COW.
- */
-pte_t * __bad_pagetable(void)
-{
- extern char empty_bad_page_table[PAGE_SIZE];
- unsigned long page, dummy1, dummy2;
-
- page = (unsigned long) empty_bad_page_table;
- __asm__ __volatile__(
- ".set\tnoreorder\n"
- "1:\tsw\t%2,(%0)\n\t"
- "subu\t%1,1\n\t"
- "bnez\t%1,1b\n\t"
- "addiu\t%0,4\n\t"
- ".set\treorder"
- :"=r" (dummy1), "=r" (dummy2)
- :"r" (pte_val(BAD_PAGE)), "0" (page), "1" (PAGE_SIZE/4)
- :"$1");
-
- return (pte_t *)page;
-}
-
-pte_t __bad_page(void)
-{
- extern char empty_bad_page[PAGE_SIZE];
- unsigned long page = (unsigned long) empty_bad_page;
-
- clear_page((void *)page);
- return pte_mkdirty(mk_pte_phys(__pa(page), PAGE_SHARED));
-}
-
void show_mem(void)
{
int i, free = 0, total = 0, reserved = 0;
diff --git a/arch/mips/mm/umap.c b/arch/mips/mm/umap.c
index c952004c9..100cb148d 100644
--- a/arch/mips/mm/umap.c
+++ b/arch/mips/mm/umap.c
@@ -93,7 +93,7 @@ remove_mapping (struct task_struct *task, unsigned long start, unsigned long end
unsigned long beg = start;
pgd_t *dir;
- down (&task->mm->mmap_sem);
+ down_write (&task->mm->mmap_sem);
dir = pgd_offset (task->mm, start);
flush_cache_range (task->mm, beg, end);
while (start < end){
@@ -102,7 +102,7 @@ remove_mapping (struct task_struct *task, unsigned long start, unsigned long end
dir++;
}
flush_tlb_range (task->mm, beg, end);
- up (&task->mm->mmap_sem);
+ up_write (&task->mm->mmap_sem);
}
EXPORT_SYMBOL(remove_mapping);
@@ -181,7 +181,7 @@ vmap_pmd_range (pmd_t *pmd, unsigned long address, unsigned long size, unsigned
end = PGDIR_SIZE;
vaddr -= address;
do {
- pte_t * pte = pte_alloc(pmd, address);
+ pte_t * pte = pte_alloc(current->mm, pmd, address);
if (!pte)
return -ENOMEM;
vmap_pte_range(pte, address, end - address, address + vaddr);
@@ -203,7 +203,7 @@ vmap_page_range (unsigned long from, unsigned long size, unsigned long vaddr)
dir = pgd_offset(current->mm, from);
flush_cache_range(current->mm, beg, end);
while (from < end) {
- pmd_t *pmd = pmd_alloc(dir, from);
+ pmd_t *pmd = pmd_alloc(current->mm, dir, from);
error = -ENOMEM;
if (!pmd)
break;
diff --git a/arch/mips/sgi/kernel/setup.c b/arch/mips/sgi/kernel/setup.c
index 09a291844..898e242bf 100644
--- a/arch/mips/sgi/kernel/setup.c
+++ b/arch/mips/sgi/kernel/setup.c
@@ -152,14 +152,16 @@ static unsigned long dosample(volatile unsigned char *tcwp,
ct1 = read_32bit_cp0_register(CP0_COUNT);
} while(msb);
- /* Stop the counter. */
- *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST);
+ /* Stop the counter. */
+ *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST);
- /* Return the difference, this is how far the r4k counter increments
- * for every 1/HZ seconds. We round off the nearest 1 MHz of
- * master clock (= 1000000 / 100 / 2 = 5000 count).
- */
- return ((ct1 - ct0) / 5000) * 5000;
+ /*
+ * Return the difference, this is how far the r4k counter increments
+ * for every 1/HZ seconds. We round off the nearest 1 MHz of master
+ * clock (= 1000000 / 100 / 2 = 5000 count).
+ */
+
+ return ((ct1 - ct0) / 5000) * 5000;
}
#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig
index f6c37c426..6d73c9fae 100644
--- a/arch/mips64/defconfig
+++ b/arch/mips64/defconfig
@@ -176,6 +176,7 @@ CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22
index 8e182f626..b457a1d82 100644
--- a/arch/mips64/defconfig-ip22
+++ b/arch/mips64/defconfig-ip22
@@ -185,6 +185,7 @@ CONFIG_SGIWD93_SCSI=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27
index f6c37c426..6d73c9fae 100644
--- a/arch/mips64/defconfig-ip27
+++ b/arch/mips64/defconfig-ip27
@@ -176,6 +176,7 @@ CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
diff --git a/arch/mips64/kernel/head.S b/arch/mips64/kernel/head.S
index e9e35aa20..0ed458b80 100644
--- a/arch/mips64/kernel/head.S
+++ b/arch/mips64/kernel/head.S
@@ -176,8 +176,6 @@ NESTED(bootstrap, 16, sp)
page swapper_pg_dir, 1
page invalid_pte_table, 0
page invalid_pmd_table, 1
- page empty_bad_page_table, 0
- page empty_bad_pmd_table, 1
page kptbl, KPTBL_PAGE_ORDER
.globl ekptbl
page kpmdtbl, 0
diff --git a/arch/mips64/kernel/linux32.c b/arch/mips64/kernel/linux32.c
index f1a6084e5..206f09377 100644
--- a/arch/mips64/kernel/linux32.c
+++ b/arch/mips64/kernel/linux32.c
@@ -443,10 +443,10 @@ sys32_execve(abi64_no_regargs, struct pt_regs regs)
* `execve' frees all current memory we only have to do an
* `munmap' if the `execve' failes.
*/
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
av = (char **) do_mmap_pgoff(0, 0, len, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (IS_ERR(av))
return (long) av;
@@ -742,7 +742,9 @@ sys32_getrusage(int who, struct rusage32 *ru)
set_fs (KERNEL_DS);
ret = sys_getrusage(who, &r);
set_fs (old_fs);
- if (put_rusage (ru, &r)) return -EFAULT;
+ if (put_rusage (ru, &r))
+ return -EFAULT;
+
return ret;
}
@@ -752,7 +754,6 @@ get_tv32(struct timeval *o, struct timeval32 *i)
return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
(__get_user(o->tv_sec, &i->tv_sec) |
__get_user(o->tv_usec, &i->tv_usec)));
- return ENOSYS;
}
static inline long
@@ -763,7 +764,6 @@ get_it32(struct itimerval *o, struct itimerval32 *i)
__get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
__get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
__get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
- return ENOSYS;
}
static inline long
@@ -777,12 +777,11 @@ put_tv32(struct timeval32 *o, struct timeval *i)
static inline long
put_it32(struct itimerval32 *o, struct itimerval *i)
{
- return (!access_ok(VERIFY_WRITE, i, sizeof(*i)) ||
+ return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
__put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
__put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
__put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
- return ENOSYS;
}
extern int do_getitimer(int which, struct itimerval *value);
@@ -839,6 +838,7 @@ sys32_alarm(unsigned int seconds)
/* And we'd better return too much than too little anyway */
if (it_old.it_value.tv_usec)
oldalarm++;
+
return oldalarm;
}
diff --git a/arch/mips64/kernel/syscall.c b/arch/mips64/kernel/syscall.c
index 8b36b6e5e..a5694b3fc 100644
--- a/arch/mips64/kernel/syscall.c
+++ b/arch/mips64/kernel/syscall.c
@@ -64,9 +64,9 @@ sys_mmap(unsigned long addr, size_t len, unsigned long prot,
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(file, addr, len, prot, flags, offset);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
out:
diff --git a/arch/mips64/mm/fault.c b/arch/mips64/mm/fault.c
index 710b6b309..42e810176 100644
--- a/arch/mips64/mm/fault.c
+++ b/arch/mips64/mm/fault.c
@@ -95,7 +95,7 @@ do_page_fault(struct pt_regs *regs, unsigned long write, unsigned long address)
printk("Cpu%d[%s:%d:%08lx:%ld:%08lx]\n", smp_processor_id(), current->comm,
current->pid, address, write, regs->cp0_epc);
#endif
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
@@ -138,7 +138,7 @@ good_area:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
/*
@@ -146,7 +146,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/*
* Quickly check for vmalloc range faults.
@@ -209,14 +209,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (user_mode(regs))
do_exit(SIGKILL);
goto no_context;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/*
* Send a sigbus, regardless of whether we were in kernel
diff --git a/arch/mips64/mm/init.c b/arch/mips64/mm/init.c
index 848c1dd34..d0da581b3 100644
--- a/arch/mips64/mm/init.c
+++ b/arch/mips64/mm/init.c
@@ -1,5 +1,4 @@
-/* $Id: init.c,v 1.13 2000/02/23 00:41:00 ralf Exp $
- *
+/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
@@ -40,25 +39,6 @@
unsigned long totalram_pages;
-void __bad_pte_kernel(pmd_t *pmd)
-{
- printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
- pmd_set(pmd, BAD_PAGETABLE);
-}
-
-void __bad_pte(pmd_t *pmd)
-{
- printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
- pmd_set(pmd, BAD_PAGETABLE);
-}
-
-/* Fixme, we need something like BAD_PMDTABLE ... */
-void __bad_pmd(pgd_t *pgd)
-{
- printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd));
- pgd_set(pgd, empty_bad_pmd_table);
-}
-
void pgd_init(unsigned long page)
{
unsigned long *p, *end;
@@ -113,72 +93,6 @@ void pmd_init(unsigned long addr, unsigned long pagetable)
}
}
-pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
-{
- pmd_t *pmd;
-
- pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 1);
- if (pgd_none(*pgd)) {
- if (pmd) {
- pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table);
- pgd_set(pgd, pmd);
- return pmd + offset;
- }
- pgd_set(pgd, BAD_PMDTABLE);
- return NULL;
- }
- free_page((unsigned long)pmd);
- if (pgd_bad(*pgd)) {
- __bad_pmd(pgd);
- return NULL;
- }
- return (pmd_t *) pgd_page(*pgd) + offset;
-}
-
-pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
-{
- pte_t *page;
-
- page = (pte_t *) __get_free_pages(GFP_USER, 1);
- if (pmd_none(*pmd)) {
- if (page) {
- clear_page(page);
- pmd_set(pmd, page);
- return page + offset;
- }
- pmd_set(pmd, BAD_PAGETABLE);
- return NULL;
- }
- free_page((unsigned long)page);
- if (pmd_bad(*pmd)) {
- __bad_pte_kernel(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
-{
- pte_t *page;
-
- page = (pte_t *) __get_free_pages(GFP_KERNEL, 0);
- if (pmd_none(*pmd)) {
- if (page) {
- clear_page(page);
- pmd_val(*pmd) = (unsigned long)page;
- return page + offset;
- }
- pmd_set(pmd, BAD_PAGETABLE);
- return NULL;
- }
- free_pages((unsigned long)page, 0);
- if (pmd_bad(*pmd)) {
- __bad_pte(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + offset;
-}
-
int do_check_pgt_cache(int low, int high)
{
int freed = 0;
@@ -247,34 +161,6 @@ unsigned long setup_zero_pages(void)
return 1UL << order;
}
-/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving a inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- *
- * ZERO_PAGE is a special page that is used for zero-initialized
- * data and COW.
- */
-pmd_t * __bad_pmd_table(void)
-{
- return empty_bad_pmd_table;
-}
-
-pte_t * __bad_pagetable(void)
-{
- return empty_bad_page_table;
-}
-
-pte_t __bad_page(void)
-{
- return __pte(0);
-}
-
void __init add_memory_region(unsigned long start, unsigned long size,
long type)
{
@@ -474,8 +360,6 @@ void __init paging_init(void)
pgd_init((unsigned long)swapper_pg_dir);
pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
- pmd_init((unsigned long)empty_bad_pmd_table, (unsigned long)empty_bad_page_table);
- memset((void *)empty_bad_page_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
low = max_low_pfn;
diff --git a/arch/mips64/mm/umap.c b/arch/mips64/mm/umap.c
index 8690d9961..ba018c599 100644
--- a/arch/mips64/mm/umap.c
+++ b/arch/mips64/mm/umap.c
@@ -90,7 +90,7 @@ remove_mapping (struct task_struct *task, unsigned long start, unsigned long end
unsigned long beg = start;
pgd_t *dir;
- down (&task->mm->mmap_sem);
+ down_write (&task->mm->mmap_sem);
dir = pgd_offset (task->mm, start);
flush_cache_range (task->mm, beg, end);
while (start < end){
@@ -99,7 +99,7 @@ remove_mapping (struct task_struct *task, unsigned long start, unsigned long end
dir++;
}
flush_tlb_range (task->mm, beg, end);
- up (&task->mm->mmap_sem);
+ up_write (&task->mm->mmap_sem);
}
EXPORT_SYMBOL(remove_mapping);
diff --git a/arch/mips64/sgi-ip27/ip27-memory.c b/arch/mips64/sgi-ip27/ip27-memory.c
index 0e469ce4b..62749a773 100644
--- a/arch/mips64/sgi-ip27/ip27-memory.c
+++ b/arch/mips64/sgi-ip27/ip27-memory.c
@@ -234,8 +234,6 @@ void __init paging_init(void)
pgd_init((unsigned long)swapper_pg_dir);
pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
- pmd_init((unsigned long)empty_bad_pmd_table, (unsigned long)empty_bad_page_table);
- memset((void *)empty_bad_page_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
for (node = 0; node < numnodes; node++) {
pfn_t start_pfn = slot_getbasepfn(node, 0);
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 85aca70af..1e365cc76 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -51,7 +51,7 @@ int sys_mmap(unsigned long addr, unsigned long len,
struct file * file = NULL;
int error;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
lock_kernel();
if (!(flags & MAP_ANONYMOUS)) {
error = -EBADF;
@@ -65,7 +65,7 @@ int sys_mmap(unsigned long addr, unsigned long len,
fput(file);
out:
unlock_kernel();
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
return error;
}
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 68d4614ec..d7ca72dd9 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -175,7 +175,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
if (in_interrupt() || !mm)
goto no_context;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = pa_find_vma(mm, address);
if (!vma)
goto bad_area;
@@ -218,14 +218,14 @@ good_area:
default:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
/*
* Something tried to access memory that isn't in our memory map..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
if (user_mode(regs)) {
struct siginfo si;
@@ -275,7 +275,7 @@ no_context:
parisc_terminate("Bad Address (null pointer deref?)",regs,code,address);
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", current->comm);
if (user_mode(regs))
do_exit(SIGKILL);
diff --git a/arch/ppc/8xx_io/Config.in b/arch/ppc/8xx_io/Config.in
index 090c09cb4..7ca789288 100644
--- a/arch/ppc/8xx_io/Config.in
+++ b/arch/ppc/8xx_io/Config.in
@@ -7,24 +7,24 @@ comment 'MPC8xx CPM Options'
if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
bool 'CPM SCC Ethernet' CONFIG_SCC_ENET
if [ "$CONFIG_SCC_ENET" = "y" ]; then
- bool 'Ethernet on SCC1' CONFIG_SCC1_ENET
- if [ "$CONFIG_SCC1_ENET" != "y" ]; then
- bool 'Ethernet on SCC2' CONFIG_SCC2_ENET
- fi
+ choice 'SCC used for Ethernet' \
+ "SCC1 CONFIG_SCC1_ENET \
+ SCC2 CONFIG_SCC2_ENET \
+ SCC3 CONFIG_SCC3_ENET" SCC1
fi
bool '860T FEC Ethernet' CONFIG_FEC_ENET
+ if [ "$CONFIG_FEC_ENET" = "y" ]; then
+ bool 'Use MDIO for PHY configuration' CONFIG_USE_MDIO
+ fi
bool 'Use Big CPM Ethernet Buffers' CONFIG_ENET_BIG_BUFFERS
fi
bool 'Use SMC2 for UART' CONFIG_8xxSMC2
if [ "$CONFIG_8xxSMC2" = "y" ]; then
bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_8xx_ALTSMC2
+ bool 'Use SMC2 for Console' CONFIG_8xx_CONS_SMC2
fi
bool 'Enable SCC2 and SCC3 for UART' CONFIG_8xxSCC
-if [ "$CONFIG_TQM860" = "y" -o "$CONFIG_TQM860L" = "y" -o "$CONFIG_TQM8xxL" = "y" ]; then
- bool 'Use SMC2 for Console' TQM_SMC2_CONSOLE
-fi
-
# This doesn't really belong here, but it is convenient to ask
# 8xx specific questions.
@@ -32,4 +32,7 @@ comment 'Generic MPC8xx Options'
bool 'Copy-Back Data Cache (else Writethrough)' CONFIG_8xx_COPYBACK
bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6
+if [ "$CONFIG_IDE" = "y" ]; then
+ bool 'MPC8xx direct IDE support on PCMCIA port' CONFIG_BLK_DEV_MPC8xx_IDE
+fi
endmenu
diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c
index 0790a81c5..19d7f3dd1 100644
--- a/arch/ppc/8xx_io/commproc.c
+++ b/arch/ppc/8xx_io/commproc.c
@@ -61,22 +61,6 @@ m8xx_cpm_reset(uint host_page_addr)
imp = (immap_t *)IMAP_ADDR;
commproc = (cpm8xx_t *)&imp->im_cpm;
-#ifdef notdef
- /* We can't do this. It seems to blow away the microcode
- * patch that EPPC-Bug loaded for us. EPPC-Bug uses SCC1 for
- * Ethernet, SMC1 for the console, and I2C for serial EEPROM.
- * Our own drivers quickly reset all of these.
- */
-
- /* Perform a reset.
- */
- commproc->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
-
- /* Wait for it.
- */
- while (commproc->cp_cpcr & CPM_CR_FLG);
-#endif
-
/* Set SDMA Bus Request priority 5.
* On 860T, this also enables FEC priority 6. I am not sure
* this is what we realy want for some applications, but the
@@ -168,6 +152,14 @@ cpm_error_interrupt(void *dev)
void
cpm_install_handler(int vec, void (*handler)(void *), void *dev_id)
{
+
+ /* If null handler, assume we are trying to free the IRQ.
+ */
+ if (!handler) {
+ cpm_free_handler(vec);
+ return;
+ }
+
if (cpm_vecs[vec].handler != 0)
printk("CPM interrupt %x replacing %x\n",
(uint)handler, (uint)cpm_vecs[vec].handler);
@@ -226,8 +218,9 @@ m8xx_cpm_hostalloc(uint size)
* The internal baud rate clock is the system clock divided by 16.
* This assumes the baudrate is 16x oversampled by the uart.
*/
-#define BRG_INT_CLK (((bd_t *)__res)->bi_intfreq * 1000000)
-#define BRG_UART_CLK (BRG_INT_CLK/16)
+#define BRG_INT_CLK (((bd_t *)__res)->bi_intfreq * 1000000)
+#define BRG_UART_CLK (BRG_INT_CLK/16)
+#define BRG_UART_CLK_DIV16 (BRG_UART_CLK/16)
void
m8xx_cpm_setbrg(uint brg, uint rate)
@@ -238,6 +231,12 @@ m8xx_cpm_setbrg(uint brg, uint rate)
*/
bp = (uint *)&cpmp->cp_brgc1;
bp += brg;
- *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN;
+ /* The BRG has a 12-bit counter. For really slow baud rates (or
+ * really fast processors), we may have to further divide by 16.
+ */
+ if (((BRG_UART_CLK / rate) - 1) < 4096)
+ *bp = (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN;
+ else
+ *bp = (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) |
+ CPM_BRG_EN | CPM_BRG_DIV16;
}
-
diff --git a/arch/ppc/8xx_io/commproc.h b/arch/ppc/8xx_io/commproc.h
index a8194cb21..6eda9d5bf 100644
--- a/arch/ppc/8xx_io/commproc.h
+++ b/arch/ppc/8xx_io/commproc.h
@@ -324,7 +324,7 @@ typedef struct scc_param {
*/
#define SCC_EB ((u_char)0x10) /* Set big endian byte order */
-/* CPM Ethernet through SCC1.
+/* CPM Ethernet through SCCx.
*/
typedef struct scc_enet {
sccp_t sen_genscc;
@@ -379,6 +379,8 @@ typedef struct scc_enet {
ushort sen_taddrl; /* temp address (LSB) */
} scc_enet_t;
+/*** MBX ************************************************************/
+
#ifdef CONFIG_MBX
/* Bits in parallel I/O port registers that have to be set/cleared
* to configure the pins for SCC1 use. The TCLK and RCLK seem unique
@@ -399,7 +401,9 @@ typedef struct scc_enet {
*/
#define SICR_ENET_MASK ((uint)0x000000ff)
#define SICR_ENET_CLKRT ((uint)0x0000003d)
-#endif
+#endif /* CONFIG_MBX */
+
+/*** RPXLITE ********************************************************/
#ifdef CONFIG_RPXLITE
/* This ENET stuff is for the MPC850 with ethernet on SCC2. Some of
@@ -416,7 +420,9 @@ typedef struct scc_enet {
#define SICR_ENET_MASK ((uint)0x0000ff00)
#define SICR_ENET_CLKRT ((uint)0x00003d00)
-#endif
+#endif /* CONFIG_RPXLITE */
+
+/*** BSEIP **********************************************************/
#ifdef CONFIG_BSEIP
/* This ENET stuff is for the MPC823 with ethernet on SCC2.
@@ -438,7 +444,9 @@ typedef struct scc_enet {
#define SICR_ENET_MASK ((uint)0x0000ff00)
#define SICR_ENET_CLKRT ((uint)0x00002c00)
-#endif
+#endif /* CONFIG_BSEIP */
+
+/*** RPXCLASSIC *****************************************************/
#ifdef CONFIG_RPXCLASSIC
/* Bits in parallel I/O port registers that have to be set/cleared
@@ -457,27 +465,63 @@ typedef struct scc_enet {
*/
#define SICR_ENET_MASK ((uint)0x000000ff)
#define SICR_ENET_CLKRT ((uint)0x0000003d)
-#endif
+#endif /* CONFIG_RPXCLASSIC */
-#if (defined(CONFIG_TQM860) || defined(CONFIG_TQM860L))
-/*
- * TQM860 and TQM860L Configuration:
- *
- * Signal PAR DIR ODR DAT Function
- * Port A, 5 1 0 - - TCLK (CLK3) for Ethernet
- * Port A, 7 1 0 - - RCLK (CLK1) for Ethernet
- * Port A, 14 1 0 - - TXD for Ethernet (SCC1)
- * Port A, 15 1 0 - - RXD for Ethernet (SCC1)
- * Port C, 7 0 0 0 - -> ETH-LOOP
- * Port C, 10 0 0 1 - CD for Ethernet (SCC1)
- * Port C, 11 0 0 1 - CTS for Ethernet (SCC1)
- * Port C, 15 * * 0 - TENA/RTS for Ethernet
+/*** TQM823L, TQM850L ***********************************************/
+
+#if defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L)
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
*/
+#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */
+#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */
+#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
+#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
+#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */
+
+#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */
+#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */
+
+/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
+ * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
+ */
+#define SICR_ENET_MASK ((uint)0x0000ff00)
+#define SICR_ENET_CLKRT ((uint)0x00002600)
+#endif /* CONFIG_TQM823L, CONFIG_TQM850L */
+
+/*** FPS850L *********************************************************/
+
+#ifdef CONFIG_FPS850L
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ */
+#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */
+#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */
+#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
+#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
+
+#define PC_ENET_TENA ((ushort)0x0002) /* PC 14 */
+#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */
+#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */
+
+/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
+ * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
+ */
+#define SICR_ENET_MASK ((uint)0x0000ff00)
+#define SICR_ENET_CLKRT ((uint)0x00002600)
+#endif /* CONFIG_FPS850L */
+
+/*** TQM860L ********************************************************/
+
+#ifdef CONFIG_TQM860L
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ */
#define PA_ENET_RXD ((ushort)0x0001) /* PA 15 */
#define PA_ENET_TXD ((ushort)0x0002) /* PA 14 */
-#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
+#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
#define PC_ENET_TENA ((ushort)0x0001) /* PC 15 */
#define PC_ENET_CLSN ((ushort)0x0010) /* PC 11 */
@@ -488,51 +532,59 @@ typedef struct scc_enet {
*/
#define SICR_ENET_MASK ((uint)0x000000ff)
#define SICR_ENET_CLKRT ((uint)0x00000026)
+#endif /* CONFIG_TQM860L */
-#endif /* CONFIG_TQM860, TQM860L */
+/*** SPD823TS *******************************************************/
-#ifdef CONFIG_TQM8xxL
-/*
- * TQM8xxL Configuration (except TQM860L):
- *
- * Signal PAR DIR ODR DAT Function
- * Port A, 5 1 0 - - TCLK (CLK3) for Ethernet
- * Port A, 7 1 0 - - RCLK (CLK1) for Ethernet
- * Port A, 12 1 0 - - TXD for Ethernet (SCC2)
- * Port A, 13 1 0 - - RXD for Ethernet (SCC2)
- * Port B, 18 1 1 - - TENA/RTS for Ethernet on STK8xx
- * Port C, 7 0 0 0 - -> ETH-LOOP
- * Port C, 8 0 0 1 - CD for Ethernet (SCC2)
- * Port C, 9 0 0 1 - CTS for Ethernet (SCC2)
- * Port C, 14 * * 0 - TENA/RTS for Ethernet on FPS850
- *
- * Note: Using PC14 as RTS2 (TENA) does not work on the TQM850L when
- * used with the starter-kit mainboard; we *must* use PB18 instead.
- * For the FPS850 system, we *must* use PC14 :-(
+#ifdef CONFIG_SPD823TS
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC2 use.
*/
-
+#define PA_ENET_MDC ((ushort)0x0001) /* PA 15 !!! */
+#define PA_ENET_MDIO ((ushort)0x0002) /* PA 14 !!! */
#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */
#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */
-#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
+#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */
#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
-#ifndef CONFIG_FPS850 /* not valid on FPS board */
-#define PB_ENET_TENA ((uint)0x00002000)
-#endif /* !CONFIG_FPS850 */
+#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */
-#ifdef CONFIG_FPS850 /* FPS uses default configuration */
-#define PC_ENET_TENA ((ushort)0x0002) /* PC 14 */
-#endif /* CONFIG_FPS850 */
#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */
#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */
+#define PC_ENET_RESET ((ushort)0x0100) /* PC 7 !!! */
-/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
+/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK2) to
* SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
*/
#define SICR_ENET_MASK ((uint)0x0000ff00)
-#define SICR_ENET_CLKRT ((uint)0x00002600)
+#define SICR_ENET_CLKRT ((uint)0x00002E00)
+#endif /* CONFIG_SPD823TS */
+
+
+/*** SM850 *********************************************************/
+
+/* The SM850 Service Module uses SCC2 for IrDA and SCC3 for Ethernet */
+
+#ifdef CONFIG_SM850
+#define PB_ENET_RXD ((uint)0x00000004) /* PB 29 */
+#define PB_ENET_TXD ((uint)0x00000002) /* PB 30 */
+#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
+#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
+
+#define PC_ENET_LBK ((ushort)0x0008) /* PC 12 */
+#define PC_ENET_TENA ((ushort)0x0004) /* PC 13 */
-#endif /* CONFIG_TQM8xxL */
+#define PC_ENET_RENA ((ushort)0x0800) /* PC 4 */
+#define PC_ENET_CLSN ((ushort)0x0400) /* PC 5 */
+
+/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
+ * SCC3. Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero.
+ */
+#define SICR_ENET_MASK ((uint)0x00FF0000)
+#define SICR_ENET_CLKRT ((uint)0x00260000)
+#endif /* CONFIG_SM850 */
+
+/*********************************************************************/
/* SCC Event register as used by Ethernet.
*/
@@ -723,8 +775,6 @@ typedef struct iic {
#define CPMVEC_PIO_PC4 ((ushort)0x01)
#define CPMVEC_ERROR ((ushort)0x00)
-extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
-
/* CPM interrupt configuration vector.
*/
#define CICR_SCD_SCC4 ((uint)0x00c00000) /* SCC4 @ SCCd */
@@ -735,4 +785,8 @@ extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */
#define CICR_IEN ((uint)0x00000080) /* Int. enable */
#define CICR_SPS ((uint)0x00000001) /* SCC Spread */
+
+extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
+extern void cpm_free_handler(int vec);
+
#endif /* __CPM_8XX__ */
diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c
index 39628da04..600046bb8 100644
--- a/arch/ppc/8xx_io/enet.c
+++ b/arch/ppc/8xx_io/enet.c
@@ -154,20 +154,26 @@ static void set_multicast_list(struct net_device *dev);
/*static ushort my_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };*/
/* Typically, 860(T) boards use SCC1 for Ethernet, and other 8xx boards
- * use SCC2. This is easily extended if necessary.
+ * use SCC2. Some even may use SCC3.
+ * This is easily extended if necessary.
*/
-#ifdef CONFIG_SCC2_ENET
+#if defined(CONFIG_SCC3_ENET)
+#define CPM_CR_ENET CPM_CR_CH_SCC3
+#define PROFF_ENET PROFF_SCC3
+#define SCC_ENET 2 /* Index, not number! */
+#define CPMVEC_ENET CPMVEC_SCC3
+#elif defined(CONFIG_SCC2_ENET)
#define CPM_CR_ENET CPM_CR_CH_SCC2
#define PROFF_ENET PROFF_SCC2
#define SCC_ENET 1 /* Index, not number! */
#define CPMVEC_ENET CPMVEC_SCC2
-#endif
-
-#ifdef CONFIG_SCC1_ENET
-#define CPM_CR_ENET CPM_CR_CH_SCC1
+#elif defined(CONFIG_SCC1_ENET)
+#define CPM_CR_ENET CPM_CR_CH_SCC1
#define PROFF_ENET PROFF_SCC1
-#define SCC_ENET 0
+#define SCC_ENET 0 /* Index, not number! */
#define CPMVEC_ENET CPMVEC_SCC1
+#else
+#error CONFIG_SCCx_ENET not defined
#endif
static int
@@ -642,10 +648,11 @@ int __init scc_enet_init(void)
volatile scc_t *sccp;
volatile scc_enet_t *ep;
volatile immap_t *immap;
+ extern unsigned long _get_IMMR(void);
cp = cpmp; /* Get pointer to Communication Processor */
- immap = (immap_t *)IMAP_ADDR; /* and to internal registers */
+ immap = (immap_t *)(_get_IMMR() & 0xFFFF0000); /* and to internal registers */
bd = (bd_t *)__res;
@@ -683,28 +690,47 @@ int __init scc_enet_init(void)
* It can't last though......
*/
+#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
/* Configure port A pins for Txd and Rxd.
*/
- immap->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD);
+ immap->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD);
immap->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
- immap->im_ioport.iop_paodr &= ~PA_ENET_TXD;
+ immap->im_ioport.iop_paodr &= ~PA_ENET_TXD;
+#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
+ /* Configure port B pins for Txd and Rxd.
+ */
+ immap->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD);
+ immap->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
+ immap->im_cpm.cp_pbodr &= ~PB_ENET_TXD;
+#else
+#error Exactly ONE pair of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
+#endif
+
+#if defined(PC_ENET_LBK)
+ /* Configure port C pins to disable External Loopback
+ */
+ immap->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
+ immap->im_ioport.iop_pcdir |= PC_ENET_LBK;
+ immap->im_ioport.iop_pcso &= ~PC_ENET_LBK;
+ immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */
+#endif /* PC_ENET_LBK */
/* Configure port C pins to enable CLSN and RENA.
*/
immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
- immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
+ immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
/* Configure port A for TCLK and RCLK.
*/
- immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
+ immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
/* Configure Serial Interface clock routing.
* First, clear all SCC bits to zero, then set the ones we want.
*/
cp->cp_sicr &= ~SICR_ENET_MASK;
- cp->cp_sicr |= SICR_ENET_CLKRT;
+ cp->cp_sicr |= SICR_ENET_CLKRT;
/* Manual says set SDDR, but I can't find anything with that
* name. I think it is a misprint, and should be SDCR. This
@@ -884,20 +910,17 @@ int __init scc_enet_init(void)
/* It is now OK to enable the Ethernet transmitter.
* Unfortunately, there are board implementation differences here.
*/
-#if (defined(CONFIG_MBX) || defined(CONFIG_TQM860) || defined(CONFIG_TQM860L) || defined(CONFIG_FPS850))
- immap->im_ioport.iop_pcpar |= PC_ENET_TENA;
+#if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA))
+ immap->im_ioport.iop_pcpar |= PC_ENET_TENA;
immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
-#endif
-
-#if (defined(CONFIG_TQM8xxL) && !defined(CONFIG_FPS850))
+#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA))
cp->cp_pbpar |= PB_ENET_TENA;
cp->cp_pbdir |= PB_ENET_TENA;
+#else
+#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA
#endif
#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
- cp->cp_pbpar |= PB_ENET_TENA;
- cp->cp_pbdir |= PB_ENET_TENA;
-
/* And while we are here, set the configuration to enable ethernet.
*/
*((volatile uint *)RPX_CSR_ADDR) &= ~BCSR0_ETHLPBK;
@@ -906,9 +929,6 @@ int __init scc_enet_init(void)
#endif
#ifdef CONFIG_BSEIP
- cp->cp_pbpar |= PB_ENET_TENA;
- cp->cp_pbdir |= PB_ENET_TENA;
-
/* BSE uses port B and C for PHY control.
*/
cp->cp_pbpar &= ~(PB_BSE_POWERUP | PB_BSE_FDXDIS);
@@ -941,7 +961,7 @@ int __init scc_enet_init(void)
*/
sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- printk("%s: CPM ENET Version 0.2, ", dev->name);
+ printk("%s: CPM ENET Version 0.2 on SCC%d, ", dev->name, SCC_ENET+1);
for (i=0; i<5; i++)
printk("%02x:", dev->dev_addr[i]);
printk("%02x\n", dev->dev_addr[5]);
@@ -949,3 +969,4 @@ int __init scc_enet_init(void)
return 0;
}
+
diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c
index 33849ea0e..848a2fc4d 100644
--- a/arch/ppc/8xx_io/fec.c
+++ b/arch/ppc/8xx_io/fec.c
@@ -8,7 +8,9 @@
* describes connections using the internal parallel port I/O, which
* is basically all of Port D.
*
- * Right now, I am very watseful with the buffers. I allocate memory
+ * Includes support for the following PHYs: QS6612, LXT970, LXT971/2.
+ *
+ * Right now, I am very wasteful 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
@@ -18,13 +20,16 @@
* Much better multiple PHY support by Magnus Damm.
* Copyright (c) 2000 Ericsson Radio Systems AB.
*
+ * Make use of MII for PHY control configurable.
+ * Some fixes.
+ * Copyright (c) 2000 Wolfgang Denk, DENX Software Engineering.
*/
/* List of PHYs we wish to support.
*/
-#define CONFIG_FEC_LXT970
-#define CONFIG_FEC_LXT971
-#define CONFIG_FEC_QS6612
+#undef CONFIG_FEC_LXT970
+#define CONFIG_FEC_LXT971
+#undef CONFIG_FEC_QS6612
#include <linux/config.h>
#include <linux/kernel.h>
@@ -54,6 +59,7 @@
#include <asm/uaccess.h>
#include "commproc.h"
+#ifdef CONFIG_USE_MDIO
/* Forward declarations of some structures to support different PHYs
*/
@@ -71,6 +77,7 @@ typedef struct {
const phy_cmd_t *ack_int;
const phy_cmd_t *shutdown;
} phy_info_t;
+#endif /* CONFIG_USE_MDIO */
/* 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 is best
@@ -78,20 +85,20 @@ typedef struct {
* We don't need to allocate pages for the transmitter. We just use
* the skbuffer directly.
*/
-#if 1
-#define FEC_ENET_RX_PAGES 4
+#ifdef CONFIG_ENET_BIG_BUFFERS
+#define FEC_ENET_RX_PAGES 16
#define FEC_ENET_RX_FRSIZE 2048
#define FEC_ENET_RX_FRPPG (PAGE_SIZE / FEC_ENET_RX_FRSIZE)
#define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
-#define TX_RING_SIZE 8 /* Must be power of two */
-#define TX_RING_MOD_MASK 7 /* for this to work */
+#define TX_RING_SIZE 16 /* Must be power of two */
+#define TX_RING_MOD_MASK 15 /* for this to work */
#else
-#define FEC_ENET_RX_PAGES 16
+#define FEC_ENET_RX_PAGES 4
#define FEC_ENET_RX_FRSIZE 2048
#define FEC_ENET_RX_FRPPG (PAGE_SIZE / FEC_ENET_RX_FRSIZE)
#define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
-#define TX_RING_SIZE 16 /* Must be power of two */
-#define TX_RING_MOD_MASK 15 /* for this to work */
+#define TX_RING_SIZE 8 /* Must be power of two */
+#define TX_RING_MOD_MASK 7 /* for this to work */
#endif
/* Interrupt events/masks.
@@ -107,6 +114,26 @@ typedef struct {
#define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */
#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
+/*
+*/
+#define FEC_ECNTRL_PINMUX 0x00000004
+#define FEC_ECNTRL_ETHER_EN 0x00000002
+#define FEC_ECNTRL_RESET 0x00000001
+
+#define FEC_RCNTRL_BC_REJ 0x00000010
+#define FEC_RCNTRL_PROM 0x00000008
+#define FEC_RCNTRL_MII_MODE 0x00000004
+#define FEC_RCNTRL_DRT 0x00000002
+#define FEC_RCNTRL_LOOP 0x00000001
+
+#define FEC_TCNTRL_FDEN 0x00000004
+#define FEC_TCNTRL_HBC 0x00000002
+#define FEC_TCNTRL_GTS 0x00000001
+
+/* Delay to wait for FEC reset command to complete (in us)
+*/
+#define FEC_RESET_DELAY 50
+
/* The FEC stores dest/src/type, data, and checksum for receive packets.
*/
#define PKT_MAXBUF_SIZE 1518
@@ -138,6 +165,7 @@ struct fec_enet_private {
uint tx_full;
spinlock_t lock;
+#ifdef CONFIG_USE_MDIO
uint phy_id;
uint phy_id_done;
uint phy_status;
@@ -148,6 +176,7 @@ struct fec_enet_private {
uint sequence_done;
uint phy_addr;
+#endif /* CONFIG_USE_MDIO */
int link;
int old_link;
@@ -165,7 +194,9 @@ struct fec_enet_private {
static int fec_enet_open(struct net_device *dev);
static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+#ifdef CONFIG_USE_MDIO
static void fec_enet_mii(struct net_device *dev);
+#endif /* CONFIG_USE_MDIO */
static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
#ifdef CONFIG_FEC_PACKETHOOK
static void fec_enet_tx(struct net_device *dev, __u32 regval);
@@ -181,6 +212,7 @@ static void fec_restart(struct net_device *dev, int duplex);
static void fec_stop(struct net_device *dev);
static ushort my_enet_addr[3];
+#ifdef CONFIG_USE_MDIO
/* 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.
@@ -197,7 +229,7 @@ mii_list_t *mii_free;
mii_list_t *mii_head;
mii_list_t *mii_tail;
-static int mii_queue(struct net_device *dev, int request,
+static int mii_queue(struct net_device *dev, int request,
void (*func)(uint, struct net_device *));
/* Make MII read/write commands for the FEC.
@@ -206,11 +238,13 @@ static int mii_queue(struct net_device *dev, int request,
#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \
(VAL & 0xffff))
#define mk_mii_end 0
+#endif /* CONFIG_USE_MDIO */
/* Transmitter timeout.
*/
#define TX_TIMEOUT (2*HZ)
+#ifdef CONFIG_USE_MDIO
/* Register definitions for the PHY.
*/
@@ -218,7 +252,7 @@ static int mii_queue(struct net_device *dev, int request,
#define MII_REG_SR 1 /* Status Register */
#define MII_REG_PHYIR1 2 /* PHY Identification Register 1 */
#define MII_REG_PHYIR2 3 /* PHY Identification Register 2 */
-#define MII_REG_ANAR 4 /* A-N Advertisement Register */
+#define MII_REG_ANAR 4 /* A-N Advertisement Register */
#define MII_REG_ANLPAR 5 /* A-N Link Partner Ability Register */
#define MII_REG_ANER 6 /* A-N Expansion Register */
#define MII_REG_ANNPTR 7 /* A-N Next Page Transmit Register */
@@ -230,18 +264,19 @@ static int mii_queue(struct net_device *dev, int request,
#define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */
#define PHY_CONF_SPMASK 0x00f0 /* mask for speed */
#define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */
-#define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */
+#define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */
#define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */
-#define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */
+#define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */
#define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */
#define PHY_STAT_FAULT 0x0200 /* 1 remote fault */
#define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */
#define PHY_STAT_SPMASK 0xf000 /* mask for speed */
#define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */
-#define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */
+#define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */
#define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */
-#define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */
+#define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */
+#endif /* CONFIG_USE_MDIO */
#ifdef CONFIG_FEC_PACKETHOOK
int
@@ -291,7 +326,7 @@ fec_unregister_ph(struct net_device *dev)
fep->ph_proto = 0;
fep->ph_regaddr = NULL;
fep->ph_priv = NULL;
-
+
fep->ph_lock = 0;
return retval;
@@ -345,7 +380,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
fep->stats.tx_bytes += skb->len;
fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK;
-
+
/* Push the data cache so the CPM does not get stale memory
* data.
*/
@@ -404,7 +439,7 @@ fec_timeout(struct net_device *dev)
bdp = fep->tx_bd_base;
printk(" tx: %u buffers\n", TX_RING_SIZE);
for (i = 0 ; i < TX_RING_SIZE; i++) {
- printk(" %08x: %04x %04x %08x\n",
+ printk(" %08x: %04x %04x %08x\n",
(uint) bdp,
bdp->cbd_sc,
bdp->cbd_datlen,
@@ -443,7 +478,6 @@ fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
if (fep->ph_regaddr) regval = *fep->ph_regaddr;
#endif
-
fecp = (volatile fec_t*)dev->base_addr;
/* Get the interrupt events that caused us to be here.
@@ -478,9 +512,13 @@ fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
}
if (int_events & FEC_ENET_MII) {
+#ifdef CONFIG_USE_MDIO
fec_enet_mii(dev);
+#else
+printk("%s[%d] %s: unexpected FEC_ENET_MII event\n", __FILE__,__LINE__,__FUNCTION__);
+#endif /* CONFIG_USE_MDIO */
}
-
+
}
}
@@ -541,23 +579,23 @@ fec_enet_tx(struct net_device *dev)
*/
if (bdp->cbd_sc & BD_ENET_TX_DEF)
fep->stats.collisions++;
-
+
/* Free the sk buffer associated with this last transmit.
*/
#if 0
printk("TXI: %x %x %x\n", bdp, skb, fep->skb_dirty);
#endif
- dev_kfree_skb(skb/*, FREE_WRITE*/);
+ dev_kfree_skb_irq (skb/*, FREE_WRITE*/);
fep->tx_skbuff[fep->skb_dirty] = NULL;
fep->skb_dirty = (fep->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 = fep->tx_bd_base;
else
bdp++;
-
+
/* Since we have freed up a buffer, the ring is no longer
* full.
*/
@@ -617,7 +655,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) {
/* Check for errors. */
if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
BD_ENET_RX_CR | BD_ENET_RX_OV)) {
- fep->stats.rx_errors++;
+ fep->stats.rx_errors++;
if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
/* Frame too long or too short. */
fep->stats.rx_length_errors++;
@@ -703,7 +741,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) {
bdp = fep->rx_bd_base;
else
bdp++;
-
+
#if 1
/* Doing this here will keep the FEC running while we process
* incoming frames. On a heavily loaded network, we should be
@@ -732,6 +770,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) {
}
+#ifdef CONFIG_USE_MDIO
static void
fec_enet_mii(struct net_device *dev)
{
@@ -743,7 +782,7 @@ fec_enet_mii(struct net_device *dev)
fep = (struct fec_enet_private *)dev->priv;
ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
mii_reg = ep->fec_mii_data;
-
+
if ((mip = mii_head) == NULL) {
printk("MII and no head!\n");
return;
@@ -756,8 +795,9 @@ fec_enet_mii(struct net_device *dev)
mip->mii_next = mii_free;
mii_free = mip;
- if ((mip = mii_head) != NULL)
+ if ((mip = mii_head) != NULL) {
ep->fec_mii_data = mip->mii_regval;
+ }
}
static int
@@ -786,13 +826,11 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
if (mii_head) {
mii_tail->mii_next = mip;
mii_tail = mip;
- }
- else {
+ } else {
mii_head = mii_tail = mip;
(&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval;
}
- }
- else {
+ } else {
retval = 1;
}
@@ -808,7 +846,7 @@ static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c)
if(!c)
return;
- for(k = 0; (c+k)->mii_data != mk_mii_end; k++)
+ for(k = 0; (c+k)->mii_data != mk_mii_end; k++)
mii_queue(dev, (c+k)->mii_data, (c+k)->funct);
}
@@ -896,7 +934,7 @@ static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev)
}
static phy_info_t phy_info_lxt970 = {
- 0x07810000,
+ 0x07810000,
"LXT970",
(const phy_cmd_t []) { /* config */
@@ -919,12 +957,12 @@ static phy_info_t phy_info_lxt970 = {
},
(const phy_cmd_t []) { /* ack_int */
/* read SR and ISR to acknowledge */
-
+
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
{ mk_mii_read(MII_LXT970_ISR), NULL },
/* find out the current status */
-
+
{ mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr },
{ mk_mii_end, }
},
@@ -933,7 +971,7 @@ static phy_info_t phy_info_lxt970 = {
{ mk_mii_end, }
},
};
-
+
#endif /* CONFIG_FEC_LXT970 */
/* ------------------------------------------------------------------------- */
@@ -950,7 +988,7 @@ static phy_info_t phy_info_lxt970 = {
#define MII_LXT971_LCR 20 /* LED Control Register */
#define MII_LXT971_TCR 30 /* Transmit Control Register */
-/*
+/*
* I had some nice ideas of running the MDIO faster...
* The 971 should support 8MHz and I tried it, but things acted really
* weird, so 2.5 MHz ought to be enough for anyone...
@@ -980,14 +1018,11 @@ static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev)
}
static phy_info_t phy_info_lxt971 = {
- 0x0001378e,
+ 0x0001378e,
"LXT971",
-
- (const phy_cmd_t []) { /* config */
- /* limit to 10MBit because my protorype board
- * doesn't work with 100. */
- { mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 MBit */
+ (const phy_cmd_t []) { /* config */
+// { mk_mii_write(MII_REG_ANAR, 0x021), NULL }, /* 10 Mbps, HD */
{ mk_mii_read(MII_REG_CR), mii_parse_cr },
{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
{ mk_mii_end, }
@@ -995,12 +1030,12 @@ static phy_info_t phy_info_lxt971 = {
(const phy_cmd_t []) { /* startup - enable interrupts */
{ mk_mii_write(MII_LXT971_IER, 0x00f2), NULL },
{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
-
+
/* Somehow does the 971 tell me that the link is down
* the first read after power-up.
* read here to get a valid value in ack_int */
- { mk_mii_read(MII_REG_SR), mii_parse_sr },
+ { mk_mii_read(MII_REG_SR), mii_parse_sr },
{ mk_mii_end, }
},
(const phy_cmd_t []) { /* ack_int */
@@ -1008,9 +1043,9 @@ static phy_info_t phy_info_lxt971 = {
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
{ mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 },
-
+
/* we only need to read ISR to acknowledge */
-
+
{ mk_mii_read(MII_LXT971_ISR), NULL },
{ mk_mii_end, }
},
@@ -1053,13 +1088,13 @@ static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev)
}
static phy_info_t phy_info_qs6612 = {
- 0x00181440,
+ 0x00181440,
"QS6612",
-
- (const phy_cmd_t []) { /* config */
-// { mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 MBit */
- /* The PHY powers up isolated on the RPX,
+ (const phy_cmd_t []) { /* config */
+// { mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 Mbps */
+
+ /* The PHY powers up isolated on the RPX,
* so send a command to allow operation.
*/
@@ -1077,9 +1112,9 @@ static phy_info_t phy_info_qs6612 = {
{ mk_mii_end, }
},
(const phy_cmd_t []) { /* ack_int */
-
+
/* we need to read ISR, SR and ANER to acknowledge */
-
+
{ mk_mii_read(MII_QS6612_ISR), NULL },
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
{ mk_mii_read(MII_REG_ANER), NULL },
@@ -1134,10 +1169,10 @@ static void mii_display_status(struct net_device *dev)
printk("link up");
switch(*s & PHY_STAT_SPMASK) {
- case PHY_STAT_100FDX: printk(", 100MBit Full Duplex"); break;
- case PHY_STAT_100HDX: printk(", 100MBit Half Duplex"); break;
- case PHY_STAT_10FDX: printk(", 10MBit Full Duplex"); break;
- case PHY_STAT_10HDX: printk(", 10MBit Half Duplex"); break;
+ case PHY_STAT_100FDX: printk(", 100 Mbps Full Duplex"); break;
+ case PHY_STAT_100HDX: printk(", 100 Mbps Half Duplex"); break;
+ case PHY_STAT_10FDX: printk(", 10 Mbps Full Duplex"); break;
+ case PHY_STAT_10HDX: printk(", 10 Mbps Half Duplex"); break;
default:
printk(", Unknown speed/duplex");
}
@@ -1177,7 +1212,7 @@ static void mii_display_config(struct net_device *dev)
if (*s & PHY_CONF_LOOP)
printk(", loopback enabled");
-
+
printk(".\n");
fep->sequence_done = 1;
@@ -1194,7 +1229,7 @@ static void mii_relink(struct net_device *dev)
if (fep->link) {
duplex = 0;
- if (fep->phy_status
+ if (fep->phy_status
& (PHY_STAT_100FDX | PHY_STAT_10FDX))
duplex = 1;
fec_restart(dev, duplex);
@@ -1245,18 +1280,20 @@ mii_discover_phy3(uint mii_reg, struct net_device *dev)
fep = dev->priv;
fep->phy_id |= (mii_reg & 0xffff);
- printk("fec: Phy @ 0x%x, type 0x%08x\n", fep->phy_addr, fep->phy_id);
for(i = 0; phy_info[i]; i++)
if(phy_info[i]->id == (fep->phy_id >> 4))
break;
if(!phy_info[i])
- panic("%s: PHY id 0x%08x is not supported!\n",
+ panic("%s: PHY id 0x%08x is not supported!\n",
dev->name, fep->phy_id);
-
+
fep->phy = phy_info[i];
fep->phy_id_done = 1;
+
+ printk("%s: Phy @ 0x%x, type %s (0x%08x)\n",
+ dev->name, fep->phy_addr, fep->phy->name, fep->phy_id);
}
/* Scan all of the MII PHY addresses looking for someone to respond
@@ -1270,25 +1307,23 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
fep = dev->priv;
- if (fep->phy_addr < 32) {
- if ((phytype = (mii_reg & 0xffff)) != 0xffff) {
-
- /* Got first part of ID, now get remainder.
- */
- fep->phy_id = phytype << 16;
- mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
- mii_discover_phy3);
- }
- else {
- fep->phy_addr++;
+ if ((phytype = (mii_reg & 0xffff)) != 0xffff) {
+
+ /* Got first part of ID, now get remainder.
+ */
+ fep->phy_id = phytype << 16;
+ mii_queue(dev, mk_mii_read(MII_REG_PHYIR2), mii_discover_phy3);
+ } else {
+ fep->phy_addr++;
+ if (fep->phy_addr < 32) {
mii_queue(dev, mk_mii_read(MII_REG_PHYIR1),
mii_discover_phy);
+ } else {
+ printk("fec: No PHY device found.\n");
}
}
- else {
- printk("FEC: No PHY device found.\n");
- }
}
+#endif /* CONFIG_USE_MDIO */
/* This interrupt occurs when the PHY detects a link change.
*/
@@ -1299,16 +1334,36 @@ mii_link_interrupt(void *dev_id)
mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
#endif
{
+#ifdef CONFIG_USE_MDIO
struct net_device *dev = dev_id;
struct fec_enet_private *fep = dev->priv;
+ volatile immap_t *immap = (immap_t *)IMAP_ADDR;
+ volatile fec_t *fecp = &(immap->im_cpm.cp_fec);
+ unsigned int ecntrl = fecp->fec_ecntrl;
+
+ /* We need the FEC enabled to access the MII
+ */
+ if ((ecntrl & FEC_ECNTRL_ETHER_EN) == 0) {
+ fecp->fec_ecntrl |= FEC_ECNTRL_ETHER_EN;
+ }
+#endif /* CONFIG_USE_MDIO */
#if 0
disable_irq(fep->mii_irq); /* disable now, enable later */
#endif
+
+#ifdef CONFIG_USE_MDIO
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */
+ if ((ecntrl & FEC_ECNTRL_ETHER_EN) == 0) {
+ fecp->fec_ecntrl = ecntrl; /* restore old settings */
+ }
+#else
+printk("%s[%d] %s: unexpected Link interrupt\n", __FILE__,__LINE__,__FUNCTION__);
+#endif /* CONFIG_USE_MDIO */
+
}
static int
@@ -1320,6 +1375,7 @@ fec_enet_open(struct net_device *dev)
* a simple way to do that.
*/
+#ifdef CONFIG_USE_MDIO
fep->sequence_done = 0;
fep->link = 0;
@@ -1327,7 +1383,6 @@ fec_enet_open(struct net_device *dev)
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, fep->phy->config);
mii_do_cmd(dev, phy_cmd_config); /* display configuration */
-
while(!fep->sequence_done)
schedule();
@@ -1335,8 +1390,12 @@ fec_enet_open(struct net_device *dev)
netif_start_queue(dev);
return 0; /* Success */
}
-
return -ENODEV; /* No PHY we understand */
+#else
+ fep->link = 1;
+ netif_start_queue(dev);
+ return 0; /* Success */
+#endif /* CONFIG_USE_MDIO */
}
@@ -1377,13 +1436,13 @@ static void set_multicast_list(struct net_device *dev)
ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
if (dev->flags&IFF_PROMISC) {
-
+
/* Log any net taps. */
printk("%s: Promiscuous mode enabled.\n", dev->name);
- ep->fec_r_cntrl |= 0x0008;
+ ep->fec_r_cntrl |= FEC_RCNTRL_PROM;
} else {
- ep->fec_r_cntrl &= ~0x0008;
+ ep->fec_r_cntrl &= ~FEC_RCNTRL_PROM;
if (dev->flags & IFF_ALLMULTI) {
/* Catch all multicast addresses, so set the
@@ -1404,7 +1463,7 @@ static void set_multicast_list(struct net_device *dev)
dmi = dev->mc_list;
for (i=0; i<dev->mc_count; i++) {
-
+
/* Only support group multicast for now.
*/
if (!(dmi->dmi_addr[0] & 1))
@@ -1448,7 +1507,7 @@ int __init fec_enet_init(void)
volatile fec_t *fecp;
bd_t *bd;
extern uint _get_IMMR(void);
-#ifdef CONFIG_RPXCLASSIC
+#ifdef CONFIG_SCC_ENET
unsigned char tmpaddr[6];
#endif
@@ -1472,8 +1531,15 @@ int __init fec_enet_init(void)
/* Whack a reset. We should wait for this.
*/
- fecp->fec_ecntrl = 1;
- udelay(10);
+ fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
+ for (i = 0;
+ (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
+ ++i) {
+ udelay(1);
+ }
+ if (i == FEC_RESET_DELAY) {
+ printk ("FEC Reset timeout!\n");
+ }
/* Set the Ethernet address. If using multiple Enets on the 8xx,
* this needs some work to get unique addresses.
@@ -1481,12 +1547,13 @@ int __init fec_enet_init(void)
eap = (unsigned char *)my_enet_addr;
iap = bd->bi_enetaddr;
-#ifdef CONFIG_RPXCLASSIC
- /* The Embedded Planet boards have only one MAC address in
- * the EEPROM, but can have two Ethernet ports. For the
- * FEC port, we create another address by setting one of
- * the address bits above something that would have (up to
- * now) been allocated.
+#ifdef CONFIG_SCC_ENET
+ /*
+ * If a board has Ethernet configured both on a SCC and the
+ * FEC, it needs (at least) 2 MAC addresses (we know that Sun
+ * disagrees, but anyway). For the FEC port, we create
+ * another address by setting one of the address bits above
+ * something that would have (up to now) been allocated.
*/
for (i=0; i<6; i++)
tmpaddr[i] = *iap++;
@@ -1494,8 +1561,9 @@ int __init fec_enet_init(void)
iap = tmpaddr;
#endif
- for (i=0; i<6; i++)
+ for (i=0; i<6; i++) {
dev->dev_addr[i] = *eap++ = *iap++;
+ }
/* Allocate memory for buffer descriptors.
*/
@@ -1518,9 +1586,6 @@ int __init fec_enet_init(void)
fep->rx_bd_base = cbd_base;
fep->tx_bd_base = cbd_base + RX_RING_SIZE;
- fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
- fep->cur_rx = fep->rx_bd_base;
-
fep->skb_cur = fep->skb_dirty = 0;
/* Initialize the receive buffer descriptors.
@@ -1565,22 +1630,27 @@ int __init fec_enet_init(void)
*/
if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
panic("Could not allocate FEC IRQ!");
+
#ifdef CONFIG_RPXCLASSIC
/* Make Port C, bit 15 an input that causes interrupts.
*/
immap->im_ioport.iop_pcpar &= ~0x0001;
immap->im_ioport.iop_pcdir &= ~0x0001;
- immap->im_ioport.iop_pcso &= ~0x0001;
- immap->im_ioport.iop_pcint |= 0x0001;
+ immap->im_ioport.iop_pcso &= ~0x0001;
+ immap->im_ioport.iop_pcint |= 0x0001;
cpm_install_handler(CPMVEC_PIO_PC15, mii_link_interrupt, dev);
/* Make LEDS reflect Link status.
*/
*((uint *) RPX_CSR_ADDR) &= ~BCSR2_FETHLEDMODE;
#endif
-#ifdef CONFIG_FADS
- if (request_8xxirq(SIU_IRQ2, mii_link_interrupt, 0, "mii", dev) != 0)
+
+#ifdef PHY_INTERRUPT
+ if (request_8xxirq(PHY_INTERRUPT, mii_link_interrupt, 0, "mii", dev) != 0)
panic("Could not allocate MII IRQ!");
+
+ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |=
+ (0x80000000 >> PHY_INTERRUPT);
#endif
dev->base_addr = (unsigned long)fecp;
@@ -1595,9 +1665,11 @@ int __init fec_enet_init(void)
dev->get_stats = fec_enet_get_stats;
dev->set_multicast_list = set_multicast_list;
+#ifdef CONFIG_USE_MDIO
for (i=0; i<NMII-1; i++)
mii_cmds[i].mii_next = &mii_cmds[i+1];
mii_free = mii_cmds;
+#endif /* CONFIG_USE_MDIO */
/* Configure all of port D for MII.
*/
@@ -1609,23 +1681,46 @@ int __init fec_enet_init(void)
immap->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */
else
immap->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */
-
+
+#ifdef CONFIG_USE_MDIO
/* Set MII speed to 2.5 MHz
*/
- fecp->fec_mii_speed = fep->phy_speed =
- ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e;
+ fecp->fec_mii_speed = fep->phy_speed =
+ (
+ ( ((bd->bi_intfreq * 1000000) + 500000) / 2500000 / 2 )
+ & 0x3F
+ ) << 1;
+#else
+ fecp->fec_mii_speed = 0; /* turn off MDIO */
+#endif /* CONFIG_USE_MDIO */
+
+ printk ("%s: FEC ENET Version 0.2, FEC irq %d"
+#ifdef PHY_INTERRUPT
+ ", MII irq %d"
+#endif
+ ", addr ",
+ dev->name, FEC_INTERRUPT
+#ifdef PHY_INTERRUPT
+ , PHY_INTERRUPT
+#endif
+ );
+ for (i=0; i<6; i++)
+ printk("%02x%c", dev->dev_addr[i], (i==5) ? '\n' : ':');
- printk("%s: FEC 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]);
+#ifdef CONFIG_USE_MDIO /* start in full duplex mode, and negotiate speed */
+ fec_restart (dev, 1);
+#else /* always use half duplex mode only */
+ fec_restart (dev, 0);
+#endif
+#ifdef CONFIG_USE_MDIO
/* Queue up command to detect the PHY and initialize the
* remainder of the interface.
*/
fep->phy_id_done = 0;
fep->phy_addr = 0;
mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
+#endif /* CONFIG_USE_MDIO */
return 0;
}
@@ -1639,7 +1734,6 @@ fec_restart(struct net_device *dev, int duplex)
{
struct fec_enet_private *fep;
int i;
- unsigned char *eap;
volatile cbd_t *bdp;
volatile immap_t *immap;
volatile fec_t *fecp;
@@ -1652,33 +1746,25 @@ fec_restart(struct net_device *dev, int duplex)
/* Whack a reset. We should wait for this.
*/
- fecp->fec_ecntrl = 1;
- udelay(10);
-
- /* Enable interrupts we wish to service.
- */
- fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
- FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
-
- /* Clear any outstanding interrupt.
- */
- fecp->fec_ievent = 0xffc0;
-
- fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
+ fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
+ for (i = 0;
+ (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
+ ++i) {
+ udelay(1);
+ }
+ if (i == FEC_RESET_DELAY) {
+ printk ("FEC Reset timeout!\n");
+ }
/* Set station address.
*/
- fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1];
- fecp->fec_addr_high = my_enet_addr[2];
-
- eap = (unsigned char *)&my_enet_addr[0];
- for (i=0; i<6; i++)
- dev->dev_addr[i] = *eap++;
+ fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1];
+ fecp->fec_addr_high = my_enet_addr[2];
/* Reset all multicast.
*/
fecp->fec_hash_table_high = 0;
- fecp->fec_hash_table_low = 0;
+ fecp->fec_hash_table_low = 0;
/* Set maximum receive buffer size.
*/
@@ -1739,12 +1825,12 @@ fec_restart(struct net_device *dev, int duplex)
/* Enable MII mode.
*/
if (duplex) {
- fecp->fec_r_cntrl = 0x04; /* MII enable */
- fecp->fec_x_cntrl = 0x04; /* FD enable */
+ fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE; /* MII enable */
+ fecp->fec_x_cntrl = FEC_TCNTRL_FDEN; /* FD enable */
}
else {
- fecp->fec_r_cntrl = 0x06; /* MII enable|No Rcv on Xmit */
- fecp->fec_x_cntrl = 0x00;
+ fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT;
+ fecp->fec_x_cntrl = 0;
}
fep->full_duplex = duplex;
@@ -1752,13 +1838,26 @@ fec_restart(struct net_device *dev, int duplex)
*/
fecp->fec_fun_code = 0x78000000;
+#ifdef CONFIG_USE_MDIO
/* Set MII speed.
*/
fecp->fec_mii_speed = fep->phy_speed;
+#endif /* CONFIG_USE_MDIO */
+
+ /* Clear any outstanding interrupt.
+ */
+ fecp->fec_ievent = 0xffc0;
+
+ fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
+
+ /* Enable interrupts we wish to service.
+ */
+ fecp->fec_imask = ( FEC_ENET_TXF | FEC_ENET_TXB |
+ FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII );
/* And last, enable the transmit and receive processing.
*/
- fecp->fec_ecntrl = 6;
+ fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
fecp->fec_r_des_active = 0x01000000;
}
@@ -1768,33 +1867,45 @@ fec_stop(struct net_device *dev)
volatile immap_t *immap;
volatile fec_t *fecp;
struct fec_enet_private *fep;
+ int i;
immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */
-
+
fecp = &(immap->im_cpm.cp_fec);
-
+
+ if ((fecp->fec_ecntrl & FEC_ECNTRL_ETHER_EN) == 0)
+ return; /* already down */
+
fep = dev->priv;
fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */
- while(!(fecp->fec_ievent & 0x10000000));
-
- /* Whack a reset. We should wait for this.
- */
- fecp->fec_ecntrl = 1;
- udelay(10);
+ for (i = 0;
+ ((fecp->fec_ievent & 0x10000000) == 0) && (i < FEC_RESET_DELAY);
+ ++i) {
+ udelay(1);
+ }
+ if (i == FEC_RESET_DELAY) {
+ printk ("FEC timeout on graceful transmit stop\n");
+ }
/* Clear outstanding MII command interrupts.
*/
fecp->fec_ievent = FEC_ENET_MII;
- /* Enable MII command finihed interrupt
+ /* Enable MII command finished interrupt
*/
fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
fecp->fec_imask = FEC_ENET_MII;
+#ifdef CONFIG_USE_MDIO
/* Set MII speed.
*/
fecp->fec_mii_speed = fep->phy_speed;
+#endif /* CONFIG_USE_MDIO */
+
+ /* Disable FEC
+ */
+ fecp->fec_ecntrl &= ~(FEC_ECNTRL_ETHER_EN);
}
diff --git a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c
index 4688d57a8..1f426ae10 100644
--- a/arch/ppc/8xx_io/uart.c
+++ b/arch/ppc/8xx_io/uart.c
@@ -53,10 +53,22 @@ extern int kgdb_output_string (const char* s, unsigned int count);
/* this defines the index into rs_table for the port to use
*/
-#ifndef CONFIG_SERIAL_CONSOLE_PORT
-#define CONFIG_SERIAL_CONSOLE_PORT 0
-#endif
-#endif
+# ifndef CONFIG_SERIAL_CONSOLE_PORT
+# ifdef CONFIG_SCC3_ENET
+# ifdef CONFIG_8xx_CONS_SMC2
+# define CONFIG_SERIAL_CONSOLE_PORT 0 /* Console on SMC2 is 1st port */
+# else
+# error "Can't use SMC1 for console with Ethernet on SCC3"
+# endif
+# else /* ! CONFIG_SCC3_ENET */
+# ifdef CONFIG_8xx_CONS_SMC2 /* Console on SMC2 */
+# define CONFIG_SERIAL_CONSOLE_PORT 1
+# else /* Console on SMC1 */
+# define CONFIG_SERIAL_CONSOLE_PORT 0
+# endif /* CONFIG_8xx_CONS_SMC2 */
+# endif /* CONFIG_SCC3_ENET */
+# endif /* CONFIG_SERIAL_CONSOLE_PORT */
+#endif /* CONFIG_SERIAL_CONSOLE */
#if 0
/* SCC2 for console
@@ -118,14 +130,22 @@ static int serial_console_setup(struct console *co, char *options);
*/
static struct serial_state rs_table[] = {
/* UART CLK PORT IRQ FLAGS NUM */
- { 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, 0 }, /* SMC1 ttyS0 */
-#ifdef CONFIG_8xxSMC2
- { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, 1 }, /* SMC2 ttyS1 */
-#endif
-#ifdef CONFIG_8xxSCC
- { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) }, /* SCC2 ttyS2 */
- { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */
-#endif
+#ifndef CONFIG_SCC3_ENET /* SMC1 not usable with Ethernet on SCC3 */
+ { 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, 0 }, /* SMC1 ttyS0 */
+#endif
+#if !defined(CONFIG_USB_MPC8xx) && !defined(CONFIG_USB_CLIENT_MPC8xx)
+# ifdef CONFIG_8xxSMC2
+ { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, 1 }, /* SMC2 ttyS1 */
+# endif
+# ifdef CONFIG_8xxSCC
+ { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) }, /* SCC2 ttyS2 */
+ { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */
+# endif
+ #else /* CONFIG_USB_xxx */
+# ifdef CONFIG_8xxSCC
+ { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */
+# endif
+#endif /* CONFIG_USB_xxx */
};
#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state))
@@ -2733,10 +2753,10 @@ int __init rs_8xx_init(void)
cp->cp_pbdir &= ~iobits;
cp->cp_pbodr &= ~iobits;
#else
+ iobits = 0xc0;
if (idx == 0) {
/* SMC1 on Port B, like all 8xx.
*/
- iobits = 0xc0;
cp->cp_pbpar |= iobits;
cp->cp_pbdir &= ~iobits;
cp->cp_pbodr &= ~iobits;
@@ -2744,7 +2764,6 @@ int __init rs_8xx_init(void)
else {
/* SMC2 is on Port A.
*/
- iobits = 0x300;
immap->im_ioport.iop_papar |= iobits;
immap->im_ioport.iop_padir &= ~iobits;
immap->im_ioport.iop_paodr &= ~iobits;
@@ -2836,6 +2855,9 @@ static int __init serial_console_setup(struct console *co, char *options)
for (bidx = 0; bidx < (sizeof(baud_table) / sizeof(int)); bidx++)
if (bd->bi_baudrate == baud_table[bidx])
break;
+ /* make sure we have a useful value */
+ if (bidx == (sizeof(baud_table) / sizeof(int)))
+ bidx = 13; /* B9600 */
co->cflag = CREAD|CLOCAL|bidx|CS8;
baud_idx = bidx;
@@ -2958,7 +2980,7 @@ static int __init serial_console_setup(struct console *co, char *options)
*/
chan = smc_chan_map[idx];
cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG;
- printk("");
+ printk("%s", "");
while (cp->cp_cpcr & CPM_CR_FLG);
/* Set UART mode, 8 bit, no parity, one stop.
diff --git a/arch/ppc/config.in b/arch/ppc/config.in
index 3b4c2c141..2d07ee819 100644
--- a/arch/ppc/config.in
+++ b/arch/ppc/config.in
@@ -57,14 +57,25 @@ if [ "$CONFIG_8xx" = "y" ]; then
"RPX-Lite CONFIG_RPXLITE \
RPX-Classic CONFIG_RPXCLASSIC \
BSE-IP CONFIG_BSEIP \
- TQM8xxL CONFIG_TQM8xxL \
- TQM860L CONFIG_TQM860L \
- TQM860 CONFIG_TQM860 \
+ TQM823L CONFIG_TQM823L \
+ TQM850L CONFIG_TQM850L \
+ TQM855L CONFIG_TQM855L \
+ TQM860L CONFIG_TQM860L \
+ FPS850L CONFIG_FPS850L \
+ TQM860 CONFIG_TQM860 \
+ SPD823TS CONFIG_SPD823TS \
+ IVMS8 CONFIG_IVMS8 \
+ SM850 CONFIG_SM850 \
MBX CONFIG_MBX \
WinCept CONFIG_WINCEPT" RPX-Lite
-
- if [ "$CONFIG_TQM8xxL" = "y" ]; then
- bool 'FPS850 Mainboard' CONFIG_FPS850
+
+ if [ "$CONFIG_TQM823L" = "y" -o \
+ "$CONFIG_TQM850L" = "y" -o \
+ "$CONFIG_FPS850L" = "y" -o \
+ "$CONFIG_TQM855L" = "y" -o \
+ "$CONFIG_TQM860L" = "y" -o \
+ "$CONFIG_SM850" = "y" ]; then
+ define_bool CONFIG_TQM8xxL y
fi
fi
@@ -299,6 +310,11 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then
bool ' Support for ADB keyboard (old driver)' CONFIG_ADB_KEYBOARD
fi
fi
+ # This is for drivers/macintosh/mac_hid.o, which is needed if the input
+ # layer is used.
+ if [ "$CONFIG_INPUT" != "n" ]; then
+ define_bool CONFIG_MAC_HID y
+ fi
fi
endmenu
diff --git a/arch/ppc/configs/IVMS8_defconfig b/arch/ppc/configs/IVMS8_defconfig
new file mode 100644
index 000000000..f73b69efc
--- /dev/null
+++ b/arch/ppc/configs/IVMS8_defconfig
@@ -0,0 +1,452 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx 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 is not set
+# CONFIG_BSEIP is not set
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
+# CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
+# CONFIG_TQM860 is not set
+# CONFIG_SPD823TS is not set
+CONFIG_IVMS8=y
+# CONFIG_SM850 is not set
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+CONFIG_MATH_EMULATION=y
+CONFIG_SASH=y
+CONFIG_SASH_PATH="/bin/sash"
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV 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 is not set
+# 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
+
+#
+# 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=y
+# 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_IDESCSI is not set
+
+#
+# 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_MPC8xx_IDE=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+
+#
+# SCSI support
+#
+# CONFIG_SCSI 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_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT 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
+# CONFIG_FLASH 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_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_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=y
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# 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=y
+# 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=y
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# MPC8xx CPM Options
+#
+# CONFIG_SCC_ENET is not set
+CONFIG_FEC_ENET=y
+CONFIG_USE_MDIO=y
+CONFIG_ENET_BIG_BUFFERS=y
+# CONFIG_8xxSMC2 is not set
+# CONFIG_8xxSCC is not set
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/SM850_defconfig b/arch/ppc/configs/SM850_defconfig
new file mode 100644
index 000000000..bab9ddd55
--- /dev/null
+++ b/arch/ppc/configs/SM850_defconfig
@@ -0,0 +1,420 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx 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 is not set
+# CONFIG_BSEIP is not set
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
+# CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
+# CONFIG_TQM860 is not set
+# CONFIG_SPD823TS is not set
+CONFIG_SM850=y
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+CONFIG_TQM8xxL=y
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+CONFIG_MATH_EMULATION=y
+CONFIG_SASH=y
+CONFIG_SASH_PATH="/bin/sash"
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV 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 is not set
+# 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
+
+#
+# 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
+
+#
+# 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_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT 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
+CONFIG_FLASH=y
+CONFIG_AMD_FLASH=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_DRM 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_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 is not set
+# 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=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+# CONFIG_SCC1_ENET is not set
+# CONFIG_SCC2_ENET is not set
+CONFIG_SCC3_ENET=y
+# CONFIG_FEC_ENET is not set
+CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xxSMC2=y
+CONFIG_8xx_ALTSMC2=y
+CONFIG_8xx_CONS_SMC2=y
+# CONFIG_8xxSCC is not set
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+CONFIG_8xx_CPU6=y
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/SPD823TS_defconfig b/arch/ppc/configs/SPD823TS_defconfig
new file mode 100644
index 000000000..899b29436
--- /dev/null
+++ b/arch/ppc/configs/SPD823TS_defconfig
@@ -0,0 +1,416 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx 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 is not set
+# CONFIG_BSEIP is not set
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
+# CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
+# CONFIG_TQM860 is not set
+CONFIG_SPD823TS=y
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+CONFIG_MATH_EMULATION=y
+CONFIG_SASH=y
+CONFIG_SASH_PATH="/bin/sash"
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV 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 is not set
+# 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
+
+#
+# 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
+
+#
+# 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_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT 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
+# CONFIG_FLASH 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_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_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 is not set
+# 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=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+# CONFIG_SCC1_ENET is not set
+CONFIG_SCC2_ENET=y
+# CONFIG_FEC_ENET is not set
+CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xxSMC2=y
+CONFIG_8xx_ALTSMC2=y
+# CONFIG_8xx_CONS_SMC2 is not set
+# CONFIG_8xxSCC is not set
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/TQM823L_defconfig b/arch/ppc/configs/TQM823L_defconfig
new file mode 100644
index 000000000..9724fd901
--- /dev/null
+++ b/arch/ppc/configs/TQM823L_defconfig
@@ -0,0 +1,419 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx 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 is not set
+# CONFIG_BSEIP is not set
+CONFIG_TQM823L=y
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
+# CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
+# CONFIG_TQM860 is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+CONFIG_TQM8xxL=y
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+CONFIG_MATH_EMULATION=y
+CONFIG_SASH=y
+CONFIG_SASH_PATH="/bin/sash"
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV 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 is not set
+# 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
+
+#
+# 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
+
+#
+# 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_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT 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
+CONFIG_FLASH=y
+CONFIG_AMD_FLASH=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_DRM 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_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 is not set
+# 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=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+# CONFIG_SCC1_ENET is not set
+CONFIG_SCC2_ENET=y
+# CONFIG_SCC3_ENET is not set
+# CONFIG_FEC_ENET is not set
+CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xxSMC2=y
+CONFIG_8xx_ALTSMC2=y
+# CONFIG_8xx_CONS_SMC2 is not set
+# CONFIG_8xxSCC is not set
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/TQM850L_defconfig b/arch/ppc/configs/TQM850L_defconfig
new file mode 100644
index 000000000..eb1e130ad
--- /dev/null
+++ b/arch/ppc/configs/TQM850L_defconfig
@@ -0,0 +1,419 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx 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 is not set
+# CONFIG_BSEIP is not set
+# CONFIG_TQM823L is not set
+CONFIG_TQM850L=y
+# CONFIG_TQM855L is not set
+# CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
+# CONFIG_TQM860 is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+CONFIG_TQM8xxL=y
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+CONFIG_MATH_EMULATION=y
+CONFIG_SASH=y
+CONFIG_SASH_PATH="/bin/sash"
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV 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 is not set
+# 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
+
+#
+# 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
+
+#
+# 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_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT 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
+CONFIG_FLASH=y
+CONFIG_AMD_FLASH=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_DRM 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_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 is not set
+# 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=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+# CONFIG_SCC1_ENET is not set
+CONFIG_SCC2_ENET=y
+# CONFIG_SCC3_ENET is not set
+# CONFIG_FEC_ENET is not set
+CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xxSMC2=y
+CONFIG_8xx_ALTSMC2=y
+# CONFIG_8xx_CONS_SMC2 is not set
+# CONFIG_8xxSCC is not set
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+CONFIG_8xx_CPU6=y
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/TQM860L_defconfig b/arch/ppc/configs/TQM860L_defconfig
new file mode 100644
index 000000000..ebe47c109
--- /dev/null
+++ b/arch/ppc/configs/TQM860L_defconfig
@@ -0,0 +1,419 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+# CONFIG_4xx 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 is not set
+# CONFIG_BSEIP is not set
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
+CONFIG_TQM860L=y
+# CONFIG_FPS850L is not set
+# CONFIG_TQM860 is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+CONFIG_TQM8xxL=y
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+CONFIG_MATH_EMULATION=y
+CONFIG_SASH=y
+CONFIG_SASH_PATH="/bin/sash"
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# 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
+# 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 is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV 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 is not set
+# 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
+
+#
+# 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
+
+#
+# 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_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
+# CONFIG_OAKNET 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT 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
+CONFIG_FLASH=y
+CONFIG_AMD_FLASH=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_DRM 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_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 is not set
+# 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=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# 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
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+CONFIG_SCC1_ENET=y
+# CONFIG_SCC2_ENET is not set
+# CONFIG_SCC3_ENET is not set
+# CONFIG_FEC_ENET is not set
+CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xxSMC2=y
+# CONFIG_8xx_ALTSMC2 is not set
+# CONFIG_8xx_CONS_SMC2 is not set
+# CONFIG_8xxSCC is not set
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig
index 210887de7..6017c8a1c 100644
--- a/arch/ppc/configs/common_defconfig
+++ b/arch/ppc/configs/common_defconfig
@@ -295,11 +295,11 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_AHA152X is not set
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
-CONFIG_SCSI_AIC7XXX=y
-# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
-CONFIG_AIC7XXX_PROC_STATS=y
-CONFIG_AIC7XXX_RESET_DELAY=15
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_SCSI_AIC7XXX_OLD=m
+# CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT is not set
+CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8
+CONFIG_AIC7XXX_OLD_PROC_STATS=y
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig
index 210887de7..d0c66555e 100644
--- a/arch/ppc/defconfig
+++ b/arch/ppc/defconfig
@@ -296,10 +296,9 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
CONFIG_SCSI_AIC7XXX=y
-# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
-CONFIG_AIC7XXX_PROC_STATS=y
-CONFIG_AIC7XXX_RESET_DELAY=15
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
+CONFIG_AIC7XXX_RESET_DELAY=15000
+# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 545fce0cd..c9bc4e23f 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o
include $(TOPDIR)/Rules.make
+entry.o: entry.S ppc_defs.h
head.o: head.S ppc_defs.h
head_4xx.o: head_4xx.S ppc_defs.h
head_8xx.o: head_8xx.S ppc_defs.h
diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c
index 914ed02ff..684b1889a 100644
--- a/arch/ppc/kernel/chrp_pci.c
+++ b/arch/ppc/kernel/chrp_pci.c
@@ -298,8 +298,9 @@ static void __init gg2_pcibios_fixup_bus(struct pci_bus *bus)
bus->resource[1] = &gg2_resources.pci_mem;
}
-static void process_bridge_ranges(struct pci_controller *hose,
- struct device_node *dev, int index)
+/* this is used by the pmac_pci code too... - paulus */
+void process_bridge_ranges(struct pci_controller *hose,
+ struct device_node *dev, int primary)
{
unsigned int *ranges;
int rlen = 0;
@@ -316,31 +317,34 @@ static void process_bridge_ranges(struct pci_controller *hose,
break;
hose->io_base_phys = ranges[3];
hose->io_base_virt = ioremap(ranges[3], ranges[5]);
- if (index == 0) {
+ if (primary)
isa_io_base = (unsigned long) hose->io_base_virt;
- printk("isa_io_base=%lx\n", isa_io_base);
- }
res = &hose->io_resource;
res->flags = IORESOURCE_IO;
+ res->start = ranges[2];
break;
case 2: /* memory space */
- if (index == 0 && ranges[1] == 0 && ranges[2] == 0){
- isa_mem_base = ranges[3];
- printk("isa_mem_base=%lx\n", isa_mem_base);
+ memno = 0;
+ if (ranges[1] == 0 && ranges[2] == 0
+ && ranges[5] <= (16 << 20)) {
+ /* 1st 16MB, i.e. ISA memory area */
+ if (primary)
+ isa_mem_base = ranges[3];
+ memno = 1;
}
- if (memno == 0) {
+ while (memno < 3 && hose->mem_resources[memno].flags)
+ ++memno;
+ if (memno == 0)
hose->pci_mem_offset = ranges[3] - ranges[2];
- printk("pci_mem_offset=%lx for this bridge\n",
- hose->pci_mem_offset);
+ if (memno < 3) {
+ res = &hose->mem_resources[memno];
+ res->flags = IORESOURCE_MEM;
+ res->start = ranges[3];
}
- res = &hose->mem_resources[memno];
- res->flags = IORESOURCE_MEM;
- ++memno;
break;
}
if (res != NULL) {
res->name = dev->full_name;
- res->start = ranges[3];
res->end = res->start + ranges[5] - 1;
res->parent = NULL;
res->sibling = NULL;
@@ -401,7 +405,7 @@ ibm_add_bridges(struct device_node *dev)
hose->cfg_addr = (volatile unsigned int *) cfg;
hose->cfg_data = cfg + 0x10;
- process_bridge_ranges(hose, dev, index);
+ process_bridge_ranges(hose, dev, index == 0);
#ifdef CONFIG_POWER3
openpic_setup_ISU(index, opprop[index+1]);
diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c
index 04b812268..b7136d001 100644
--- a/arch/ppc/kernel/chrp_setup.c
+++ b/arch/ppc/kernel/chrp_setup.c
@@ -84,7 +84,7 @@ extern void mackbd_leds(unsigned char leds);
extern void mackbd_init_hw(void);
extern unsigned char mackbd_sysrq_xlate[128];
-kdev_t boot_dev;
+extern kdev_t boot_dev;
extern PTE *Hash, *Hash_end;
extern unsigned long Hash_size, Hash_mask;
@@ -237,7 +237,6 @@ static void __init sio_init(void)
void __init
chrp_setup_arch(void)
{
- extern char cmd_line[];
struct device_node *device;
/* init to some ~sane value until calibrate_delay() runs */
@@ -252,7 +251,6 @@ chrp_setup_arch(void)
else
#endif
ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
- printk("Boot arguments: %s\n", cmd_line);
/* Lookup PCI host bridges */
chrp_find_bridges();
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index f296d1606..89f5b6d68 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -1135,7 +1135,7 @@ copy_and_flush:
#ifdef CONFIG_APUS
/*
* On APUS the physical base address of the kernel is not known at compile
- * time, which means the __pa/__va constants used are incorect. In the
+ * time, which means the __pa/__va constants used are incorrect. In the
* __init section is recorded the virtual addresses of instructions using
* these constants, so all that has to be done is fix these before
* continuing the kernel boot.
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index 40579ce63..3bdf141e8 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -968,26 +968,6 @@ _GLOBAL(set_context)
SYNC
blr
-/* Jump into the system reset for the rom.
- * We first disable the MMU, and then jump to the ROM reset address.
- *
- * r3 is the board info structure, r4 is the location for starting.
- * I use this for building a small kernel that can load other kernels,
- * rather than trying to write or rely on a rom monitor that can tftp load.
- */
- .globl m8xx_gorom
-m8xx_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
-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
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index 279bccf0a..6609ecda2 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -7,8 +7,8 @@
* Copyright (C) 1992 Linus Torvalds
* Adapted from arch/i386 by Gary Thomas
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- * Updated and modified by Cort Dougan (cort@cs.nmt.edu)
- * Copyright (C) 1996 Cort Dougan
+ * Updated and modified by Cort Dougan <cort@fsmlabs.com>
+ * Copyright (C) 1996-2001 Cort Dougan
* Adapted for Power Macintosh by Paul Mackerras
* Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
* Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
@@ -258,7 +258,10 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
retval = setup_irq(irq, action);
if (retval)
+ {
kfree(action);
+ return retval;
+ }
return 0;
}
@@ -464,13 +467,11 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
ppc_spurious_interrupts++;
printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
/* We can't call disable_irq here, it would deadlock */
- if (!desc->depth)
- desc->depth = 1;
+ ++desc->depth;
desc->status |= IRQ_DISABLED;
- /* This is not a real spurrious interrupt, we
- * have to eoi it, so we jump to out
- */
mask_irq(irq);
+ /* This is a real interrupt, we have to eoi it,
+ so we jump to out */
goto out;
}
status &= ~IRQ_PENDING; /* we commit to handling */
diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c
index 91114e459..4185e5b44 100644
--- a/arch/ppc/kernel/m8260_setup.c
+++ b/arch/ppc/kernel/m8260_setup.c
@@ -85,10 +85,6 @@ void __init adbdev_init(void)
void __init
m8260_setup_arch(void)
{
- extern char cmd_line[];
-
- printk("Boot arguments: %s\n", cmd_line);
-
/* Reset the Communication Processor Module.
*/
m8260_cpm_reset();
diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c
index fb585641c..1d3260d78 100644
--- a/arch/ppc/kernel/m8xx_setup.c
+++ b/arch/ppc/kernel/m8xx_setup.c
@@ -32,6 +32,7 @@
#include <linux/init.h>
#include <linux/blk.h>
#include <linux/ioport.h>
+#include <asm/mpc8xx.h> /* Before ide.h to avoid warning: `MAX_HWIFS' redefined */
#include <linux/ide.h>
#include <linux/bootmem.h>
@@ -41,7 +42,6 @@
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/ide.h>
-#include <asm/mpc8xx.h>
#include <asm/8xx_immap.h>
#include <asm/machdep.h>
@@ -52,19 +52,65 @@ static int m8xx_set_rtc_time(unsigned long time);
unsigned long m8xx_get_rtc_time(void);
void m8xx_calibrate_decr(void);
-#if 0
-extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int mackbd_getkeycode(unsigned int scancode);
-extern int mackbd_pretranslate(unsigned char scancode, char raw_mode);
-extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
- char raw_mode);
-extern char mackbd_unexpected_up(unsigned char keycode);
-extern void mackbd_leds(unsigned char leds);
-extern void mackbd_init_hw(void);
-#endif
-
unsigned char __res[sizeof(bd_t)];
unsigned long empty_zero_page[1024];
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+
+#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
+#include "../../../drivers/ide/ide_modes.h"
+
+static void m8xx_ide_tuneproc(ide_drive_t *drive, byte pio);
+
+typedef struct ide_ioport_desc {
+ unsigned long base_off; /* Offset to PCMCIA memory */
+ ide_ioreg_t reg_off[IDE_NR_PORTS]; /* controller reg. offsets */
+ int irq; /* IRQ */
+} ide_ioport_desc_t;
+
+ide_ioport_desc_t ioport_dsc[MAX_HWIFS] = {
+#ifdef IDE0_BASE_OFFSET
+ { IDE0_BASE_OFFSET,
+ {
+ IDE0_DATA_REG_OFFSET,
+ IDE0_ERROR_REG_OFFSET,
+ IDE0_NSECTOR_REG_OFFSET,
+ IDE0_SECTOR_REG_OFFSET,
+ IDE0_LCYL_REG_OFFSET,
+ IDE0_HCYL_REG_OFFSET,
+ IDE0_SELECT_REG_OFFSET,
+ IDE0_STATUS_REG_OFFSET,
+ IDE0_CONTROL_REG_OFFSET,
+ IDE0_IRQ_REG_OFFSET,
+ },
+ IDE0_INTERRUPT,
+ },
+# ifdef IDE1_BASE_OFFSET
+ { IDE1_BASE_OFFSET,
+ {
+ IDE1_DATA_REG_OFFSET,
+ IDE1_ERROR_REG_OFFSET,
+ IDE1_NSECTOR_REG_OFFSET,
+ IDE1_SECTOR_REG_OFFSET,
+ IDE1_LCYL_REG_OFFSET,
+ IDE1_HCYL_REG_OFFSET,
+ IDE1_SELECT_REG_OFFSET,
+ IDE1_STATUS_REG_OFFSET,
+ IDE1_CONTROL_REG_OFFSET,
+ IDE1_IRQ_REG_OFFSET,
+ },
+ IDE1_INTERRUPT,
+ },
+# endif /* IDE1_BASE_OFFSET */
+#endif /* IDE0_BASE_OFFSET */
+};
+
+ide_pio_timings_t ide_pio_clocks[6];
+
+/* Make clock cycles and always round up */
+#define PCMCIA_MK_CLKS( t, T ) (( (t) * (T) + 999U ) / 1000U )
+
+#endif /* CONFIG_BLK_DEV_MPC8xx_IDE */
+#endif /* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */
#ifdef CONFIG_BLK_DEV_RAM
extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
@@ -77,6 +123,8 @@ extern char saved_command_line[256];
extern unsigned long find_available_memory(void);
extern void m8xx_cpm_reset(uint);
+static void ide_interrupt_handler(void* dev_id);
+
void __init adbdev_init(void)
{
}
@@ -85,12 +133,9 @@ void __init
m8xx_setup_arch(void)
{
int cpm_page;
- extern char cmd_line[];
cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE);
- printk("Boot arguments: %s\n", cmd_line);
-
/* Reset the Communication Processor Module.
*/
m8xx_cpm_reset(cpm_page);
@@ -137,7 +182,7 @@ abort(void)
*/
void timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
{
- printk("timebase_interrupt()\n");
+ printk ("timebase_interrupt()\n");
}
/* The decrementer counts at the system (internal) clock frequency divided by
@@ -164,7 +209,7 @@ void __init m8xx_calibrate_decr(void)
fp = (binfo->bi_intfreq * 1000000) / 16;
freq = fp*60; /* try to make freq/1e6 an integer */
divisor = 60;
- printk("time_init: decrementer frequency = %d/%d\n", freq, divisor);
+ printk("Decrementer Frequency = %d/%d\n", freq, divisor);
tb_ticks_per_jiffy = freq / HZ / divisor;
tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
@@ -232,9 +277,21 @@ m8xx_get_rtc_time(void)
void
m8xx_restart(char *cmd)
{
- extern void m8xx_gorom(void);
+ __volatile__ unsigned char dummy;
+ uint msr;
- m8xx_gorom();
+ cli();
+ ((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr |= 0x00000080;
+
+ /* Clear the ME bit in MSR to cause checkstop on machine check
+ */
+ __asm__("mfmsr %0" : "=r" (msr) );
+ msr &= ~0x1000;
+ __asm__("mtmsr %0" : : "r" (msr) );
+
+ dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0];
+ printk("Restart failed\n");
+ while(1);
}
void
@@ -257,8 +314,8 @@ int m8xx_setup_residual(char *buffer)
bp = (bd_t *)__res;
- len += sprintf(len+buffer,"clock\t\t: %dMHz\n"
- "bus clock\t: %dMHz\n",
+ len += sprintf(len+buffer,"clock\t\t: %ldMHz\n"
+ "bus clock\t: %ldMHz\n",
bp->bi_intfreq /*/ 1000000*/,
bp->bi_busfreq /*/ 1000000*/);
@@ -298,17 +355,13 @@ m8xx_init_IRQ(void)
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-/* Define this to make a PCMCIA ATA Flash card work.
-*/
-#define ATA_FLASH 1
-
/*
* IDE stuff.
*/
void
m8xx_ide_insw(ide_ioreg_t port, void *buf, int ns)
{
-#ifdef ATA_FLASH
+#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
ide_insw(port, buf, ns);
#else
ide_insw(port+_IO_BASE, buf, ns);
@@ -318,7 +371,7 @@ m8xx_ide_insw(ide_ioreg_t port, void *buf, int ns)
void
m8xx_ide_outsw(ide_ioreg_t port, void *buf, int ns)
{
-#ifdef ATA_FLASH
+#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
ide_outsw(port, buf, ns);
#else
ide_outsw(port+_IO_BASE, buf, ns);
@@ -328,8 +381,11 @@ m8xx_ide_outsw(ide_ioreg_t port, void *buf, int ns)
int
m8xx_ide_default_irq(ide_ioreg_t base)
{
-#ifdef ATA_FLASH
- return PCMCIA_INTERRUPT;
+#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
+ if (base >= MAX_HWIFS)
+ return 0;
+
+ return (ioport_dsc[base].irq);
#else
return 14;
#endif
@@ -348,60 +404,105 @@ m8xx_ide_request_irq(unsigned int irq,
const char *device,
void *dev_id)
{
-#ifdef ATA_FLASH
+#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
return request_8xxirq(irq, handler, flags, device, dev_id);
#else
return request_irq(irq, handler, flags, device, dev_id);
#endif
}
-/* We can use an external IDE controller or wire the IDE interface to
- * the internal PCMCIA controller.
+/* We can use an external IDE controller
+ * or wire the IDE interface to the internal PCMCIA controller.
+ *
+ * See include/linux/ide.h for definition of hw_regs_t (p, base)
*/
-void __init m8xx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq)
+void m8xx_ide_init_hwif_ports(hw_regs_t *hw,
+ ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
{
- ide_ioreg_t port = base;
+ ide_ioreg_t *p = hw->io_ports;
int i;
-#ifdef ATA_FLASH
+#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
volatile pcmconf8xx_t *pcmp;
+
+ static unsigned long pcmcia_base = 0;
+#else
+ ide_ioreg_t port = data_port; /* ??? XXX ??? XXX */
#endif
+ unsigned long base;
-#ifdef ATA_FLASH
+#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
*p = 0;
- *irq = 0;
+ if (irq)
+ *irq = 0;
+
+ pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
- if (base != 0) /* Only map the first ATA flash drive */
+ if (!pcmcia_base) {
+ /* relies PCMCIA registers being set up by firmware */
+ pcmcia_base = (unsigned long) ioremap(PCMCIA_MEM_ADDR,
+ PCMCIA_MEM_SIZE);
+
+ /* Compute clock cycles for PIO timings */
+ for (i=0; i<6; ++i) {
+ bd_t *binfo = (bd_t *)__res;
+
+ ide_pio_clocks[i].hold_time =
+ PCMCIA_MK_CLKS (ide_pio_timings[i].hold_time,
+ binfo->bi_busfreq);
+ ide_pio_clocks[i].setup_time =
+ PCMCIA_MK_CLKS (ide_pio_timings[i].setup_time,
+ binfo->bi_busfreq);
+ ide_pio_clocks[i].active_time =
+ PCMCIA_MK_CLKS (ide_pio_timings[i].active_time,
+ binfo->bi_busfreq);
+ ide_pio_clocks[i].cycle_time =
+ PCMCIA_MK_CLKS (ide_pio_timings[i].cycle_time,
+ binfo->bi_busfreq);
+#if 0
+ printk ("PIO mode %d timings: %d/%d/%d => %d/%d/%d\n",
+ i,
+ ide_pio_clocks[i].setup_time,
+ ide_pio_clocks[i].active_time,
+ ide_pio_clocks[i].hold_time,
+ ide_pio_clocks[i].cycle_time,
+ ide_pio_timings[i].setup_time,
+ ide_pio_timings[i].active_time,
+ ide_pio_timings[i].hold_time,
+ ide_pio_timings[i].cycle_time);
+#endif
+ }
+ }
+
+ if (data_port >= MAX_HWIFS)
return;
- pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
+ base = pcmcia_base + ioport_dsc[data_port].base_off;
+
+# if (!defined(CONFIG_SPD823TS) && !defined(CONFIG_IVMS8))
+ /* SPD823TS and IVMS8 have a direct connection */
if (pcmp->pcmc_pipr & 0x18000000)
return; /* No card in slot */
+# endif /* CONFIG_SPD823TS, CONFIG_IVMS8 */
- base = (unsigned long) ioremap(PCMCIA_MEM_ADDR, 0x200);
+ for (i = 0; i < IDE_NR_PORTS; ++i) {
+ *p++ = base + ioport_dsc[data_port].reg_off[i];
+ }
- /* For the M-Systems ATA card, the first 8 registers map 1:1.
- * The following register, control/Altstatus, is located at 0x0e.
- * Following that, the irq offset, is not used, so we place it in
- * an unused location, 0x0a.
- */
- *p++ = base + 8;
- for (i = 1; i < 8; ++i)
- *p++ = base + i;
- *p++ = base + 0x0e; /* control/altstatus */
- *p = base + 0x0a; /* IRQ, not used */
- if (irq)
- *irq = PCMCIA_INTERRUPT;
+ if (irq) {
+ *irq = ioport_dsc[data_port].irq;
+ }
- /* Configure the interface for this interrupt.
- */
- pcmp->pcmc_pgcra = (mk_int_int_mask(PCMCIA_INTERRUPT) << 24) |
- (mk_int_int_mask(PCMCIA_INTERRUPT) << 16);
+ /* register routine to tune PIO mode */
+ ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc;
- /* Enable status change interrupt from slot A.
- */
- pcmp->pcmc_per = 0xff100000;
- pcmp->pcmc_pscr = ~0;
-#else
+ /* Enable Harddisk Interrupt,
+ * and make it edge sensitive
+ */
+ hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_handler;
+ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |=
+ (0x80000000 >> ioport_dsc[data_port].irq);
+
+#else /* ! CONFIG_BLK_DEV_MPC8xx_IDE */
/* Just a regular IDE drive on some I/O port.
*/
@@ -411,10 +512,84 @@ void __init m8xx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq)
*p++ = base + 0x206;
if (irq != NULL)
*irq = 0;
-#endif
+#endif /* CONFIG_BLK_DEV_MPC8xx_IDE */
}
+#endif /* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */
+
+
+/* -------------------------------------------------------------------- */
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
+
+/* PCMCIA Timing */
+#ifndef PCMCIA_SHT
+#define PCMCIA_SHT(t) ((t & 0x0F)<<16) /* Strobe Hold Time */
+#define PCMCIA_SST(t) ((t & 0x0F)<<12) /* Strobe Setup Time */
+#define PCMCIA_SL(t) ((t==32) ? 0 : ((t & 0x1F)<<7)) /* Strobe Length */
#endif
+
+/* Calculate PIO timings */
+static void
+m8xx_ide_tuneproc(ide_drive_t *drive, byte pio)
+{
+ volatile pcmconf8xx_t *pcmp;
+ ide_pio_data_t d;
+ ulong timing, mask, reg;
+
+ pio = ide_get_best_pio_mode(drive, pio, 4, &d);
+
+#if 1
+ printk("%s[%d] %s: best PIO mode: %d\n",
+ __FILE__,__LINE__,__FUNCTION__, pio);
+#endif
+ pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
+
+ mask = ~(PCMCIA_SHT(0xFF) | PCMCIA_SST(0xFF) | PCMCIA_SL(0xFF));
+
+ timing = PCMCIA_SHT(ide_pio_clocks[pio].hold_time )
+ | PCMCIA_SST(ide_pio_clocks[pio].setup_time )
+ | PCMCIA_SL (ide_pio_clocks[pio].active_time)
+ ;
+
+#if 1
+ printk ("Setting timing bits 0x%08lx in PCMCIA controller\n", timing);
+#endif
+ if ((reg = pcmp->pcmc_por0 & mask) != 0)
+ pcmp->pcmc_por0 = reg | timing;
+
+ if ((reg = pcmp->pcmc_por1 & mask) != 0)
+ pcmp->pcmc_por1 = reg | timing;
+
+ if ((reg = pcmp->pcmc_por2 & mask) != 0)
+ pcmp->pcmc_por2 = reg | timing;
+
+ if ((reg = pcmp->pcmc_por3 & mask) != 0)
+ pcmp->pcmc_por3 = reg | timing;
+
+ if ((reg = pcmp->pcmc_por4 & mask) != 0)
+ pcmp->pcmc_por4 = reg | timing;
+
+ if ((reg = pcmp->pcmc_por5 & mask) != 0)
+ pcmp->pcmc_por5 = reg | timing;
+
+ if ((reg = pcmp->pcmc_por6 & mask) != 0)
+ pcmp->pcmc_por6 = reg | timing;
+
+ if ((reg = pcmp->pcmc_por7 & mask) != 0)
+ pcmp->pcmc_por7 = reg | timing;
+}
+
+void ide_interrupt_handler (void *dev)
+{
+}
+
+#endif /* CONFIG_BLK_DEV_MPC8xx_IDE */
+#endif /* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */
+
+/* -------------------------------------------------------------------- */
+
void __init
m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
@@ -490,7 +665,6 @@ m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_ide_md.default_io_base = m8xx_ide_default_io_base;
ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid;
ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports;
- ppc_ide_md.ide_request_irq = m8xx_ide_request_irq;
ppc_ide_md.io_base = _IO_BASE;
#endif
diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c
index 0cbd4f553..919cb57eb 100644
--- a/arch/ppc/kernel/open_pic.c
+++ b/arch/ppc/kernel/open_pic.c
@@ -42,6 +42,45 @@ static volatile unsigned char* chrp_int_ack_special;
OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU];
+/* Global Operations */
+static void openpic_disable_8259_pass_through(void);
+static u_int openpic_irq(void);
+static void openpic_eoi(void);
+static void openpic_set_priority(u_int pri);
+static void openpic_set_spurious(u_int vector);
+
+#ifdef CONFIG_SMP
+/* Interprocessor Interrupts */
+static void openpic_initipi(u_int ipi, u_int pri, u_int vector);
+static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
+#endif
+
+/* Timer Interrupts */
+static void openpic_inittimer(u_int timer, u_int pri, u_int vector);
+static void openpic_maptimer(u_int timer, u_int cpumask);
+
+/* Interrupt Sources */
+static void openpic_enable_irq(u_int irq);
+static void openpic_disable_irq(u_int irq);
+static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity,
+ int is_level);
+static void openpic_mapirq(u_int irq, u_int cpumask);
+
+/*
+ * These functions are not used but the code is kept here
+ * for completeness and future reference.
+ */
+#ifdef notused
+static void openpic_reset(void);
+static void openpic_enable_8259_pass_through(void);
+static u_int openpic_get_priority(void);
+static u_int openpic_get_spurious(void);
+static void openpic_set_sense(u_int irq, int sense);
+#endif /* notused */
+
+/*
+ * Description of the openpic for the higher-level irq code
+ */
static void openpic_end_irq(unsigned int irq_nr);
static void openpic_ack_irq(unsigned int irq_nr);
static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask);
@@ -370,17 +409,19 @@ void find_ISUs(void)
#endif
}
-static inline void openpic_reset(void)
+#ifdef notused
+static void openpic_reset(void)
{
openpic_setfield(&OpenPIC->Global.Global_Configuration0,
OPENPIC_CONFIG_RESET);
}
-static inline void openpic_enable_8259_pass_through(void)
+static void openpic_enable_8259_pass_through(void)
{
openpic_clearfield(&OpenPIC->Global.Global_Configuration0,
OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
}
+#endif /* notused */
static void openpic_disable_8259_pass_through(void)
{
@@ -412,8 +453,8 @@ static void openpic_eoi(void)
(void)openpic_read(&OpenPIC->THIS_CPU.EOI);
}
-
-static inline u_int openpic_get_priority(void)
+#ifdef notused
+static u_int openpic_get_priority(void)
{
DECL_THIS_CPU;
@@ -421,6 +462,7 @@ static inline u_int openpic_get_priority(void)
return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority,
OPENPIC_CURRENT_TASK_PRIORITY_MASK);
}
+#endif /* notused */
static void openpic_set_priority(u_int pri)
{
@@ -435,11 +477,13 @@ static void openpic_set_priority(u_int pri)
/*
* Get/set the spurious vector
*/
-static inline u_int openpic_get_spurious(void)
+#ifdef notused
+static u_int openpic_get_spurious(void)
{
return openpic_readfield(&OpenPIC->Global.Spurious_Vector,
OPENPIC_VECTOR_MASK);
}
+#endif /* notused */
static void openpic_set_spurious(u_int vec)
{
@@ -604,21 +648,6 @@ static void __init openpic_maptimer(u_int timer, u_int cpumask)
static void openpic_enable_irq(u_int irq)
{
check_arg_irq(irq);
-
- /*
- * Never want to disable a timer or ipi irq
- * (only want to disable irqs within an ISU).
- */
- if (((irq >= OPENPIC_VEC_IPI+open_pic_irq_offset) &&
- (irq < OPENPIC_VEC_IPI+open_pic_irq_offset+OPENPIC_NUM_IPI)) ||
- ((irq >= OPENPIC_VEC_TIMER+open_pic_irq_offset) &&
- (irq < OPENPIC_VEC_TIMER+open_pic_irq_offset+OPENPIC_NUM_TIMERS)))
- {
- /* silently ignore the enable of the timer or ipi irq. */
- return;
- }
-
-
openpic_clearfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -632,19 +661,6 @@ static void openpic_disable_irq(u_int irq)
u32 vp;
check_arg_irq(irq);
- /*
- * Never want to disable a timer or ipi irq
- * (only want to disable irqs within an ISU).
- */
- if (((irq >= OPENPIC_VEC_IPI+open_pic_irq_offset) &&
- (irq < OPENPIC_VEC_IPI+open_pic_irq_offset+OPENPIC_NUM_IPI)) ||
- ((irq >= OPENPIC_VEC_TIMER+open_pic_irq_offset) &&
- (irq < OPENPIC_VEC_TIMER+open_pic_irq_offset+OPENPIC_NUM_TIMERS)))
- {
- panic("openpic_disable_irq - disabling non-ISU irq");
- }
-
-
openpic_setfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -667,11 +683,13 @@ void openpic_enable_ipi(u_int irq)
openpic_clearfield_IPI(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK);
}
+
void openpic_disable_ipi(u_int irq)
{
- /* NEVER disable an IPI... that's just plain wrong! */
+ irq -= (OPENPIC_VEC_IPI+open_pic_irq_offset);
+ check_arg_ipi(irq);
+ openpic_setfield_IPI(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK);
}
-
#endif
/*
@@ -702,39 +720,33 @@ static void openpic_mapirq(u_int irq, u_int physmask)
openpic_write(&GET_ISU(irq).Destination, physmask);
}
+#ifdef notused
/*
* Set the sense for an interrupt source (and disable it!)
*
* sense: 1 for level, 0 for edge
*/
-static inline void openpic_set_sense(u_int irq, int sense)
+static void openpic_set_sense(u_int irq, int sense)
{
openpic_safe_writefield(&GET_ISU(irq).Vector_Priority,
OPENPIC_SENSE_LEVEL,
(sense ? OPENPIC_SENSE_LEVEL : 0));
}
+#endif /* notused */
/* No spinlocks, should not be necessary with the OpenPIC
* (1 register = 1 interrupt and we have the desc lock).
*/
static void openpic_ack_irq(unsigned int irq_nr)
{
-#if 1 /* masking should be unnecessary, but I still get spurrious */
openpic_disable_irq(irq_nr);
-#endif
- if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
- openpic_eoi();
+ openpic_eoi();
}
static void openpic_end_irq(unsigned int irq_nr)
{
- if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0)
- openpic_eoi();
-
-#if 1 /* masking should be unnecessary, but I still get spurrious */
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
openpic_enable_irq(irq_nr);
-#endif
}
static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask)
@@ -745,23 +757,11 @@ static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask)
#ifdef CONFIG_SMP
static void openpic_ack_ipi(unsigned int irq_nr)
{
+ openpic_eoi();
}
static void openpic_end_ipi(unsigned int irq_nr)
{
- /* IPIs are marked IRQ_PER_CPU. This has the side effect of
- * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
- * applying to them. We EOI them late to avoid re-entering.
- * however, I'm wondering if we could simply let them have the
- * SA_INTERRUPT flag and let them execute with all interrupts OFF.
- * This would have the side effect of either running cross-CPU
- * functions with interrupts off, or we can re-enable them explicitely
- * with a __sti() in smp_call_function_interrupt(), since
- * smp_call_function() is protected by a spinlock.
- * Or maybe we shouldn't set the IRQ_PER_CPU flag on cross-CPU
- * function calls IPI at all but that would make a special case.
- */
- openpic_eoi();
}
static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
@@ -791,8 +791,11 @@ openpic_get_irq(struct pt_regs *regs)
irq = i8259_irq( smp_processor_id() );
openpic_eoi();
}
- if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset)
+ if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) {
irq = -1;
+ /* That's not SMP safe ... but who cares ? */
+ ppc_spurious_interrupts++;
+ }
return irq;
}
diff --git a/arch/ppc/kernel/open_pic_defs.h b/arch/ppc/kernel/open_pic_defs.h
index fed4dd1cc..c0ea1ea86 100644
--- a/arch/ppc/kernel/open_pic_defs.h
+++ b/arch/ppc/kernel/open_pic_defs.h
@@ -28,8 +28,6 @@
#ifdef __KERNEL__
-#include <linux/config.h>
-
/*
* OpenPIC supports up to 2048 interrupt sources and up to 32 processors
*/
@@ -289,40 +287,6 @@ extern volatile struct OpenPIC *OpenPIC;
#define Vector_Priority _Vector_Priority.Reg
#define Destination _Destination.Reg
- /*
- * Local (static) OpenPIC Operations
- */
-
-
-/* Global Operations */
-static void openpic_reset(void);
-static void openpic_enable_8259_pass_through(void);
-static void openpic_disable_8259_pass_through(void);
-static u_int openpic_irq(void);
-static void openpic_eoi(void);
-static u_int openpic_get_priority(void);
-static void openpic_set_priority(u_int pri);
-static u_int openpic_get_spurious(void);
-static void openpic_set_spurious(u_int vector);
-
-#ifdef CONFIG_SMP
-/* Interprocessor Interrupts */
-static void openpic_initipi(u_int ipi, u_int pri, u_int vector);
-static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
-#endif
-
-/* Timer Interrupts */
-static void openpic_inittimer(u_int timer, u_int pri, u_int vector);
-static void openpic_maptimer(u_int timer, u_int cpumask);
-
-/* Interrupt Sources */
-static void openpic_enable_irq(u_int irq);
-static void openpic_disable_irq(u_int irq);
-static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity,
- int is_level);
-static void openpic_mapirq(u_int irq, u_int cpumask);
-static void openpic_set_sense(u_int irq, int sense);
-
#endif /* __KERNEL__ */
#endif /* _LINUX_OPENPIC_H */
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 1e503fae4..56a724bc0 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -109,7 +109,7 @@ pcibios_fixup_resources(struct pci_dev* dev)
struct resource *res = dev->resource + i;
if (!res->start)
continue;
- if (res->flags & IORESOURCE_MEM) {
+ if ((res->flags & IORESOURCE_MEM) && hose->pci_mem_offset) {
res->start += hose->pci_mem_offset;
res->end += hose->pci_mem_offset;
#ifdef DEBUG
@@ -121,7 +121,9 @@ pcibios_fixup_resources(struct pci_dev* dev)
if ((res->flags & IORESOURCE_IO)
&& (unsigned long) hose->io_base_virt != isa_io_base) {
- unsigned long offs = (unsigned long) hose->io_base_virt - isa_io_base;
+ unsigned long offs;
+
+ offs = (unsigned long)hose->io_base_virt - isa_io_base;
res->start += offs;
res->end += offs;
printk("Fixup IO res, dev: %x.%x, res_start: %lx->%lx\n",
@@ -245,13 +247,30 @@ pcibios_allocate_bus_resources(struct list_head *bus_list)
}
}
+static inline void alloc_resource(struct pci_dev *dev, int idx)
+{
+ struct resource *pr, *r = &dev->resource[idx];
+
+ DBG("PCI:%x:%x:%x: Resource %08lx-%08lx (f=%lx)\n",
+ dev->bus->number, dev->devfn >> 3, dev->devfn & 7,
+ r->start, r->end, r->flags);
+ 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;
+ }
+}
+
static void __init
pcibios_allocate_resources(int pass)
{
struct pci_dev *dev;
int idx, disabled;
u16 command;
- struct resource *r, *pr;
+ struct resource *r;
pci_for_each_dev(dev) {
pci_read_config_word(dev, PCI_COMMAND, &command);
@@ -259,7 +278,7 @@ pcibios_allocate_resources(int pass)
r = &dev->resource[idx];
if (r->parent) /* Already allocated */
continue;
- if (!r->start) /* Address not assigned at all */
+ if (!r->start) /* Not assigned at all */
continue;
if (r->end == 0xffffffff) {
/* LongTrail OF quirk: unassigned */
@@ -273,28 +292,19 @@ pcibios_allocate_resources(int pass)
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;
- }
- }
+ if (pass == disabled)
+ alloc_resource(dev, idx);
}
- 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, &reg);
- pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
- }
+ if (pass)
+ continue;
+ 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, &reg);
+ pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
}
}
}
@@ -315,17 +325,18 @@ pcibios_assign_resources(void)
for(idx=0; idx<6; idx++) {
r = &dev->resource[idx];
-
+#if 0 /* we don't need this PC-ism */
/*
* 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;
+#endif
/*
* We shall assign a new address to this resource, either because
- * the BIOS forgot to do so or because we have decided the old
+ * the BIOS (sic) forgot to do so or because we have decided the old
* address was unusable for some reason.
*/
if (!r->start && r->end &&
@@ -572,7 +583,7 @@ pcibios_init(void)
{
struct pci_controller *hose;
struct pci_bus *bus;
- int next_busno;
+ int next_busno, i;
printk("PCI: Probing PCI hardware\n");
@@ -582,6 +593,17 @@ pcibios_init(void)
hose->first_busno = next_busno;
hose->last_busno = 0xff;
bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
+ if (hose->io_resource.flags) {
+ unsigned long offs;
+
+ offs = (unsigned long)hose->io_base_virt - isa_io_base;
+ hose->io_resource.start += offs;
+ hose->io_resource.end += offs;
+ bus->resource[0] = &hose->io_resource;
+ }
+ for (i = 0; i < 3; ++i)
+ if (hose->mem_resources[i].flags)
+ bus->resource[i+1] = &hose->mem_resources[i];
hose->bus = bus;
hose->last_busno = bus->subordinate;
if (pci_assign_all_busses || next_busno <= hose->last_busno)
@@ -654,8 +676,20 @@ unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
+ struct pci_controller *hose;
+
pci_read_bridge_bases(bus);
-
+
+ hose = pci_bus_to_hose(bus->number);
+
+ /* Apply pci_mem_offset to bridge mem resource */
+ if (hose->first_busno != bus->number)
+ if (bus->resource[1]->start && (bus->resource[1]->end != -1))
+ {
+ bus->resource[1]->start += hose->pci_mem_offset;
+ bus->resource[1]->end += hose->pci_mem_offset;
+ }
+
if ( ppc_md.pcibios_fixup_bus )
ppc_md.pcibios_fixup_bus(bus);
}
@@ -774,6 +808,32 @@ pci_resource_to_bus(struct pci_dev *pdev, struct resource *res)
* is fixed
*/
unsigned long
+phys_to_bus(unsigned long pa)
+{
+ struct pci_controller *hose;
+ int i;
+
+ for (hose = hose_head; hose; hose = hose->next) {
+ for (i = 0; i < 3; ++i) {
+ if (pa >= hose->mem_resources[i].start
+ && pa <= hose->mem_resources[i].end) {
+ /*
+ * XXX the hose->pci_mem_offset really
+ * only applies to mem_resources[0].
+ * We need a way to store an offset for
+ * the others. -- paulus
+ */
+ if (i == 0)
+ pa -= hose->pci_mem_offset;
+ return pa;
+ }
+ }
+ }
+ /* hmmm, didn't find it */
+ return 0;
+}
+
+unsigned long
pci_phys_to_bus(unsigned long pa, int busnr)
{
#ifdef CONFIG_POWER4
diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c
index 9e1fffb49..597f4417a 100644
--- a/arch/ppc/kernel/pmac_pci.c
+++ b/arch/ppc/kernel/pmac_pci.c
@@ -29,6 +29,8 @@
#undef DEBUG
+extern void process_bridge_ranges(struct pci_controller *hose,
+ struct device_node *dev, int primary);
static void add_bridges(struct device_node *dev);
/* XXX Could be per-controller, but I don't think we risk anything by
@@ -372,7 +374,7 @@ static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
(void)in_le32((volatile unsigned int *)bp->cfg_data);
}
-static void __init
+static int __init
setup_uninorth(struct pci_controller* hose, struct reg_property* addr)
{
pci_assign_all_busses = 1;
@@ -380,6 +382,7 @@ setup_uninorth(struct pci_controller* hose, struct reg_property* addr)
hose->ops = &macrisc_pci_ops;
hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
+#if 0 /* done in process_bridge_ranges now - paulus */
hose->io_base_phys = addr->address;
/* is 0x10000 enough for io space ? */
hose->io_base_virt = (void *)ioremap(addr->address, 0x10000);
@@ -389,6 +392,9 @@ setup_uninorth(struct pci_controller* hose, struct reg_property* addr)
*/
if (addr->address == 0xf2000000)
isa_io_base = (unsigned long)hose->io_base_virt;
+#endif
+ /* We "know" that the bridge at f2000000 has the PCI slots. */
+ return addr->address == 0xf2000000;
}
static void __init
@@ -399,8 +405,10 @@ setup_bandit(struct pci_controller* hose, struct reg_property* addr)
ioremap(addr->address + 0x800000, 0x1000);
hose->cfg_data = (volatile unsigned char *)
ioremap(addr->address + 0xc00000, 0x1000);
+#if 0 /* done in process_bridge_ranges now - paulus */
hose->io_base_phys = addr->address;
hose->io_base_virt = (void *) ioremap(addr->address, 0x10000);
+#endif
init_bandit(hose);
}
@@ -413,19 +421,23 @@ setup_chaos(struct pci_controller* hose, struct reg_property* addr)
ioremap(addr->address + 0x800000, 0x1000);
hose->cfg_data = (volatile unsigned char *)
ioremap(addr->address + 0xc00000, 0x1000);
+#if 0 /* done in process_bridge_ranges now - paulus */
hose->io_base_phys = addr->address;
hose->io_base_virt = (void *) ioremap(addr->address, 0x10000);
+#endif
}
void __init
setup_grackle(struct pci_controller *hose, unsigned io_space_size)
{
setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
+#if 0 /* done in process_bridge_ranges now - paulus */
hose->io_base_phys = 0xfe000000;
hose->io_base_virt = (void *) ioremap(0xfe000000, io_space_size);
pci_dram_offset = 0;
isa_mem_base = 0xfd000000;
isa_io_base = (unsigned long) hose->io_base_virt;
+#endif
if (machine_is_compatible("AAPL,PowerBook1998"))
grackle_set_loop_snoop(hose, 1);
#if 0 /* Disabled for now, HW problems ??? */
@@ -445,6 +457,7 @@ static void __init add_bridges(struct device_node *dev)
struct reg_property *addr;
char* disp_name;
int *bus_range;
+ int first = 1, primary;
for (; dev != NULL; dev = dev->next) {
addr = (struct reg_property *) get_property(dev, "reg", &len);
@@ -467,8 +480,9 @@ static void __init add_bridges(struct device_node *dev)
hose->last_busno = bus_range ? bus_range[1] : 0xff;
disp_name = NULL;
+ primary = first;
if (device_is_compatible(dev, "uni-north")) {
- setup_uninorth(hose, addr);
+ primary = setup_uninorth(hose, addr);
disp_name = "UniNorth";
} else if (strcmp(dev->name, "pci") == 0) {
/* XXX assume this is a mpc106 (grackle) */
@@ -480,6 +494,7 @@ static void __init add_bridges(struct device_node *dev)
} else if (strcmp(dev->name, "chaos") == 0) {
setup_chaos(hose, addr);
disp_name = "Chaos";
+ primary = 0;
}
printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n",
disp_name, addr->address, hose->first_busno, hose->last_busno);
@@ -488,12 +503,14 @@ static void __init add_bridges(struct device_node *dev)
hose, hose->cfg_addr, hose->cfg_data);
#endif
- /* Setup a default isa_io_base */
- if (isa_io_base == 0)
- isa_io_base = (unsigned long)hose->io_base_virt;
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ process_bridge_ranges(hose, dev, primary);
/* Fixup "bus-range" OF property */
fixup_bus_range(dev);
+
+ first &= !primary;
}
}
diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c
index 839f66d80..0251a36e3 100644
--- a/arch/ppc/kernel/pmac_setup.c
+++ b/arch/ppc/kernel/pmac_setup.c
@@ -81,7 +81,7 @@ extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int mackbd_getkeycode(unsigned int scancode);
extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep,
char raw_mode);
-extern int mackbd_unexpected_up(unsigned char keycode);
+extern char mackbd_unexpected_up(unsigned char keycode);
extern void mackbd_leds(unsigned char leds);
extern void __init mackbd_init_hw(void);
extern int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode,
@@ -253,6 +253,7 @@ pmac_get_cpuinfo(char *buffer)
#endif
+#ifdef CONFIG_VT
/*
* Dummy mksound function that does nothing.
* The real one is in the dmasound driver.
@@ -262,6 +263,7 @@ static void
pmac_mksound(unsigned int hz, unsigned int ticks)
{
}
+#endif /* CONFIG_VT */
static volatile u32 *sysctrl_regs;
@@ -345,9 +347,9 @@ pmac_setup_arch(void)
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
#endif
-
+#ifdef CONFIG_VT
kd_mksound = pmac_mksound;
-
+#endif
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start)
ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
@@ -380,7 +382,7 @@ extern char *bootdevice;
void *boot_host;
int boot_target;
int boot_part;
-kdev_t boot_dev;
+extern kdev_t boot_dev;
void __init
pmac_init2(void)
diff --git a/arch/ppc/kernel/ppc8xx_pic.c b/arch/ppc/kernel/ppc8xx_pic.c
index e2db1e34d..0ec85e541 100644
--- a/arch/ppc/kernel/ppc8xx_pic.c
+++ b/arch/ppc/kernel/ppc8xx_pic.c
@@ -153,6 +153,20 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
irq += i8259_pic.irq_offset;
return (request_8xxirq(irq, handler, irqflags, devname, dev_id));
#else
- panic("request_irq");
+ /*
+ * Handle other "well-known" interrupts, but panic on unknown ones.
+ */
+ switch (irq) {
+#ifdef IDE0_INTERRUPT
+ case IDE0_INTERRUPT: /* fall through */
+#endif
+#ifdef IDE1_INTERRUPT
+ case IDE1_INTERRUPT: /* fall through */
+#endif
+ return (request_8xxirq(irq, handler, irqflags, devname, dev_id));
+
+ default: /* unknown IRQ -> panic */
+ panic("request_irq");
+ }
#endif
}
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 43a05659d..3ffecdb67 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -46,6 +46,10 @@
#endif /* CONFIG_SMP */
#include <asm/time.h>
+#ifdef CONFIG_8xx
+#include "../8xx_io/commproc.h"
+#endif
+
/* Tell string.h we don't want memcpy etc. as cpp defines */
#define EXPORT_SYMTAB_STROPS
@@ -94,7 +98,7 @@ EXPORT_SYMBOL_NOVERS(isa_mem_base);
EXPORT_SYMBOL_NOVERS(pci_dram_offset);
#endif
EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
-EXPORT_SYMBOL(DMA_MODE_READ);
+EXPORT_SYMBOL_NOVERS(DMA_MODE_READ);
EXPORT_SYMBOL(DMA_MODE_WRITE);
#ifndef CONFIG_8xx
#if defined(CONFIG_ALL_PPC)
@@ -192,6 +196,9 @@ EXPORT_SYMBOL(last_task_used_altivec);
EXPORT_SYMBOL(giveup_altivec);
#endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_SMP
+EXPORT_SYMBOL(global_irq_lock);
+EXPORT_SYMBOL(global_irq_count);
+EXPORT_SYMBOL(global_irq_holder);
EXPORT_SYMBOL(__global_cli);
EXPORT_SYMBOL(__global_sti);
EXPORT_SYMBOL(__global_save_flags);
@@ -242,11 +249,11 @@ EXPORT_SYMBOL(set_backlight_level);
EXPORT_SYMBOL(set_backlight_enable);
EXPORT_SYMBOL(register_backlight_controller);
#endif /* CONFIG_PMAC_BACKLIGHT */
-EXPORT_SYMBOL_NOVERS(sys_ctrler);
#ifndef CONFIG_MACH_SPECIFIC
EXPORT_SYMBOL_NOVERS(have_of);
#endif /* CONFIG_MACH_SPECIFIC */
#if defined(CONFIG_ALL_PPC)
+EXPORT_SYMBOL_NOVERS(sys_ctrler);
EXPORT_SYMBOL(find_devices);
EXPORT_SYMBOL(find_type_devices);
EXPORT_SYMBOL(find_compatible_devices);
@@ -280,7 +287,9 @@ EXPORT_SYMBOL(bootx_update_display);
#if defined(CONFIG_SCSI) && defined(CONFIG_ALL_PPC)
EXPORT_SYMBOL(note_scsi_host);
#endif
+#ifdef CONFIG_VT
EXPORT_SYMBOL(kd_mksound);
+#endif
#ifdef CONFIG_NVRAM
EXPORT_SYMBOL(nvram_read_byte);
EXPORT_SYMBOL(nvram_write_byte);
@@ -342,11 +351,18 @@ EXPORT_SYMBOL(debugger_dabr_match);
EXPORT_SYMBOL(debugger_fault_handler);
#endif
+#ifdef CONFIG_8xx
+EXPORT_SYMBOL(request_8xxirq);
+EXPORT_SYMBOL(cpm_install_handler);
+EXPORT_SYMBOL(cpm_free_handler);
+#endif /* CONFIG_8xx */
+
EXPORT_SYMBOL(ret_to_user_hook);
EXPORT_SYMBOL(do_softirq);
EXPORT_SYMBOL(next_mmu_context);
EXPORT_SYMBOL(set_context);
EXPORT_SYMBOL(mmu_context_overflow);
+EXPORT_SYMBOL_NOVERS(disarm_decr);
#if !defined(CONFIG_8xx) && !defined(CONFIG_4xx)
extern long *intercept_table;
EXPORT_SYMBOL(intercept_table);
diff --git a/arch/ppc/kernel/prep_pci.c b/arch/ppc/kernel/prep_pci.c
index 2f556d83d..369e8c47c 100644
--- a/arch/ppc/kernel/prep_pci.c
+++ b/arch/ppc/kernel/prep_pci.c
@@ -37,6 +37,10 @@ unsigned char *Motherboard_map_name;
/* How is the 82378 PIRQ mapping setup? */
unsigned char *Motherboard_routes;
+void (*Motherboard_non0)(struct pci_dev *);
+
+void Powerplus_Map_Non0(struct pci_dev *);
+
/* Used for Motorola to store system config register */
static unsigned long *ProcInfo;
@@ -505,6 +509,52 @@ static char Nobis_pci_IRQ_routes[] __prepdata = {
13 /* Line 4 */
};
+/* Motorola PowerPlus architecture PCI IRQ tables */
+/* Interrupt line values for INTA-D on primary/secondary MPIC inputs */
+
+struct powerplus_irq_list
+{
+ unsigned char primary[4]; /* INT A-D */
+ unsigned char secondary[4]; /* INT A-D */
+};
+
+/*
+ * For standard PowerPlus boards, bus 0 PCI INTs A-D are routed to
+ * OpenPIC inputs 9-12. PCI INTs A-D from the on board P2P bridge
+ * are routed to OpenPIC inputs 5-8. These values are offset by
+ * 16 in the table to reflect the Linux kernel interrupt value.
+ */
+struct powerplus_irq_list Powerplus_pci_IRQ_list =
+{
+ {25, 26, 27, 28},
+ {21, 22, 23, 24}
+};
+
+/*
+ * For the MCP750 (system slot board), cPCI INTs A-D are routed to
+ * OpenPIC inputs 8-11 and the PMC INTs A-D are routed to OpenPIC
+ * input 3. On a hot swap MCP750, the companion card PCI INTs A-D
+ * are routed to OpenPIC inputs 12-15. These values are offset by
+ * 16 in the table to reflect the Linux kernel interrupt value.
+ */
+struct powerplus_irq_list Mesquite_pci_IRQ_list =
+{
+ {24, 25, 26, 27},
+ {28, 29, 30, 31}
+};
+
+/*
+ * This table represents the standard PCI swizzle defined in the
+ * PCI bus specification.
+ */
+static unsigned char prep_pci_intpins[4][4] =
+{
+ { 1, 2, 3, 4}, /* Buses 0, 4, 8, ... */
+ { 2, 3, 4, 1}, /* Buses 1, 5, 9, ... */
+ { 3, 4, 1, 2}, /* Buses 2, 6, 10 ... */
+ { 4, 1, 2, 3}, /* Buses 3, 7, 11 ... */
+};
+
/* We have to turn on LEVEL mode for changed IRQ's */
/* All PCI IRQ's need to be level mode, so this should be something
* other than hard-coded as well... IRQ's are individually mappable
@@ -599,6 +649,7 @@ static u_char mvme2600_openpic_initsenses[] __initdata = {
#define MOT_RAVEN_PRESENT 0x1
#define MOT_HAWK_PRESENT 0x2
+int mot_entry = -1;
int prep_keybd_present = 1;
int MotMPIC;
int mot_multi;
@@ -682,33 +733,36 @@ struct mot_info {
const char *name;
unsigned char *map;
unsigned char *routes;
+ void (*map_non0_bus)(struct pci_dev *); /* For boards with more than bus 0 devices. */
+ struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */
+ unsigned char secondary_bridge_devfn; /* devfn of secondary bus transparent bridge */
} mot_info[] = {
- {0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes},
- {0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes},
- {0x040, 0x00, 0x00, "Blackhawk (Powerstack)", Blackhawk_pci_IRQ_map, Blackhawk_pci_IRQ_routes},
- {0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)", Omaha_pci_IRQ_map, Omaha_pci_IRQ_routes},
- {0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)", Utah_pci_IRQ_map, Utah_pci_IRQ_routes},
- {0x0A0, 0x00, 0x00, "Powerstack (Series EX)", Comet2_pci_IRQ_map, Comet2_pci_IRQ_routes},
- {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", Sitka_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
- {0x000, 0x00, 0x00, "", NULL, NULL}
+ {0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ {0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+ {0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes, NULL, NULL, 0x00},
+ {0x040, 0x00, 0x00, "Blackhawk (Powerstack)", Blackhawk_pci_IRQ_map, Blackhawk_pci_IRQ_routes, NULL, NULL, 0x00},
+ {0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)", Omaha_pci_IRQ_map, Omaha_pci_IRQ_routes, NULL, NULL, 0x00},
+ {0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)", Utah_pci_IRQ_map, Utah_pci_IRQ_routes, NULL, NULL, 0x00},
+ {0x0A0, 0x00, 0x00, "Powerstack (Series EX)", Comet2_pci_IRQ_map, Comet2_pci_IRQ_routes, NULL, NULL, 0x00},
+ {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Mesquite_pci_IRQ_list, 0xFF},
+ {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", Sitka_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Mesquite_pci_IRQ_list, 0xC0},
+ {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xA0},
+ {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xA0},
+ {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+ {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+ {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+ {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+ {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+ {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ {0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
+ {0x000, 0x00, 0x00, "", NULL, NULL, NULL, NULL, 0x00}
};
unsigned long __init prep_route_pci_interrupts(void)
@@ -723,7 +777,6 @@ unsigned long __init prep_route_pci_interrupts(void)
unsigned char cpu_type;
unsigned char base_mod;
int entry;
- int mot_entry = -1;
cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;
base_mod = inb(MOTOROLA_BASETYPE_REG);
@@ -769,6 +822,7 @@ unsigned long __init prep_route_pci_interrupts(void)
Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name;
Motherboard_map = mot_info[mot_entry].map;
Motherboard_routes = mot_info[mot_entry].routes;
+ Motherboard_non0 = mot_info[mot_entry].map_non0_bus;
if (!(mot_info[entry].cpu_type & 0x100)) {
/* AJF adjust level/edge control according to routes */
@@ -836,6 +890,157 @@ unsigned long __init prep_route_pci_interrupts(void)
}
void __init
+prep_pib_init(void)
+{
+unsigned char reg;
+unsigned short short_reg;
+
+struct pci_dev *dev = NULL;
+
+ if (( _prep_type == _PREP_Motorola) && (OpenPIC_Addr)) {
+ /*
+ * Perform specific configuration for the Via Tech or
+ * or Winbond PCI-ISA-Bridge part.
+ */
+ if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_82C586_1, dev))) {
+ /*
+ * PPCBUG does not set the enable bits
+ * for the IDE device. Force them on here.
+ */
+ pcibios_read_config_byte(dev->bus->number,
+ dev->devfn, 0x40, &reg);
+
+ reg |= 0x03; /* IDE: Chip Enable Bits */
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x40, reg);
+
+ /* Force correct IDE function interrupt */
+ dev->irq = 14;
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn,
+ PCI_INTERRUPT_LINE,
+ dev->irq);
+
+ } else if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+ PCI_DEVICE_ID_WINBOND_83C553, dev))) {
+ /*
+ * Clear the PCI Interrupt Routing Control Register.
+ */
+ short_reg = 0x0000;
+ pci_write_config_word(dev, 0x44, short_reg);
+ if (OpenPIC_Addr){
+ /*
+ * Route both IDE interrupts to IRQ 14
+ */
+ reg = 0xEE;
+ pci_write_config_byte(dev, 0x44, reg);
+ }
+ }
+ if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_82C586_2,
+ dev)))
+ {
+ /* Force correct USB function interrupt */
+ dev->irq = 11;
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn,
+ PCI_INTERRUPT_LINE,
+ dev->irq);
+ }
+ }
+ if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+ PCI_DEVICE_ID_WINBOND_82C105, dev))){
+ if (OpenPIC_Addr){
+ /* Disable LEGIRQ mode so PCI INTs are routed to
+ the 8259 */
+ printk("Set winbond IDE to native mode\n");
+ pci_write_config_dword(dev, 0x40, 0x10ff00a1);
+ }else{
+ /* Enable LEGIRQ for PCI INT -> 8259 IRQ routing */
+ pci_write_config_dword(dev, 0x40, 0x10ff08a1);
+ }
+ }
+}
+
+void
+Powerplus_Map_Non0(struct pci_dev *dev)
+{
+ struct pci_bus *pbus; /* Parent bus structure pointer */
+ struct pci_dev *tdev = dev; /* Temporary device structure */
+ unsigned int devnum; /* Accumulated device number */
+ unsigned char intline; /* Linux interrupt value */
+ unsigned char intpin; /* PCI interrupt pin */
+
+ /* Check for valid PCI dev pointer */
+ if (dev == NULL) return;
+
+ /* Initialize bridge IDSEL variable */
+ devnum = PCI_SLOT(tdev->devfn);
+
+ /* Read the interrupt pin of the device and adjust for indexing */
+ pcibios_read_config_byte(dev->bus->number, dev->devfn,
+ PCI_INTERRUPT_PIN, &intpin);
+
+ /* If device doesn't request an interrupt, return */
+ if ( (intpin < 1) || (intpin > 4) )
+ return;
+
+ intpin--;
+
+ /*
+ * Walk up to bus 0, adjusting the interrupt pin for the standard
+ * PCI bus swizzle.
+ */
+ do {
+ intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1;
+ pbus = tdev->bus; /* up one level */
+ tdev = pbus->self;
+ devnum = PCI_SLOT(tdev->devfn);
+ } while(tdev->bus->number);
+
+ /* Use the primary interrupt inputs by default */
+ intline = mot_info[mot_entry].pci_irq_list->primary[intpin];
+
+ /*
+ * If the board has secondary interrupt inputs, walk the bus and
+ * note the devfn of the bridge from bus 0. If it is the same as
+ * the devfn of the bus bridge with secondary inputs, use those.
+ * Otherwise, assume it's a PMC site and get the interrupt line
+ * value from the interrupt routing table.
+ */
+ if (mot_info[mot_entry].secondary_bridge_devfn)
+ {
+ pbus = dev->bus;
+
+ while (pbus->primary != 0)
+ pbus = pbus->parent;
+
+ if ((pbus->self)->devfn != 0xA0)
+ {
+ if ((pbus->self)->devfn == mot_info[mot_entry].secondary_bridge_devfn)
+ intline = mot_info[mot_entry].pci_irq_list->secondary[intpin];
+ else
+ {
+ if ((char *)(mot_info[mot_entry].map) == (char *)Mesquite_pci_IRQ_map)
+ intline = mot_info[mot_entry].map[((pbus->self)->devfn)/8] + 16;
+ else
+ {
+ int i;
+ for (i=0;i<3;i++)
+ intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1;
+ intline = mot_info[mot_entry].pci_irq_list->primary[intpin];
+ }
+ }
+ }
+ }
+
+ /* Write calculated interrupt value to header and device list */
+ dev->irq = intline;
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, (u8)dev->irq);
+}
+
+void __init
prep_pcibios_fixup(void)
{
struct pci_dev *dev;
@@ -849,11 +1054,21 @@ prep_pcibios_fixup(void)
if (OpenPIC_Addr) {
/* PCI interrupts are controlled by the OpenPIC */
pci_for_each_dev(dev) {
- if (dev->bus->number == 0) {
+ if (dev->bus->number == 0)
+ {
dev->irq = openpic_to_irq(Motherboard_map[PCI_SLOT(dev->devfn)]);
- pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_INTERRUPT_PIN, dev->irq);
+ pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_INTERRUPT_LINE, dev->irq);
+ }
+ else
+ {
+ if (Motherboard_non0 != NULL)
+ Motherboard_non0(dev);
}
}
+
+ /* Setup the Winbond or Via PIB */
+ prep_pib_init();
+
return;
}
@@ -912,6 +1127,7 @@ prep_find_bridges(void)
hose->first_busno = 0;
hose->last_busno = 0xff;
hose->pci_mem_offset = PREP_ISA_MEM_BASE;
+ hose->io_base_virt = (void *)PREP_ISA_IO_BASE;
printk("PReP architecture\n");
{
diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c
index 0c23c51ac..772cceb61 100644
--- a/arch/ppc/kernel/prep_setup.c
+++ b/arch/ppc/kernel/prep_setup.c
@@ -215,7 +215,6 @@ no_l2:
void __init
prep_setup_arch(void)
{
- extern char cmd_line[];
unsigned char reg;
#if 0 /* unused?? */
unsigned char ucMothMemType;
@@ -272,8 +271,6 @@ prep_setup_arch(void)
}
}
- printk("Boot arguments: %s\n", cmd_line);
-
#ifdef CONFIG_SOUND_CS4232
/*
* setup proper values for the cs4232 driver so we don't have
diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c
index f3b39c222..f8eb0729d 100644
--- a/arch/ppc/kernel/prom.c
+++ b/arch/ppc/kernel/prom.c
@@ -757,8 +757,11 @@ prom_init(int r3, int r4, prom_entry pp)
setup_disp_fake_bi(RELOC(prom_disp_node));
#endif
- /* If OpenFirmware version >= 3, then use quiesce call */
- if (prom_version >= 3) {
+ /* If pmac, then use quiesce call. We can't rely on prom_version
+ * since some old iMacs appear to have an incorrect /openprom/model
+ * entry in the device tree
+ */
+ if (!chrp) {
prom_print(RELOC("Calling quiesce ...\n"));
call_prom(RELOC("quiesce"), 0, 0);
}
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 73afefc56..5ad504503 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -386,8 +386,8 @@ int get_cpuinfo(char *buffer)
if ( i )
len += sprintf(buffer+len, "\n");
len += sprintf(buffer+len,"total bogomips\t: %lu.%02lu\n",
- (bogosum+2500)/500000,
- (bogosum+2500)/5000 % 100);
+ (bogosum+2500)/(500000/HZ),
+ (bogosum+2500)/(5000/HZ) % 100);
#endif /* CONFIG_SMP */
/*
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index 7edf7209d..29166ba77 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -100,14 +100,14 @@ extern void __secondary_start_psurge3(void); /* Temporary horrible hack */
#define PSURGE_QUAD_CKSTOP_RDBK 8
#define PSURGE_QUAD_RESET_CTL 11
-#define PSURGE_QUAD_OUT(r, v) (out_8((u8 *)(quad_base+((r)<<2)+1), (v)))
-#define PSURGE_QUAD_IN(r) (in_8((u8 *)(quad_base+((r)<<2)+1)) & 0x0f)
+#define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v)))
+#define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f)
#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
/* virtual addresses for the above */
static volatile u8 *hhead_base;
-static volatile u32 *quad_base;
+static volatile u8 *quad_base;
static volatile u32 *psurge_pri_intr;
static volatile u8 *psurge_sec_intr;
static volatile u32 *psurge_start;
@@ -216,7 +216,7 @@ smp_psurge_message_pass(int target, int msg, unsigned long data, int wait)
/*
* Determine a quad card presence. We read the board ID register, we
- * for the data bus to change to something else, and we read it again.
+ * force the data bus to change to something else, and we read it again.
* It it's stable, then the register probably exist (ugh !)
*/
static int __init psurge_quad_probe(void)
@@ -303,11 +303,7 @@ static int __init smp_psurge_probe(void)
psurge_type = psurge_quad_probe();
if (psurge_type != PSURGE_DUAL) {
psurge_quad_init();
- /* I believe we could "count" CPUs by counting 1 bits
- * in procbits on a quad board. For now, we assume 4,
- * non-present CPUs will just be seen as "stuck".
- * (hope they are the higher-numbered ones -- paulus)
- */
+ /* All released cards using this HW design have 4 CPUs */
ncpus = 4;
} else {
iounmap((void *) quad_base);
@@ -424,11 +420,10 @@ smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
break;
case MSG_ALL_BUT_SELF:
openpic_cause_IPI(msg,
- 0xffffffff & ~(1 << smp_hw_index[smp_processor_id()]));
-
+ 0xffffffff & ~(1 << smp_processor_id()));
break;
default:
- openpic_cause_IPI(msg, smp_hw_index[1<<target]);
+ openpic_cause_IPI(msg, 1<<target);
break;
}
}
@@ -437,27 +432,14 @@ static int
smp_core99_probe(void)
{
struct device_node *cpus;
- int *pp;
int i, ncpus = 1;
if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
-#if 0 /* Paulus method.. doesn't seem to work on earlier dual G4's??*/
- cpus = find_devices("cpus");
- if (cpus != 0) {
- pp = (int *) get_property(cpus, "#cpus", NULL);
- if (pp != NULL)
- ncpus = *pp;
- }
-#else /* My original method -- Troy <hozer@drgw.net> */
-
cpus = find_type_devices("cpu");
- if (cpus){
- for ( ncpus = 1; cpus->next; cpus = cpus->next ){
- ncpus++;
- }
- }
-#endif
- printk("smp_core99_probe: OF reports %d cpus\n", ncpus);
+ if (cpus)
+ while ((cpus = cpus->next) != NULL)
+ ++ncpus;
+ printk("smp_core99_probe: found %d cpus\n", ncpus);
if (ncpus > 1) {
openpic_request_IPIs();
for (i = 1; i < ncpus; ++i)
@@ -1010,6 +992,9 @@ void __init smp_boot_cpus(void)
/* Setup CPU 0 last (important) */
smp_ops->setup_cpu(0);
+
+ if (smp_num_cpus < 2)
+ smp_tb_synchronized = 1;
}
void __init smp_software_tb_sync(int cpu)
@@ -1027,17 +1012,6 @@ void __init smp_software_tb_sync(int cpu)
register unsigned long start = 0;
register unsigned long stop = 0;
register unsigned long temp = 0;
-
- if (smp_num_cpus < 2) {
- smp_tb_synchronized = 1;
- return;
- }
-
- /* This code need fixing on >2 CPUs --BenH/paulus */
- if (smp_num_cpus > 2) {
- smp_tb_synchronized = 0;
- return;
- }
set_tb(0, 0);
@@ -1107,6 +1081,7 @@ void __init smp_commence(void)
if (ppc_md.progress) ppc_md.progress("smp_commence", 0x370);
wmb();
smp_commenced = 1;
+
/* if the smp_ops->setup_cpu function has not already synched the
* timebases with a nicer hardware-based method, do so now
*
@@ -1117,9 +1092,9 @@ void __init smp_commence(void)
* since if this code runs pretty early and needs all cpus that
* reported in in smp_callin_map to be working
*
- * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus
+ * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus/BenH
*/
- if (!smp_tb_synchronized) {
+ if (!smp_tb_synchronized && smp_num_cpus == 2) {
unsigned long flags;
__save_and_cli(flags);
smp_software_tb_sync(0);
@@ -1142,7 +1117,7 @@ void __init smp_callin(void)
while(!smp_commenced)
barrier();
/* see smp_commence for more info */
- if (!smp_tb_synchronized){
+ if (!smp_tb_synchronized && smp_num_cpus == 2) {
smp_software_tb_sync(cpu);
}
__sti();
diff --git a/arch/ppc/kernel/softemu8xx.c b/arch/ppc/kernel/softemu8xx.c
index 26a8fe165..e8879d0a0 100644
--- a/arch/ppc/kernel/softemu8xx.c
+++ b/arch/ppc/kernel/softemu8xx.c
@@ -75,12 +75,12 @@ Soft_emulate_8xx(struct pt_regs *regs)
sdisp = (instword & 0xffff);
ea = (uint *)(regs->gpr[idxreg] + sdisp);
if (copy_from_user(ip, ea, sizeof(double)))
- retval = EFAULT;
+ retval = -EFAULT;
break;
case LFDU:
if (copy_from_user(ip, ea, sizeof(double)))
- retval = EFAULT;
+ retval = -EFAULT;
else
regs->gpr[idxreg] = (uint)ea;
break;
@@ -88,7 +88,7 @@ Soft_emulate_8xx(struct pt_regs *regs)
sdisp = (instword & 0xffff);
ea = (uint *)(regs->gpr[idxreg] + sdisp);
if (copy_from_user(ip, ea, sizeof(float)))
- retval = EFAULT;
+ retval = -EFAULT;
break;
case STFD:
/* this is a 16 bit quantity that is sign extended
@@ -97,12 +97,12 @@ Soft_emulate_8xx(struct pt_regs *regs)
sdisp = (instword & 0xffff);
ea = (uint *)(regs->gpr[idxreg] + sdisp);
if (copy_to_user(ea, ip, sizeof(double)))
- retval = EFAULT;
+ retval = -EFAULT;
break;
case STFDU:
if (copy_to_user(ea, ip, sizeof(double)))
- retval = EFAULT;
+ retval = -EFAULT;
else
regs->gpr[idxreg] = (uint)ea;
break;
diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
index d0fee4344..f4ed98698 100644
--- a/arch/ppc/kernel/syscalls.c
+++ b/arch/ppc/kernel/syscalls.c
@@ -198,9 +198,9 @@ unsigned long sys_mmap(unsigned long addr, size_t len,
goto out;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
ret = do_mmap(file, addr, len, prot, flags, offset);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
out:
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index 5b36cedcc..76a550214 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -67,6 +67,8 @@
#include <asm/time.h>
+unsigned long disarm_decr[NR_CPUS];
+
#ifdef CONFIG_SMP
extern void smp_local_timer_interrupt(struct pt_regs *);
extern int smp_tb_synchronized;
@@ -147,7 +149,6 @@ int timer_interrupt(struct pt_regs * regs)
if (!user_mode(regs))
ppc_do_profile(instruction_pointer(regs));
-
do {
jiffy_stamp += tb_ticks_per_jiffy;
if (smp_processor_id()) continue;
@@ -184,7 +185,8 @@ int timer_interrupt(struct pt_regs * regs)
}
write_unlock(&xtime_lock);
} while((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0);
- set_dec(next_dec);
+ if ( !disarm_decr[smp_processor_id()] )
+ set_dec(next_dec);
last_jiffy_stamp(cpu) = jiffy_stamp;
#ifdef CONFIG_SMP
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 0269254cf..29d302267 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -237,7 +237,7 @@ emulate_instruction(struct pt_regs *regs)
return retval;
if (get_user(instword, (uint *)(regs->nip)))
- return EFAULT;
+ return -EFAULT;
/* Emulate the mfspr rD, PVR.
*/
@@ -281,7 +281,7 @@ ProgramCheckException(struct pt_regs *regs)
/* Try to emulate it if we should. */
int errcode;
if ((errcode = emulate_instruction(regs))) {
- if (errcode == EFAULT)
+ if (errcode == -EFAULT)
_exception(SIGBUS, regs);
else
_exception(SIGILL, regs);
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 97bb6dbc1..507c60019 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -99,7 +99,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
bad_page_fault(regs, address, SIGSEGV);
return;
}
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
@@ -159,7 +159,7 @@ good_area:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/*
* keep track of tlb+htab misses that are good addrs but
* just need pte's created via handle_mm_fault()
@@ -169,7 +169,7 @@ good_area:
return;
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
pte_errors++;
/* User mode accesses cause a SIGSEGV */
@@ -190,7 +190,7 @@ bad_area:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", current->comm);
if (user_mode(regs))
do_exit(SIGKILL);
@@ -198,7 +198,7 @@ out_of_memory:
return;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
@@ -276,7 +276,7 @@ unsigned long va_to_phys(unsigned long address)
pte = va_to_pte(address);
if (pte)
- return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK-1)));
+ return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK)));
return (0);
}
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 839b618d0..5b9cac931 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -110,7 +110,7 @@ pgprot_t kmap_prot;
#endif
void MMU_init(void);
-static void *MMU_get_page(void);
+void *early_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);
@@ -125,7 +125,7 @@ unsigned long oak_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);
+int map_page(unsigned long va, unsigned long pa, int flags);
void set_phys_avail(unsigned long total_ram);
extern void die_if_kernel(char *,struct pt_regs *,long);
@@ -206,41 +206,20 @@ void __bad_pte(pmd_t *pmd)
pmd_val(*pmd) = (unsigned long) BAD_PAGETABLE;
}
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
-{
- pte_t *pte;
-
- if (pmd_none(*pmd)) {
- if (!mem_init_done)
- pte = (pte_t *) MMU_get_page();
- else if ((pte = (pte_t *) __get_free_page(GFP_KERNEL)))
- clear_page(pte);
- if (pte) {
- pmd_val(*pmd) = (unsigned long)pte;
- return pte + offset;
- }
- pmd_val(*pmd) = (unsigned long)BAD_PAGETABLE;
- return NULL;
- }
- if (pmd_bad(*pmd)) {
- __bad_pte(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + offset;
-}
-
int do_check_pgt_cache(int low, int high)
{
int freed = 0;
- if(pgtable_cache_size > high) {
+ if (pgtable_cache_size > high) {
do {
- if(pgd_quicklist)
- free_pgd_slow(get_pgd_fast()), freed++;
- if(pmd_quicklist)
- free_pmd_slow(get_pmd_fast()), freed++;
- if(pte_quicklist)
- free_pte_slow(get_pte_fast()), freed++;
- } while(pgtable_cache_size > low);
+ if (pgd_quicklist) {
+ free_pgd_slow(get_pgd_fast());
+ freed++;
+ }
+ if (pte_quicklist) {
+ pte_free_slow(pte_alloc_one_fast(NULL, 0));
+ freed++;
+ }
+ } while (pgtable_cache_size > low);
}
return freed;
}
@@ -383,6 +362,7 @@ void *
__ioremap(unsigned long addr, unsigned long size, unsigned long flags)
{
unsigned long p, v, i;
+ int err;
/*
* Choose an address to map it to.
@@ -453,10 +433,20 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
flags |= _PAGE_GUARDED;
/*
- * Is it a candidate for a BAT mapping?
+ * Should check if it is a candidate for a BAT mapping
*/
- for (i = 0; i < size; i += PAGE_SIZE)
- map_page(v+i, p+i, flags);
+
+ spin_lock(&init_mm.page_table_lock);
+ err = 0;
+ for (i = 0; i < size && err == 0; i += PAGE_SIZE)
+ err = map_page(v+i, p+i, flags);
+ spin_unlock(&init_mm.page_table_lock);
+ if (err) {
+ if (mem_init_done)
+ vfree((void *)v);
+ return NULL;
+ }
+
out:
return (void *) (v + (addr & ~PAGE_MASK));
}
@@ -492,7 +482,7 @@ unsigned long iopa(unsigned long addr)
return (pte_val(*pg) & PAGE_MASK) | (addr & ~PAGE_MASK);
}
-void
+int
map_page(unsigned long va, unsigned long pa, int flags)
{
pmd_t *pd;
@@ -501,10 +491,13 @@ map_page(unsigned long va, unsigned long pa, int flags)
/* Use upper 10 bits of VA to index the first level map */
pd = pmd_offset(pgd_offset_k(va), va);
/* Use middle 10 bits of VA to index the second-level map */
- pg = pte_alloc(pd, va);
+ pg = pte_alloc(&init_mm, pd, va);
+ if (pg == 0)
+ return -ENOMEM;
set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags)));
if (mem_init_done)
flush_hash_page(0, va);
+ return 0;
}
#ifndef CONFIG_8xx
@@ -830,21 +823,16 @@ static void __init mapin_ram(void)
}
}
-/* In fact this is only called until mem_init is done. */
-static void __init *MMU_get_page(void)
+/* This is only called until mem_init is done. */
+void __init *early_get_page(void)
{
void *p;
- if (mem_init_done) {
- p = (void *) __get_free_page(GFP_KERNEL);
- } else if (init_bootmem_done) {
+ if (init_bootmem_done) {
p = alloc_bootmem_pages(PAGE_SIZE);
} else {
p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE);
}
- if (p == 0)
- panic("couldn't get a page in MMU_get_page");
- __clear_user(p, PAGE_SIZE);
return p;
}
@@ -889,13 +877,14 @@ void free_initmem(void)
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+
for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1);
free_page(start);
totalram_pages++;
}
- printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
}
#endif
diff --git a/arch/ppc/treeboot/mkevimg b/arch/ppc/treeboot/mkevimg
index 68eb4dd3f..ca3ca0e8f 100644
--- a/arch/ppc/treeboot/mkevimg
+++ b/arch/ppc/treeboot/mkevimg
@@ -431,7 +431,7 @@ require 'elf.pl';
close(BOOT);
- print("\nBoot image file \"$ofile\" built successfuly.\n\n");
+ print("\nBoot image file \"$ofile\" built successfully.\n\n");
exit(0);
}
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index a1125e933..de40410b0 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -687,7 +687,7 @@ pgm_no_sv:
lr %r3,%r8
la %r0,0x7f
nr %r3,%r0 # clear per-event-bit
- be BASED(pgm_dn) # none of Martins exceptions occured bypass
+ be BASED(pgm_dn) # none of Martins exceptions occurred bypass
l %r9,BASED(.Ljump_table)
sll %r3,2
l %r9,0(%r3,%r9) # load address of handler routine
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index cc7700864..594fa34a5 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -61,9 +61,9 @@ static inline long do_mmap2(
goto out;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 2c75918af..527f08282 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -122,7 +122,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
* task's user address space, so we search the VMAs
*/
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
@@ -173,7 +173,7 @@ good_area:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
/*
@@ -181,7 +181,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/* User mode accesses just cause a SIGSEGV */
if (psw_mask & PSW_PROBLEM_STATE) {
@@ -240,14 +240,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (psw_mask & PSW_PROBLEM_STATE)
do_exit(SIGKILL);
goto no_context;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/*
* Send a sigbus, regardless of whether we were in kernel
diff --git a/arch/s390/tools/dasdfmt/dasdfmt.c b/arch/s390/tools/dasdfmt/dasdfmt.c
index 2820fc91d..560feff6b 100644
--- a/arch/s390/tools/dasdfmt/dasdfmt.c
+++ b/arch/s390/tools/dasdfmt/dasdfmt.c
@@ -477,7 +477,7 @@ do_format_dasd(char *dev_name,format_data_t format_params,int testmode,
rc=stat(dev_name,&stat_buf);
if (rc) {
- ERRMSG_EXIT(EXIT_FAILURE,"%s: error occured during stat: " \
+ ERRMSG_EXIT(EXIT_FAILURE,"%s: error occurred during stat: " \
"%s\n",prog_name,strerror(errno));
} else {
if (!S_ISBLK(stat_buf.st_mode))
diff --git a/arch/s390x/kernel/binfmt_elf32.c b/arch/s390x/kernel/binfmt_elf32.c
index b08f0f686..d21f6966b 100644
--- a/arch/s390x/kernel/binfmt_elf32.c
+++ b/arch/s390x/kernel/binfmt_elf32.c
@@ -193,11 +193,11 @@ elf_map32 (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int p
if(!addr)
addr = 0x40000000;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
map_addr = do_mmap(filep, ELF_PAGESTART(addr),
eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
return(map_addr);
}
diff --git a/arch/s390x/kernel/entry.S b/arch/s390x/kernel/entry.S
index c5fbdd61f..0dddf63c7 100644
--- a/arch/s390x/kernel/entry.S
+++ b/arch/s390x/kernel/entry.S
@@ -724,7 +724,7 @@ pgm_no_sv:
stosm 48(%r15),0x03 # reenable interrupts
lghi %r3,0x7f
nr %r3,%r8 # clear per-event-bit & move to r3
- je pgm_dn # none of Martins exceptions occured bypass
+ je pgm_dn # none of Martins exceptions occurred bypass
sll %r3,3
larl %r9,pgm_check_table
lg %r9,0(%r3,%r9) # load address of handler routine
diff --git a/arch/s390x/kernel/exec32.c b/arch/s390x/kernel/exec32.c
index 3e6f44558..8c517456a 100644
--- a/arch/s390x/kernel/exec32.c
+++ b/arch/s390x/kernel/exec32.c
@@ -54,7 +54,7 @@ int setup_arg_pages32(struct linux_binprm *bprm)
if (!mpnt)
return -ENOMEM;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
{
mpnt->vm_mm = current->mm;
mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
@@ -73,12 +73,11 @@ int setup_arg_pages32(struct linux_binprm *bprm)
struct page *page = bprm->page[i];
if (page) {
bprm->page[i] = NULL;
- current->mm->rss++;
put_dirty_page(current,page,stack_base);
}
stack_base += PAGE_SIZE;
}
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
return 0;
}
diff --git a/arch/s390x/kernel/linux32.c b/arch/s390x/kernel/linux32.c
index 668ac46c4..c567d4b49 100644
--- a/arch/s390x/kernel/linux32.c
+++ b/arch/s390x/kernel/linux32.c
@@ -4184,9 +4184,9 @@ static inline long do_mmap2(
goto out;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
diff --git a/arch/s390x/kernel/sys_s390.c b/arch/s390x/kernel/sys_s390.c
index 4c06bd326..e05a8be0b 100644
--- a/arch/s390x/kernel/sys_s390.c
+++ b/arch/s390x/kernel/sys_s390.c
@@ -61,9 +61,9 @@ static inline long do_mmap2(
goto out;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
diff --git a/arch/s390x/mm/fault.c b/arch/s390x/mm/fault.c
index 4c324b690..cd60eb61d 100644
--- a/arch/s390x/mm/fault.c
+++ b/arch/s390x/mm/fault.c
@@ -122,7 +122,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
* task's user address space, so we search the VMAs
*/
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma) {
@@ -176,7 +176,7 @@ good_area:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
/*
@@ -184,7 +184,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/* User mode accesses just cause a SIGSEGV */
if (psw_mask & PSW_PROBLEM_STATE) {
@@ -243,14 +243,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (psw_mask & PSW_PROBLEM_STATE)
do_exit(SIGKILL);
goto no_context;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/*
* Send a sigbus, regardless of whether we were in kernel
diff --git a/arch/s390x/tools/dasdfmt/dasdfmt.c b/arch/s390x/tools/dasdfmt/dasdfmt.c
index 2820fc91d..560feff6b 100644
--- a/arch/s390x/tools/dasdfmt/dasdfmt.c
+++ b/arch/s390x/tools/dasdfmt/dasdfmt.c
@@ -477,7 +477,7 @@ do_format_dasd(char *dev_name,format_data_t format_params,int testmode,
rc=stat(dev_name,&stat_buf);
if (rc) {
- ERRMSG_EXIT(EXIT_FAILURE,"%s: error occured during stat: " \
+ ERRMSG_EXIT(EXIT_FAILURE,"%s: error occurred during stat: " \
"%s\n",prog_name,strerror(errno));
} else {
if (!S_ISBLK(stat_buf.st_mode))
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 2bdcd75ea..e3a27f414 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -77,3 +77,4 @@ DECLARE_EXPORT(__ashldi3);
/* needed by some modules */
EXPORT_SYMBOL(flush_dcache_page);
#endif
+EXPORT_SYMBOL(flush_tlb_page);
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 64007b236..1aaf5a04b 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -57,9 +57,9 @@ do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
goto out;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (file)
fput(file);
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index e284fa65d..7d75f92b5 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -109,7 +109,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
if (in_interrupt() || !mm)
goto no_context;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
@@ -151,7 +151,7 @@ good_area:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
/*
@@ -159,7 +159,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
if (user_mode(regs)) {
tsk->thread.address = address;
@@ -208,14 +208,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (user_mode(regs))
do_exit(SIGKILL);
goto no_context;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/*
* Send a sigbus, regardless of whether we were in kernel
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index 20c0782e7..79e281b96 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -105,8 +105,8 @@ CONFIG_SUN_AURORA=m
#
# CONFIG_SPARCAUDIO is not set
# CONFIG_SPARCAUDIO_AMD7930 is not set
-# CONFIG_SPARCAUDIO_CS4231 is not set
# CONFIG_SPARCAUDIO_DBRI is not set
+# CONFIG_SPARCAUDIO_CS4231 is not set
# CONFIG_SPARCAUDIO_DUMMY is not set
#
@@ -126,7 +126,6 @@ CONFIG_BLK_DEV_NBD=m
# 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
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
@@ -266,6 +265,8 @@ CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_QUOTA is not set
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
CONFIG_AFFS_FS=m
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index cba111a71..32f418f99 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -305,7 +305,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
goto out;
}
#endif
- if(!(child = find_task_by_pid(pid))) {
+ read_lock(&tasklist_lock);
+ child = find_task_by_pid(pid);
+ if (child)
+ get_task_struct(child);
+ read_unlock(&tasklist_lock);
+
+ if (!child) {
pt_error_return(regs, ESRCH);
goto out;
}
@@ -319,7 +325,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
* You'll never be able to kill the process. ;-)
*/
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
if((!child->dumpable ||
(current->uid != child->euid) ||
@@ -330,12 +336,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) {
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
@@ -347,21 +353,21 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
write_unlock_irqrestore(&tasklist_lock, flags);
send_sig(SIGSTOP, child, 1);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
if (!(child->ptrace & PT_PTRACED)) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
if(child->state != TASK_STOPPED) {
if(request != PTRACE_KILL) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
}
if(child->p_pptr != current) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
switch(request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -373,16 +379,16 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
pt_os_succ_return(regs, tmp, (long *)data);
else
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
case PTRACE_PEEKUSR:
read_sunos_user(regs, addr, child, (long *) data);
- goto out;
+ goto out_tsk;
case PTRACE_POKEUSR:
write_sunos_user(regs, addr, child);
- goto out;
+ goto out_tsk;
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: {
@@ -391,7 +397,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
pt_succ_return(regs, 0);
else
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
case PTRACE_GETREGS: {
@@ -402,7 +408,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
rval = verify_area(VERIFY_WRITE, pregs, sizeof(struct pt_regs));
if(rval) {
pt_error_return(regs, -rval);
- goto out;
+ goto out_tsk;
}
__put_user(cregs->psr, (&pregs->psr));
__put_user(cregs->pc, (&pregs->pc));
@@ -414,7 +420,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
#ifdef DEBUG_PTRACE
printk ("PC=%x nPC=%x o7=%x\n", cregs->pc, cregs->npc, cregs->u_regs [15]);
#endif
- goto out;
+ goto out_tsk;
}
case PTRACE_SETREGS: {
@@ -429,7 +435,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
i = verify_area(VERIFY_READ, pregs, sizeof(struct pt_regs));
if(i) {
pt_error_return(regs, -i);
- goto out;
+ goto out_tsk;
}
__get_user(psr, (&pregs->psr));
__get_user(pc, (&pregs->pc));
@@ -446,7 +452,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
for(i = 1; i < 16; i++)
__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]));
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_GETFPREGS: {
@@ -466,7 +472,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
i = verify_area(VERIFY_WRITE, fps, sizeof(struct fps));
if(i) {
pt_error_return(regs, -i);
- goto out;
+ goto out_tsk;
}
for(i = 0; i < 32; i++)
__put_user(child->thread.float_regs[i], (&fps->regs[i]));
@@ -480,7 +486,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
__put_user(child->thread.fpqueue[i].insn, (&fps->fpq[i].insn));
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SETFPREGS: {
@@ -500,7 +506,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
i = verify_area(VERIFY_READ, fps, sizeof(struct fps));
if(i) {
pt_error_return(regs, -i);
- goto out;
+ goto out_tsk;
}
copy_from_user(&child->thread.float_regs[0], &fps->regs[0], (32 * sizeof(unsigned long)));
__get_user(child->thread.fsr, (&fps->fsr));
@@ -511,7 +517,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
__get_user(child->thread.fpqueue[i].insn, (&fps->fpq[i].insn));
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_READTEXT:
@@ -520,13 +526,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
if (res == data) {
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/* Partial read is an IO failure */
if (res >= 0)
res = -EIO;
pt_error_return(regs, -res);
- goto out;
+ goto out_tsk;
}
case PTRACE_WRITETEXT:
@@ -535,13 +541,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
if (res == data) {
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/* Partial write is an IO failure */
if (res >= 0)
res = -EIO;
pt_error_return(regs, -res);
- goto out;
+ goto out_tsk;
}
case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
@@ -550,12 +556,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
case PTRACE_CONT: { /* restart after signal. */
if ((unsigned long) data > _NSIG) {
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
if (addr != 1) {
if (addr & 3) {
pt_error_return(regs, EINVAL);
- goto out;
+ goto out_tsk;
}
#ifdef DEBUG_PTRACE
printk ("Original: %08lx %08lx\n", child->thread.kregs->pc, child->thread.kregs->npc);
@@ -580,7 +586,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
#endif
wake_up_process(child);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/*
@@ -591,19 +597,19 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
case PTRACE_KILL: {
if (child->state == TASK_ZOMBIE) { /* already dead */
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
wake_up_process(child);
child->exit_code = SIGKILL;
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SUNDETACH: { /* detach a process that was attached. */
unsigned long flags;
if ((unsigned long) data > _NSIG) {
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
wake_up_process(child);
@@ -614,15 +620,18 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
SET_LINKS(child);
write_unlock_irqrestore(&tasklist_lock, flags);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/* PTRACE_DUMPCORE unsupported... */
default:
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
+out_tsk:
+ if (child)
+ free_task_struct(child);
out:
unlock_kernel();
}
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 498fdb26f..3b71c98e1 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.67 2000/11/30 08:37:31 anton Exp $
+/* $Id: sys_sparc.c,v 1.68 2001/03/24 09:36:10 davem Exp $
* linux/arch/sparc/kernel/sys_sparc.c
*
* This file contains various random system calls that
@@ -236,9 +236,9 @@ static unsigned long do_mmap2(unsigned long addr, unsigned long len,
if (flags & MAP_SHARED)
current->thread.flags |= SPARC_FLAG_MMAPSHARED;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED);
@@ -284,7 +284,7 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr,
if (old_len > TASK_SIZE - PAGE_SIZE ||
new_len > TASK_SIZE - PAGE_SIZE)
goto out;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
vma = find_vma(current->mm, addr);
if (vma && (vma->vm_flags & VM_SHARED))
current->thread.flags |= SPARC_FLAG_MMAPSHARED;
@@ -309,7 +309,7 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr,
ret = do_mremap(addr, old_len, new_len, flags, new_addr);
out_sem:
current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
out:
return ret;
}
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index adaae6062..5a9b4752a 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.132 2001/02/13 01:16:43 davem Exp $
+/* $Id: sys_sunos.c,v 1.133 2001/03/24 09:36:10 davem Exp $
* sys_sunos.c: SunOS specific syscall compatibility support.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -116,9 +116,9 @@ asmlinkage unsigned long sunos_mmap(unsigned long addr, unsigned long len,
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
retval = do_mmap(file, addr, len, prot, flags, off);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if(!ret_type)
retval = ((retval < PAGE_OFFSET) ? 0 : retval);
@@ -145,7 +145,7 @@ asmlinkage int sunos_brk(unsigned long brk)
unsigned long rlim;
unsigned long newbrk, oldbrk;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
if(ARCH_SUN4C_SUN4) {
if(brk >= 0x20000000 && brk < 0xe0000000) {
goto out;
@@ -208,7 +208,7 @@ asmlinkage int sunos_brk(unsigned long brk)
do_brk(oldbrk, newbrk-oldbrk);
retval = 0;
out:
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
return retval;
}
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 1521d3246..764bca89b 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.118 2000/12/29 07:52:41 anton Exp $
+/* $Id: fault.c,v 1.119 2001/03/24 09:36:10 davem Exp $
* fault.c: Page fault handlers for the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -224,7 +224,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
if (in_interrupt() || !mm)
goto no_context;
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
/*
* The kernel referencing a bad kernel pointer can lock up
@@ -274,7 +274,7 @@ good_area:
default:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
/*
@@ -282,7 +282,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
bad_area_nosemaphore:
/* User mode accesses just cause a SIGSEGV */
@@ -338,14 +338,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (from_user)
do_exit(SIGKILL);
goto no_context;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
@@ -479,7 +479,7 @@ inline void force_user_fault(unsigned long address, int write)
printk("wf<pid=%d,wr=%d,addr=%08lx>\n",
tsk->pid, write, address);
#endif
- down(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if(!vma)
goto bad_area;
@@ -500,10 +500,10 @@ good_area:
}
if (!handle_mm_fault(mm, vma, address, write))
goto do_sigbus;
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
return;
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
#if 0
printk("Window whee %s [%d]: segfaults at %08lx\n",
tsk->comm, tsk->pid, address);
@@ -518,7 +518,7 @@ bad_area:
return;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index d27495bd6..89807b38a 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -1,10 +1,10 @@
-/* $Id: init.c,v 1.96 2000/11/30 08:51:50 anton Exp $
+/* $Id: init.c,v 1.97 2001/02/26 02:57:34 anton Exp $
* linux/arch/sparc/mm/init.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1995 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
*/
#include <linux/config.h>
@@ -53,7 +53,7 @@ extern unsigned int sparc_ramdisk_size;
unsigned long highstart_pfn, highend_pfn;
unsigned long totalram_pages;
-static unsigned long totalhigh_pages;
+unsigned long totalhigh_pages;
/*
* BAD_PAGE is the page that is used for page faults when linux
@@ -134,42 +134,79 @@ void __init sparc_context_init(int numctx)
#define DEBUG_BOOTMEM
extern unsigned long cmdline_memory_size;
-extern unsigned long last_valid_pfn;
+unsigned long last_valid_pfn;
+
+unsigned long calc_highpages(void)
+{
+ int i;
+ int nr = 0;
+
+ for (i = 0; sp_banks[i].num_bytes != 0; i++) {
+ unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
+ unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
+
+ if (end_pfn <= max_low_pfn)
+ continue;
+
+ if (start_pfn < max_low_pfn)
+ start_pfn = max_low_pfn;
+
+ nr += end_pfn - start_pfn;
+ }
+
+ return nr;
+}
+
+unsigned long calc_max_low_pfn(void)
+{
+ int i;
+ unsigned long tmp = (SRMMU_MAXMEM >> PAGE_SHIFT);
+ unsigned long curr_pfn, last_pfn;
+
+ last_pfn = (sp_banks[0].base_addr + sp_banks[0].num_bytes) >> PAGE_SHIFT;
+ for (i = 1; sp_banks[i].num_bytes != 0; i++) {
+ curr_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
-void __init bootmem_init(void)
+ if (curr_pfn >= tmp) {
+ if (last_pfn < tmp)
+ tmp = last_pfn;
+ break;
+ }
+
+ last_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
+ }
+
+ return tmp;
+}
+
+unsigned long __init bootmem_init(unsigned long *pages_avail)
{
unsigned long bootmap_size, start_pfn, max_pfn;
unsigned long end_of_phys_memory = 0UL;
- unsigned long bootmap_pfn;
+ unsigned long bootmap_pfn, bytes_avail, size;
int i;
- /* XXX It is a bit ambiguous here, whether we should
- * XXX treat the user specified mem=xxx as total wanted
- * XXX physical memory, or as a limit to the upper
- * XXX physical address we allow. For now it is the
- * XXX latter. -DaveM
- */
#ifdef DEBUG_BOOTMEM
prom_printf("bootmem_init: Scan sp_banks, ");
#endif
+ bytes_avail = 0UL;
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
end_of_phys_memory = sp_banks[i].base_addr +
sp_banks[i].num_bytes;
+ bytes_avail += sp_banks[i].num_bytes;
if (cmdline_memory_size) {
- if (end_of_phys_memory > cmdline_memory_size) {
- if (cmdline_memory_size < sp_banks[i].base_addr) {
- end_of_phys_memory =
- sp_banks[i-1].base_addr +
- sp_banks[i-1].num_bytes;
+ if (bytes_avail > cmdline_memory_size) {
+ unsigned long slack = bytes_avail - cmdline_memory_size;
+
+ bytes_avail -= slack;
+ end_of_phys_memory -= slack;
+
+ sp_banks[i].num_bytes -= slack;
+ if (sp_banks[i].num_bytes == 0) {
sp_banks[i].base_addr = 0xdeadbeef;
- sp_banks[i].num_bytes = 0;
} else {
- sp_banks[i].num_bytes -=
- (end_of_phys_memory -
- cmdline_memory_size);
- end_of_phys_memory = cmdline_memory_size;
- sp_banks[++i].base_addr = 0xdeadbeef;
- sp_banks[i].num_bytes = 0;
+ sp_banks[i+1].num_bytes = 0;
+ sp_banks[i+1].base_addr = 0xdeadbeef;
}
break;
}
@@ -195,9 +232,9 @@ void __init bootmem_init(void)
highstart_pfn = highend_pfn = max_pfn;
if (max_low_pfn > (SRMMU_MAXMEM >> PAGE_SHIFT)) {
- highstart_pfn = max_low_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT);
- printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
- (highend_pfn - highstart_pfn) >> (20-PAGE_SHIFT));
+ highstart_pfn = (SRMMU_MAXMEM >> PAGE_SHIFT);
+ max_low_pfn = calc_max_low_pfn();
+ printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", calc_highpages());
}
#ifdef CONFIG_BLK_DEV_INITRD
@@ -225,13 +262,14 @@ void __init bootmem_init(void)
prom_printf("init_bootmem(spfn[%lx],bpfn[%lx],mlpfn[%lx])\n",
start_pfn, bootmap_pfn, max_low_pfn);
#endif
- bootmap_size = init_bootmem(bootmap_pfn, max_low_pfn);
+ bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, phys_base>>PAGE_SHIFT, max_low_pfn);
/* Now register the available physical memory with the
* allocator.
*/
+ *pages_avail = 0;
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- unsigned long curr_pfn, last_pfn, size;
+ unsigned long curr_pfn, last_pfn;
curr_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
if (curr_pfn >= max_low_pfn)
@@ -249,7 +287,7 @@ void __init bootmem_init(void)
continue;
size = (last_pfn - curr_pfn) << PAGE_SHIFT;
-
+ *pages_avail += last_pfn - curr_pfn;
#ifdef DEBUG_BOOTMEM
prom_printf("free_bootmem: base[%lx] size[%lx]\n",
sp_banks[i].base_addr,
@@ -259,29 +297,42 @@ void __init bootmem_init(void)
size);
}
- /* Reserve the kernel text/data/bss, the bootmem bitmap and initrd. */
-#ifdef DEBUG_BOOTMEM
#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start)
+ if (initrd_start) {
+ size = initrd_end - initrd_start;
+#ifdef DEBUG_BOOTMEM
prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
- initrd_start, initrd_end - initrd_start);
+ initrd_start, size);
#endif
- prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
- phys_base, (start_pfn << PAGE_SHIFT) - phys_base);
- prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
- (bootmap_pfn << PAGE_SHIFT), bootmap_size);
-#endif
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start) {
- reserve_bootmem(initrd_start, initrd_end - initrd_start);
+ /* Reserve the initrd image area. */
+ reserve_bootmem(initrd_start, size);
+ *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
+
initrd_start += PAGE_OFFSET;
initrd_end += PAGE_OFFSET;
}
#endif
- reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) - phys_base);
- reserve_bootmem((bootmap_pfn << PAGE_SHIFT), bootmap_size);
+ /* Reserve the kernel text/data/bss. */
+ size = (start_pfn << PAGE_SHIFT) - phys_base;
+#ifdef DEBUG_BOOTMEM
+ prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", phys_base, size);
+#endif
+ reserve_bootmem(phys_base, size);
+ *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
+
+ /* Reserve the bootmem map. We do not account for it
+ * in pages_avail because we will release that memory
+ * in free_all_bootmem.
+ */
+ size = bootmap_size;
+#ifdef DEBUG_BOOTMEM
+ prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
+ (bootmap_pfn << PAGE_SHIFT), size);
+#endif
+ reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size);
+ *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
- last_valid_pfn = max_pfn;
+ return max_pfn;
}
/*
@@ -293,8 +344,6 @@ extern void sun4c_paging_init(void);
extern void srmmu_paging_init(void);
extern void device_scan(void);
-unsigned long last_valid_pfn;
-
void __init paging_init(void)
{
switch(sparc_cpu_model) {
@@ -359,71 +408,6 @@ static void __init taint_real_pages(void)
}
}
-void __init free_mem_map_range(struct page *first, struct page *last)
-{
- first = (struct page *) PAGE_ALIGN((unsigned long)first);
- last = (struct page *) ((unsigned long)last & PAGE_MASK);
-#ifdef DEBUG_BOOTMEM
- prom_printf("[%p,%p] ", first, last);
-#endif
- while (first < last) {
- ClearPageReserved(virt_to_page(first));
- set_page_count(virt_to_page(first), 1);
- free_page((unsigned long)first);
- totalram_pages++;
- num_physpages++;
-
- first = (struct page *)((unsigned long)first + PAGE_SIZE);
- }
-}
-
-/* Walk through holes in sp_banks regions, if the mem_map array
- * areas representing those holes consume a page or more, free
- * up such pages. This helps a lot on machines where physical
- * ram is configured such that it begins at some hugh value.
- *
- * The sp_banks array is sorted by base address.
- */
-void __init free_unused_mem_map(void)
-{
- int i;
-
-#ifdef DEBUG_BOOTMEM
- prom_printf("free_unused_mem_map: ");
-#endif
- for (i = 0; sp_banks[i].num_bytes; i++) {
- if (i == 0) {
- struct page *first, *last;
-
- first = mem_map;
- last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT];
- free_mem_map_range(first, last);
- } else {
- struct page *first, *last;
- unsigned long prev_end;
-
- prev_end = sp_banks[i-1].base_addr +
- sp_banks[i-1].num_bytes;
- prev_end = PAGE_ALIGN(prev_end);
- first = &mem_map[prev_end >> PAGE_SHIFT];
- last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT];
-
- free_mem_map_range(first, last);
-
- if (!sp_banks[i+1].num_bytes) {
- prev_end = sp_banks[i].base_addr +
- sp_banks[i].num_bytes;
- first = &mem_map[prev_end >> PAGE_SHIFT];
- last = &mem_map[last_valid_pfn];
- free_mem_map_range(first, last);
- }
- }
- }
-#ifdef DEBUG_BOOTMEM
- prom_printf("\n");
-#endif
-}
-
void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
{
unsigned long tmp;
@@ -458,9 +442,8 @@ void __init mem_init(void)
/* Saves us work later. */
memset((void *)&empty_zero_page, 0, PAGE_SIZE);
- i = last_valid_pfn >> (8 + 5);
+ i = last_valid_pfn >> ((20 - PAGE_SHIFT) + 5);
i += 1;
-
sparc_valid_addr_bitmap = (unsigned long *)
__alloc_bootmem(i << 2, SMP_CACHE_BYTES, 0UL);
@@ -472,7 +455,7 @@ void __init mem_init(void)
taint_real_pages();
- max_mapnr = last_valid_pfn;
+ max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT);
high_memory = __va(max_low_pfn << PAGE_SHIFT);
#ifdef DEBUG_BOOTMEM
@@ -480,10 +463,6 @@ void __init mem_init(void)
#endif
num_physpages = totalram_pages = free_all_bootmem();
-#if 0
- free_unused_mem_map();
-#endif
-
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
@@ -513,19 +492,6 @@ void __init mem_init(void)
initpages << (PAGE_SHIFT-10),
totalhigh_pages << (PAGE_SHIFT-10),
(unsigned long)PAGE_OFFSET, (last_valid_pfn << PAGE_SHIFT));
-
- /* NOTE NOTE NOTE NOTE
- * Please keep track of things and make sure this
- * always matches the code in mm/page_alloc.c -DaveM
- */
- i = nr_free_pages() >> 7;
- if (i < 48)
- i = 48;
- if (i > 256)
- i = 256;
- freepages.min = i;
- freepages.low = i << 1;
- freepages.high = freepages.low + i;
}
void free_initmem (void)
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index a5b2b117b..e2b6116ff 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.226 2001/02/13 01:16:44 davem Exp $
+/* $Id: srmmu.c,v 1.228 2001/03/16 06:56:20 davem Exp $
* srmmu.c: SRMMU specific routines for memory management.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1124,6 +1124,15 @@ static unsigned long __init map_spbank(unsigned long vbase, int sp_entry)
unsigned long pstart = (sp_banks[sp_entry].base_addr & SRMMU_PGDIR_MASK);
unsigned long vstart = (vbase & SRMMU_PGDIR_MASK);
unsigned long vend = SRMMU_PGDIR_ALIGN(vbase + sp_banks[sp_entry].num_bytes);
+ /* Map "low" memory only */
+ const unsigned long min_vaddr = PAGE_OFFSET;
+ const unsigned long max_vaddr = PAGE_OFFSET + SRMMU_MAXMEM;
+
+ if (vstart < min_vaddr || vstart >= max_vaddr)
+ return vstart;
+
+ if (vend > max_vaddr || vend < min_vaddr)
+ vend = max_vaddr;
while(vstart < vend) {
do_large_mapping(vstart, pstart);
@@ -1159,10 +1168,11 @@ static inline void map_kernel(void)
extern void sparc_context_init(int);
extern int linux_num_cpus;
+extern unsigned long totalhigh_pages;
void (*poke_srmmu)(void) __initdata = NULL;
-extern void bootmem_init(void);
+extern unsigned long bootmem_init(unsigned long *pages_avail);
extern void sun_serial_setup(void);
void __init srmmu_paging_init(void)
@@ -1172,6 +1182,7 @@ void __init srmmu_paging_init(void)
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
+ unsigned long pages_avail;
sparc_iomap.start = SUN4M_IOBASE_VADDR; /* 16MB of IOSPACE on all sun4m's. */
@@ -1196,7 +1207,8 @@ void __init srmmu_paging_init(void)
prom_halt();
}
- bootmem_init();
+ pages_avail = 0;
+ last_valid_pfn = bootmem_init(&pages_avail);
srmmu_nocache_init();
srmmu_inherit_prom_mappings(0xfe400000,(LINUX_OPPROM_ENDVM-PAGE_SIZE));
@@ -1245,11 +1257,25 @@ void __init srmmu_paging_init(void)
kmap_init();
{
- unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0};
+ unsigned long zones_size[MAX_NR_ZONES];
+ unsigned long zholes_size[MAX_NR_ZONES];
+ unsigned long npages;
+ int znum;
+
+ for (znum = 0; znum < MAX_NR_ZONES; znum++)
+ zones_size[znum] = zholes_size[znum] = 0;
+
+ npages = max_low_pfn - (phys_base >> PAGE_SHIFT);
+
+ zones_size[ZONE_DMA] = npages;
+ zholes_size[ZONE_DMA] = npages - pages_avail;
+
+ npages = highend_pfn - max_low_pfn;
+ zones_size[ZONE_HIGHMEM] = npages;
+ zholes_size[ZONE_HIGHMEM] = npages - calc_highpages();
- zones_size[ZONE_DMA] = max_low_pfn;
- zones_size[ZONE_HIGHMEM] = highend_pfn - max_low_pfn;
- free_area_init(zones_size);
+ free_area_init_node(0, NULL, NULL, zones_size,
+ phys_base, zholes_size);
}
}
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index ef5157b05..91a1d571e 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1,4 +1,4 @@
-/* $Id: sun4c.c,v 1.202 2000/12/01 03:17:31 anton Exp $
+/* $Id: sun4c.c,v 1.205 2001/03/16 06:57:41 davem Exp $
* sun4c.c: Doing in software what should be done in hardware.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -15,6 +15,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/highmem.h>
#include <asm/scatterlist.h>
#include <asm/page.h>
@@ -31,6 +32,7 @@
#include <asm/openprom.h>
#include <asm/mmu_context.h>
#include <asm/sun4paddr.h>
+#include <asm/highmem.h>
/* Because of our dynamic kernel TLB miss strategy, and how
* our DVMA mapping allocation works, you _MUST_:
@@ -2432,7 +2434,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p
extern void sparc_context_init(int);
extern unsigned long end;
-extern void bootmem_init(void);
+extern unsigned long bootmem_init(unsigned long *pages_avail);
extern unsigned long last_valid_pfn;
extern void sun_serial_setup(void);
@@ -2441,13 +2443,14 @@ void __init sun4c_paging_init(void)
int i, cnt;
unsigned long kernel_end, vaddr;
extern struct resource sparc_iomap;
- unsigned long end_pfn;
+ unsigned long end_pfn, pages_avail;
kernel_end = (unsigned long) &end;
kernel_end += (SUN4C_REAL_PGDIR_SIZE * 4);
kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end);
- bootmem_init();
+ pages_avail = 0;
+ last_valid_pfn = bootmem_init(&pages_avail);
end_pfn = last_valid_pfn;
/* This does not logically belong here, but we need to
@@ -2488,10 +2491,25 @@ void __init sun4c_paging_init(void)
sparc_context_init(num_contexts);
{
- unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0};
+ unsigned long zones_size[MAX_NR_ZONES];
+ unsigned long zholes_size[MAX_NR_ZONES];
+ unsigned long npages;
+ int znum;
- zones_size[ZONE_DMA] = end_pfn;
- free_area_init(zones_size);
+ for (znum = 0; znum < MAX_NR_ZONES; znum++)
+ zones_size[znum] = zholes_size[znum] = 0;
+
+ npages = max_low_pfn - (phys_base >> PAGE_SHIFT);
+
+ zones_size[ZONE_DMA] = npages;
+ zholes_size[ZONE_DMA] = npages - pages_avail;
+
+ npages = highend_pfn - max_low_pfn;
+ zones_size[ZONE_HIGHMEM] = npages;
+ zholes_size[ZONE_HIGHMEM] = npages - calc_highpages();
+
+ free_area_init_node(0, NULL, NULL, zones_size,
+ phys_base, zholes_size);
}
cnt = 0;
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index 2d67b5e54..888b96c6f 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.130 2001/01/18 04:47:44 davem Exp $
+# $Id: config.in,v 1.136 2001/03/24 06:04:24 davem Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
@@ -47,6 +47,9 @@ define_bool CONFIG_SUN_CONSOLE y
define_bool CONFIG_SUN_AUXIO y
define_bool CONFIG_SUN_IO y
bool 'PCI support' CONFIG_PCI
+if [ "$CONFIG_PCI" = "y" ] ; then
+ define_bool CONFIG_RTC y
+fi
source drivers/pci/Config.in
tristate 'Openprom tree appears in /proc/openprom' CONFIG_SUN_OPENPROMFS
@@ -74,6 +77,7 @@ if [ "$CONFIG_PCI" = "y" ]; then
tristate 'SUNW, envctrl support' CONFIG_ENVCTRL
tristate '7-Segment Display support' CONFIG_DISPLAY7SEG
tristate 'CP1XXX Hardware Watchdog support' CONFIG_WATCHDOG_CP1XXX
+ tristate 'RIO Hardware Watchdog support' CONFIG_WATCHDOG_RIO
fi
endmenu
@@ -165,12 +169,14 @@ if [ "$CONFIG_SCSI" != "n" ]; then
dep_tristate 'PTI Qlogic, ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI
if [ "$CONFIG_PCI" != "n" ]; then
- dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
- if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
- bool ' Enable tagged command queueing (TCQ) by default' CONFIG_AIC7XXX_TAGGED_QUEUEING
- int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8
- bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS
- int ' Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5
+ source drivers/scsi/aic7xxx/Config.in
+ if [ "$CONFIG_SCSI_AIC7XXX" != "y" ]; then
+ dep_tristate 'Old Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX_OLD $CONFIG_SCSI
+ if [ "$CONFIG_SCSI_AIC7XXX_OLD" != "n" ]; then
+ bool ' Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT
+ int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE 8
+ bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_OLD_PROC_STATS
+ fi
fi
dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI
dep_tristate 'SYM53C8XX SCSI support' CONFIG_SCSI_SYM53C8XX $CONFIG_SCSI
@@ -197,8 +203,6 @@ if [ "$CONFIG_SCSI" != "n" ]; then
fi
endmenu
-source drivers/message/fusion/Config.in
-
source drivers/fc4/Config.in
if [ "$CONFIG_PCI" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -284,6 +288,7 @@ if [ "$CONFIG_NET" = "y" ]; then
bool ' Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I
fi
tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN
+ tristate 'Sun GEM support' CONFIG_SUNGEM
fi
tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS
endmenu
@@ -325,8 +330,12 @@ bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM
dep_tristate ' Creator/Creator3D' CONFIG_DRM_FFB $CONFIG_DRM
endmenu
+source drivers/input/Config.in
+
source fs/Config.in
+source drivers/usb/Config.in
+
mainmenu_option next_comment
comment 'Watchdog'
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index d80f93cf6..beb7ee7ff 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -38,6 +38,7 @@ CONFIG_SUN_CONSOLE=y
CONFIG_SUN_AUXIO=y
CONFIG_SUN_IO=y
CONFIG_PCI=y
+CONFIG_RTC=y
CONFIG_PCI_NAMES=y
CONFIG_SUN_OPENPROMFS=m
CONFIG_NET=y
@@ -70,6 +71,7 @@ CONFIG_PRINTER=m
CONFIG_ENVCTRL=m
CONFIG_DISPLAY7SEG=m
CONFIG_WATCHDOG_CP1XXX=m
+CONFIG_WATCHDOG_RIO=m
#
# Console drivers
@@ -125,8 +127,8 @@ CONFIG_SUN_AURORA=m
#
# Linux/SPARC audio subsystem (EXPERIMENTAL)
#
-CONFIG_SPARCAUDIO=y
-CONFIG_SPARCAUDIO_CS4231=y
+CONFIG_SPARCAUDIO=m
+CONFIG_SPARCAUDIO_CS4231=m
# CONFIG_SPARCAUDIO_DUMMY is not set
#
@@ -151,7 +153,6 @@ CONFIG_BLK_DEV_NBD=m
# 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
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_INITRD is not set
@@ -305,10 +306,12 @@ CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SUNESP=y
CONFIG_SCSI_QLOGICPTI=m
CONFIG_SCSI_AIC7XXX=m
-CONFIG_AIC7XXX_TAGGED_QUEUEING=y
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
-CONFIG_AIC7XXX_PROC_STATS=y
-CONFIG_AIC7XXX_RESET_DELAY=5
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
+CONFIG_AIC7XXX_RESET_DELAY=5000
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y
+CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8
+CONFIG_AIC7XXX_OLD_PROC_STATS=y
CONFIG_SCSI_NCR53C8XX=m
CONFIG_SCSI_SYM53C8XX=y
CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=4
@@ -318,7 +321,7 @@ CONFIG_SCSI_NCR53C8XX_SYNC=40
# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
CONFIG_SCSI_QLOGIC_ISP=m
-CONFIG_SCSI_QLOGIC_FC=m
+CONFIG_SCSI_QLOGIC_FC=y
#
# Fibre Channel support
@@ -388,6 +391,7 @@ CONFIG_ADAPTEC_STARFIRE=m
CONFIG_ACENIC=m
# CONFIG_ACENIC_OMIT_TIGON_I is not set
CONFIG_SK98LIN=m
+CONFIG_SUNGEM=y
CONFIG_MYRI_SBUS=m
CONFIG_FDDI=y
CONFIG_SKFP=m
@@ -411,6 +415,17 @@ CONFIG_DRM=y
CONFIG_DRM_FFB=m
#
+# 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
+
+#
# File systems
#
# CONFIG_QUOTA is not set
@@ -524,6 +539,99 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_UTF8 is not set
#
+# USB support
+#
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# 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 Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_BLUETOOTH=m
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_WACOM=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_DC2XX=m
+CONFIG_USB_MDC800=m
+CONFIG_USB_SCANNER=m
+CONFIG_USB_MICROTEK=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_OV511=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_DABUSB=m
+
+#
+# USB Network adaptors
+#
+CONFIG_USB_PLUSB=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_NET1080=m
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_SERIAL_DEBUG is not set
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_OMNINET=m
+
+#
+# USB misc drivers
+#
+CONFIG_USB_RIO500=m
+
+#
# Watchdog
#
# CONFIG_SOFT_WATCHDOG is not set
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 8648bb190..218242631 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.63 2000/12/14 22:57:25 davem Exp $
+# $Id: Makefile,v 1.64 2001/02/28 05:59:45 davem Exp $
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
@@ -27,7 +27,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
power.o sbus.o iommu_common.o sparc64_ksyms.o
obj-$(CONFIG_PCI) += ebus.o pci_common.o pci_iommu.o \
- pci_psycho.o pci_sabre.o
+ pci_psycho.o pci_sabre.o pci_schizo.o
obj-$(CONFIG_SMP) += smp.o trampoline.o
obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o ioctl32.o
obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c
index cc26817b4..10787f22f 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/spitfire.h>
#include <asm/starfire.h>
/* Probe and map in the Auxiliary I/O register */
@@ -56,7 +57,7 @@ found_sdev:
return;
}
#endif
- if(central_bus || this_is_starfire) {
+ if (central_bus || this_is_starfire || (tlb_type == cheetah)) {
auxio_register = 0UL;
return;
}
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
index bda2fb6a5..314230ef2 100644
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ b/arch/sparc64/kernel/binfmt_aout32.c
@@ -277,24 +277,24 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
goto beyond_if;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (error != N_TXTADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
}
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset + ex.a_text);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if (error != N_DATADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
@@ -318,7 +318,8 @@ beyond_if:
unsigned long pgd_cache;
pgd_cache = ((unsigned long)current->mm->pgd[0])<<11UL;
- __asm__ __volatile__("stxa\t%0, [%1] %2"
+ __asm__ __volatile__("stxa\t%0, [%1] %2\n\t"
+ "membar #Sync"
: /* no outputs */
: "r" (pgd_cache),
"r" (TSB_REG), "i" (ASI_DMMU));
@@ -368,12 +369,12 @@ static int load_aout32_library(struct file *file)
start_addr = ex.a_entry & 0xfffff000;
/* Now use mmap to map the library into memory. */
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
N_TXTOFF(ex));
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
retval = error;
if (error != start_addr)
goto out;
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c
index 8e1a0367c..a3bf89bb2 100644
--- a/arch/sparc64/kernel/cpu.c
+++ b/arch/sparc64/kernel/cpu.c
@@ -34,7 +34,8 @@ struct cpu_fp_info linux_sparc_fpu[] = {
{ 0x22, 0x10, 0, "UltraSparc II integrated FPU"},
{ 0x17, 0x11, 0, "UltraSparc II integrated FPU"},
{ 0x17, 0x12, 0, "UltraSparc IIi integrated FPU"},
- { 0x17, 0x14, 0, "UltraSparc III integrated FPU"},
+ { 0x17, 0x13, 0, "UltraSparc IIe integrated FPU"},
+ { 0x3e, 0x14, 0, "UltraSparc III integrated FPU"},
};
#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info))
@@ -44,7 +45,8 @@ struct cpu_iu_info linux_sparc_chips[] = {
{ 0x22, 0x10, "TI UltraSparc II (BlackBird)"},
{ 0x17, 0x11, "TI UltraSparc II (BlackBird)"},
{ 0x17, 0x12, "TI UltraSparc IIi"},
- { 0x17, 0x14, "TI UltraSparc III (Cheetah)"}, /* A guess... */
+ { 0x17, 0x13, "TI UltraSparc IIe"},
+ { 0x3e, 0x14, "TI UltraSparc III (Cheetah)"},
};
#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info))
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c
index be8771985..849a44c87 100644
--- a/arch/sparc64/kernel/devices.c
+++ b/arch/sparc64/kernel/devices.c
@@ -13,6 +13,7 @@
#include <asm/oplib.h>
#include <asm/system.h>
#include <asm/smp.h>
+#include <asm/spitfire.h>
struct prom_cpuinfo linux_cpus[64] __initdata = { { 0 } };
unsigned prom_cpu_nodes[64];
@@ -50,8 +51,14 @@ void __init device_scan(void)
if(strcmp(node_str, "cpu") == 0) {
cpu_nds[cpu_ctr] = scan;
linux_cpus[cpu_ctr].prom_node = scan;
- prom_getproperty(scan, "upa-portid",
- (char *) &thismid, sizeof(thismid));
+ thismid = 0;
+ if (tlb_type == spitfire) {
+ prom_getproperty(scan, "upa-portid",
+ (char *) &thismid, sizeof(thismid));
+ } else if (tlb_type == cheetah) {
+ prom_getproperty(scan, "portid",
+ (char *) &thismid, sizeof(thismid));
+ }
linux_cpus[cpu_ctr].mid = thismid;
printk("Found CPU %d (node=%08x,mid=%d)\n",
cpu_ctr, (unsigned) scan, thismid);
diff --git a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S
index 80c74aa18..f3a32d714 100644
--- a/arch/sparc64/kernel/dtlb_base.S
+++ b/arch/sparc64/kernel/dtlb_base.S
@@ -1,4 +1,4 @@
-/* $Id: dtlb_base.S,v 1.8 2000/11/10 08:28:45 davem Exp $
+/* $Id: dtlb_base.S,v 1.9 2001/03/22 00:12:32 davem Exp $
* dtlb_base.S: Front end to DTLB miss replacement strategy.
* This is included directly into the trap table.
*
@@ -10,8 +10,6 @@
#define VPTE_SHIFT (PAGE_SHIFT - 3)
#define KERN_HIGHBITS ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000)
#define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
-#define KERN_LOWBITS_IO (_PAGE_E | _PAGE_P | _PAGE_W)
-#define KERN_IOBITS (KERN_LOWBITS ^ KERN_LOWBITS_IO)
/* %g1 TLB_SFSR (%g1 + %g1 == TLB_TAG_ACCESS)
* %g2 (KERN_HIGHBITS | KERN_LOWBITS)
@@ -94,5 +92,3 @@
#undef VPTE_SHIFT
#undef KERN_HIGHBITS
#undef KERN_LOWBITS
-#undef KERN_LOWBITS_IO
-#undef KERN_IOBITS
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index 6dbe45a6c..a1e633353 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -1,4 +1,4 @@
-/* $Id: ebus.c,v 1.54 2001/02/13 01:16:44 davem Exp $
+/* $Id: ebus.c,v 1.60 2001/03/15 02:11:09 davem Exp $
* ebus.c: PCI to EBus bridge device.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -25,6 +25,7 @@ struct linux_ebus *ebus_chain = 0;
#ifdef CONFIG_SUN_AUXIO
extern void auxio_probe(void);
#endif
+extern void rs_init(void);
static inline void *ebus_alloc(size_t size)
{
@@ -159,7 +160,7 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
struct pci_controller_info *p = pbm->parent;
if (ebus_intmap_match(dev->bus, preg, &irqs[i]) != -1) {
- dev->irqs[i] = p->irq_build(p,
+ dev->irqs[i] = p->irq_build(pbm,
dev->bus->self,
irqs[i]);
} else {
@@ -200,7 +201,10 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
dev->num_addrs = len / sizeof(struct linux_prom_registers);
for (i = 0; i < dev->num_addrs; i++) {
- n = (regs[i].which_io - 0x10) >> 2;
+ if (dev->bus->is_rio == 0)
+ n = (regs[i].which_io - 0x10) >> 2;
+ else
+ n = regs[i].which_io;
dev->resource[i].start = dev->bus->self->resource[n].start;
dev->resource[i].start += (unsigned long)regs[i].phys_addr;
@@ -222,7 +226,7 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
struct pci_controller_info *p = pbm->parent;
if (ebus_intmap_match(dev->bus, &regs[0], &irqs[i]) != -1) {
- dev->irqs[i] = p->irq_build(p,
+ dev->irqs[i] = p->irq_build(pbm,
dev->bus->self,
irqs[i]);
} else {
@@ -269,14 +273,19 @@ void __init ebus_init(void)
struct linux_ebus *ebus;
struct pci_dev *pdev;
struct pcidev_cookie *cookie;
- int nd, ebusnd;
+ int nd, ebusnd, is_rio;
int num_ebus = 0;
if (!pci_present())
return;
+ is_rio = 0;
pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
if (!pdev) {
+ pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_RIO_EBUS, 0);
+ is_rio = 1;
+ }
+ if (!pdev) {
printk("ebus: No EBus's found.\n");
return;
}
@@ -286,6 +295,7 @@ void __init ebus_init(void)
ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
ebus->next = 0;
+ ebus->is_rio = is_rio;
while (ebusnd) {
/* SUNW,pci-qfe uses four empty ebuses on it.
@@ -295,8 +305,16 @@ void __init ebus_init(void)
we'd have to tweak with the ebus_chain
in the runtime after initialization. -jj */
if (!prom_getchild (ebusnd)) {
+ struct pci_dev *orig_pdev = pdev;
+
+ is_rio = 0;
pdev = pci_find_device(PCI_VENDOR_ID_SUN,
- PCI_DEVICE_ID_SUN_EBUS, pdev);
+ PCI_DEVICE_ID_SUN_EBUS, orig_pdev);
+ if (!pdev) {
+ pdev = pci_find_device(PCI_VENDOR_ID_SUN,
+ PCI_DEVICE_ID_SUN_RIO_EBUS, orig_pdev);
+ is_rio = 1;
+ }
if (!pdev) {
if (ebus == ebus_chain) {
ebus_chain = NULL;
@@ -305,7 +323,7 @@ void __init ebus_init(void)
}
break;
}
-
+ ebus->is_rio = is_rio;
cookie = pdev->sysdata;
ebusnd = cookie->prom_node;
continue;
@@ -346,10 +364,20 @@ void __init ebus_init(void)
next_ebus:
printk("\n");
- pdev = pci_find_device(PCI_VENDOR_ID_SUN,
- PCI_DEVICE_ID_SUN_EBUS, pdev);
- if (!pdev)
- break;
+ {
+ struct pci_dev *orig_pdev = pdev;
+
+ is_rio = 0;
+ pdev = pci_find_device(PCI_VENDOR_ID_SUN,
+ PCI_DEVICE_ID_SUN_EBUS, orig_pdev);
+ if (!pdev) {
+ pdev = pci_find_device(PCI_VENDOR_ID_SUN,
+ PCI_DEVICE_ID_SUN_RIO_EBUS, orig_pdev);
+ is_rio = 1;
+ }
+ if (!pdev)
+ break;
+ }
cookie = pdev->sysdata;
ebusnd = cookie->prom_node;
@@ -357,9 +385,11 @@ void __init ebus_init(void)
ebus->next = ebus_alloc(sizeof(struct linux_ebus));
ebus = ebus->next;
ebus->next = 0;
+ ebus->is_rio = is_rio;
++num_ebus;
}
+ rs_init();
#ifdef CONFIG_SUN_AUXIO
auxio_probe();
#endif
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index fd6096ec5..9aed69e26 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.120 2000/09/08 13:58:12 jj Exp $
+/* $Id: entry.S,v 1.127 2001/03/23 07:56:30 davem Exp $
* arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points.
*
* Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -42,13 +42,29 @@ sparc64_vpte_patchme2:
/* This is trivial with the new code... */
.globl do_fpdis
do_fpdis:
- ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g5 ! Load Group
sethi %hi(TSTATE_PEF), %g4 ! IEU0
+ rdpr %tstate, %g5
+ andcc %g5, %g4, %g0
+ be,pt %xcc, 1f
+ nop
+ rd %fprs, %g5
+ andcc %g5, FPRS_FEF, %g0
+ be,pt %xcc, 1f
+ nop
+
+ /* Legal state when DCR_IFPOE is set in Cheetah %dcr. */
+ sethi %hi(109f), %g7
+ ba,pt %xcc, etrap
+109: or %g7, %lo(109b), %g7
+ add %g0, %g0, %g0
+ ba,a,pt %xcc, rtrap_clr_l6
+
+1: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g5 ! Load Group
wr %g0, FPRS_FEF, %fprs ! LSU Group+4bubbles
andcc %g5, FPRS_FEF, %g0 ! IEU1 Group
be,a,pt %icc, 1f ! CTI
clr %g7 ! IEU0
- ldub [%g6 + AOFF_task_thread + AOFF_thread_gsr], %g7 ! Load Group
+ ldx [%g6 + AOFF_task_thread + AOFF_thread_gsr], %g7 ! Load Group
1: andcc %g5, FPRS_DL, %g0 ! IEU1
bne,pn %icc, 2f ! CTI
fzero %f0 ! FPA
@@ -92,10 +108,9 @@ do_fpdis:
ldxa [%g3] ASI_DMMU, %g5
add %g6, AOFF_task_fpregs + 0xc0, %g2
stxa %g0, [%g3] ASI_DMMU
+ membar #Sync
faddd %f0, %f2, %f8
fmuld %f0, %f2, %f10
- flush %g6
- membar #StoreLoad | #LoadLoad
ldda [%g1] ASI_BLK_S, %f32 ! grrr, where is ASI_BLK_NUCLEUS 8-(
ldda [%g2] ASI_BLK_S, %f48
faddd %f0, %f2, %f12
@@ -118,11 +133,10 @@ do_fpdis:
ldxa [%g3] ASI_DMMU, %g5
add %g6, AOFF_task_fpregs, %g1
stxa %g0, [%g3] ASI_DMMU
+ membar #Sync
add %g6, AOFF_task_fpregs + 0x40, %g2
faddd %f32, %f34, %f36
fmuld %f32, %f34, %f38
- flush %g6
- membar #StoreLoad | #LoadLoad
ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-(
ldda [%g2] ASI_BLK_S, %f16
faddd %f32, %f34, %f40
@@ -137,15 +151,14 @@ do_fpdis:
fmuld %f32, %f34, %f58
faddd %f32, %f34, %f60
fmuld %f32, %f34, %f62
- b,pt %xcc, fpdis_exit
+ ba,pt %xcc, fpdis_exit
membar #Sync
3: mov SECONDARY_CONTEXT, %g3
add %g6, AOFF_task_fpregs, %g1
ldxa [%g3] ASI_DMMU, %g5
mov 0x40, %g2
stxa %g0, [%g3] ASI_DMMU
- flush %g6
- membar #StoreLoad | #LoadLoad
+ membar #Sync
ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-(
ldda [%g1 + %g2] ASI_BLK_S, %f16
add %g1, 0x80, %g1
@@ -154,7 +167,7 @@ do_fpdis:
membar #Sync
fpdis_exit:
stxa %g5, [%g3] ASI_DMMU
- flush %g6
+ membar #Sync
fpdis_exit2:
wr %g7, 0, %gsr
ldx [%g6 + AOFF_task_thread + AOFF_thread_xfsr], %fsr
@@ -164,22 +177,152 @@ fpdis_exit2:
wr %g0, FPRS_FEF, %fprs ! clean DU/DL bits
retry
+ .align 32
+fp_other_bounce:
+ call do_fpother
+ add %sp, STACK_BIAS + REGWIN_SZ, %o0
+ ba,pt %xcc, rtrap
+ clr %l6
+
+ .globl do_fpother_check_fitos
+ .align 32
+do_fpother_check_fitos:
+ sethi %hi(fp_other_bounce - 4), %g7
+ or %g7, %lo(fp_other_bounce - 4), %g7
+
+ /* NOTE: Need to preserve %g7 until we fully commit
+ * to the fitos fixup.
+ */
+ stx %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr]
+ rdpr %tstate, %g3
+ andcc %g3, TSTATE_PRIV, %g0
+ bne,pn %xcc, do_fptrap_after_fsr
+ nop
+ ldx [%g6 + AOFF_task_thread + AOFF_thread_xfsr], %g3
+ srlx %g3, 14, %g1
+ and %g1, 7, %g1
+ cmp %g1, 2 ! Unfinished FP-OP
+ bne,pn %xcc, do_fptrap_after_fsr
+ sethi %hi(1 << 23), %g1 ! Inexact
+ andcc %g3, %g1, %g0
+ bne,pn %xcc, do_fptrap_after_fsr
+ rdpr %tpc, %g1
+ lduwa [%g1] ASI_AIUP, %g3 ! This cannot ever fail
+#define FITOS_MASK 0xc1f83fe0
+#define FITOS_COMPARE 0x81a01880
+ sethi %hi(FITOS_MASK), %g1
+ or %g1, %lo(FITOS_MASK), %g1
+ and %g3, %g1, %g1
+ sethi %hi(FITOS_COMPARE), %g2
+ or %g2, %lo(FITOS_COMPARE), %g2
+ cmp %g1, %g2
+ bne,pn %xcc, do_fptrap_after_fsr
+ nop
+ std %f62, [%g6 + AOFF_task_fpregs + (62 * 4)]
+ sethi %hi(fitos_table_1), %g1
+ and %g3, 0x1f, %g2
+ or %g1, %lo(fitos_table_1), %g1
+ sllx %g2, 2, %g2
+ jmpl %g1 + %g2, %g0
+ ba,pt %xcc, fitos_emul_continue
+
+fitos_table_1:
+ fitod %f0, %f62
+ fitod %f1, %f62
+ fitod %f2, %f62
+ fitod %f3, %f62
+ fitod %f4, %f62
+ fitod %f5, %f62
+ fitod %f6, %f62
+ fitod %f7, %f62
+ fitod %f8, %f62
+ fitod %f9, %f62
+ fitod %f10, %f62
+ fitod %f11, %f62
+ fitod %f12, %f62
+ fitod %f13, %f62
+ fitod %f14, %f62
+ fitod %f15, %f62
+ fitod %f16, %f62
+ fitod %f17, %f62
+ fitod %f18, %f62
+ fitod %f19, %f62
+ fitod %f20, %f62
+ fitod %f21, %f62
+ fitod %f22, %f62
+ fitod %f23, %f62
+ fitod %f24, %f62
+ fitod %f25, %f62
+ fitod %f26, %f62
+ fitod %f27, %f62
+ fitod %f28, %f62
+ fitod %f29, %f62
+ fitod %f30, %f62
+ fitod %f31, %f62
+
+fitos_emul_continue:
+ sethi %hi(fitos_table_2), %g1
+ srl %g3, 25, %g2
+ or %g1, %lo(fitos_table_2), %g1
+ and %g2, 0x1f, %g2
+ sllx %g2, 2, %g2
+ jmpl %g1 + %g2, %g0
+ ba,pt %xcc, fitos_emul_fini
+
+fitos_table_2:
+ fdtos %f62, %f0
+ fdtos %f62, %f1
+ fdtos %f62, %f2
+ fdtos %f62, %f3
+ fdtos %f62, %f4
+ fdtos %f62, %f5
+ fdtos %f62, %f6
+ fdtos %f62, %f7
+ fdtos %f62, %f8
+ fdtos %f62, %f9
+ fdtos %f62, %f10
+ fdtos %f62, %f11
+ fdtos %f62, %f12
+ fdtos %f62, %f13
+ fdtos %f62, %f14
+ fdtos %f62, %f15
+ fdtos %f62, %f16
+ fdtos %f62, %f17
+ fdtos %f62, %f18
+ fdtos %f62, %f19
+ fdtos %f62, %f20
+ fdtos %f62, %f21
+ fdtos %f62, %f22
+ fdtos %f62, %f23
+ fdtos %f62, %f24
+ fdtos %f62, %f25
+ fdtos %f62, %f26
+ fdtos %f62, %f27
+ fdtos %f62, %f28
+ fdtos %f62, %f29
+ fdtos %f62, %f30
+ fdtos %f62, %f31
+
+fitos_emul_fini:
+ ldd [%g6 + AOFF_task_fpregs + (62 * 4)], %f62
+ done
+
.globl do_fptrap
.align 32
do_fptrap:
- ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3
stx %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr]
+do_fptrap_after_fsr:
+ ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3
rd %fprs, %g1
or %g3, %g1, %g3
stb %g3, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved]
rd %gsr, %g3
- stb %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr]
+ stx %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr]
mov SECONDARY_CONTEXT, %g3
add %g6, AOFF_task_fpregs, %g2
ldxa [%g3] ASI_DMMU, %g5
stxa %g0, [%g3] ASI_DMMU
- flush %g6
- membar #StoreStore | #LoadStore
+ membar #Sync
andcc %g1, FPRS_DL, %g0
be,pn %icc, 4f
mov 0x40, %g3
@@ -193,7 +336,7 @@ do_fptrap:
5: mov SECONDARY_CONTEXT, %g1
membar #Sync
stxa %g5, [%g1] ASI_DMMU
- flush %g6
+ membar #Sync
ba,pt %xcc, etrap
wr %g0, 0, %fprs
@@ -215,7 +358,7 @@ do_fptrap:
.globl do_ivec
do_ivec:
mov 0x40, %g3
- ldxa [%g3 + %g0] ASI_UDB_INTR_R, %g3
+ ldxa [%g3 + %g0] ASI_INTR_R, %g3
sethi %hi(KERNBASE), %g4
cmp %g3, %g4
bgeu,pn %xcc, do_ivec_xcall
@@ -242,10 +385,10 @@ do_ivec:
do_ivec_xcall:
mov 0x50, %g1
- ldxa [%g1 + %g0] ASI_UDB_INTR_R, %g1
+ ldxa [%g1 + %g0] ASI_INTR_R, %g1
srl %g3, 0, %g3
mov 0x60, %g7
- ldxa [%g7 + %g0] ASI_UDB_INTR_R, %g7
+ ldxa [%g7 + %g0] ASI_INTR_R, %g7
stxa %g0, [%g0] ASI_INTR_RECEIVE
membar #Sync
jmpl %g3, %g0
@@ -1114,9 +1257,18 @@ do_gettimeofday: /* %o0 = timevalp */
ldx [%g3 + %lo(timer_tick_offset)], %g3
or %g2, %lo(xtime), %g2
or %g1, %lo(timer_tick_compare), %g1
-1: ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o4
- rd %tick, %o1
- ldx [%g1], %g7
+1: rdpr %ver, %o2
+ sethi %hi(0x003e0014), %o1
+ srlx %o2, 32, %o2
+ or %o1, %lo(0x003e0014), %o1
+ ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o4
+ cmp %o2, %o1
+ bne,pt %xcc, 2f
+ nop
+ ba,pt %xcc, 3f
+ rd %asr24, %o1
+2: rd %tick, %o1
+3: ldx [%g1], %g7
ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o2
xor %o4, %o2, %o2
xor %o5, %o3, %o3
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
index b0a8f766d..c6df20212 100644
--- a/arch/sparc64/kernel/etrap.S
+++ b/arch/sparc64/kernel/etrap.S
@@ -1,4 +1,4 @@
-/* $Id: etrap.S,v 1.43 2000/03/29 09:55:30 davem Exp $
+/* $Id: etrap.S,v 1.44 2001/03/22 00:51:25 davem Exp $
* etrap.S: Preparing for entry into the kernel on Sparc V9.
*
* Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -186,3 +186,5 @@ scetrap: rdpr %pil, %g2 ! Single Group
nop
#undef TASK_REGOFF
+#undef ETRAP_PSTATE1
+#undef ETRAP_PSTATE2
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 5e855ad2c..6d52fb821 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.65 2000/05/09 17:40:13 davem Exp $
+/* $Id: head.S,v 1.75 2001/03/22 09:54:26 davem Exp $
* head.S: Initial boot code for the Sparc64 port of Linux.
*
* Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -21,6 +21,8 @@
#include <asm/signal.h>
#include <asm/processor.h>
#include <asm/lsu.h>
+#include <asm/dcr.h>
+#include <asm/dcu.h>
#include <asm/head.h>
#include <asm/ttable.h>
@@ -76,11 +78,145 @@ sparc_ramdisk_size:
* PROM entry point is on %o4
*/
sparc64_boot:
+ rdpr %ver, %g1
+ sethi %hi(0x003e0014), %g5
+ srlx %g1, 32, %g1
+ or %g5, %lo(0x003e0014), %g5
+ cmp %g1, %g5
+ bne,pt %icc, spitfire_boot
+ nop
+
+cheetah_boot:
+ mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
+ wr %g1, %asr18
+
+ sethi %uhi(DCU_ME | DCU_RE | DCU_PE | DCU_HPE | DCU_SPE | DCU_SL | DCU_WE), %g5
+ or %g5, %ulo(DCU_ME | DCU_RE | DCU_PE | DCU_HPE | DCU_SPE | DCU_SL | DCU_WE), %g5
+ sllx %g5, 32, %g5
+ or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
+ ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
+ or %g5, %g3, %g5
+ stxa %g5, [%g0] ASI_DCU_CONTROL_REG
+ membar #Sync
+
+ wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
+ wr %g0, 0, %fprs
+
+ /* Just like for Spitfire, we probe itlb-2 for a mapping which
+ * matches our current %pc. We take the physical address in
+ * that mapping and use it to make our own.
+ */
+
+ /* %g5 holds the tlb data */
+ sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
+ sllx %g5, 32, %g5
+ or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5
+
+ /* Put PADDR tlb data mask into %g3. */
+ sethi %uhi(_PAGE_PADDR), %g3
+ or %g3, %ulo(_PAGE_PADDR), %g3
+ sllx %g3, 32, %g3
+ sethi %hi(_PAGE_PADDR), %g7
+ or %g7, %lo(_PAGE_PADDR), %g7
+ or %g3, %g7, %g3
+
+ set 2 << 16, %l0 /* TLB entry walker. */
+ set 0x1fff, %l2 /* Page mask. */
+ rd %pc, %l3
+ andn %l3, %l2, %g2 /* vaddr comparator */
+
+1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1
+ membar #Sync
+ andn %g1, %l2, %g1
+ cmp %g1, %g2
+ be,pn %xcc, cheetah_got_tlbentry
+ nop
+ and %l0, (127 << 3), %g1
+ cmp %g1, (127 << 3)
+ blu,pt %xcc, 1b
+ add %l0, (1 << 3), %l0
+
+cheetah_got_tlbentry:
+ ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1
+ membar #Sync
+ and %g1, %g3, %g1
+ sub %g1, %g2, %g1
+ or %g5, %g1, %g5
+
+ /* Clear out any KERNBASE area entries. */
+ set 2 << 16, %l0
+ sethi %hi(KERNBASE), %g3
+ sethi %hi(KERNBASE<<1), %g7
+ mov TLB_TAG_ACCESS, %l7
+
+ /* First, check ITLB */
+1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1
+ membar #Sync
+ andn %g1, %l2, %g1
+ cmp %g1, %g3
+ blu,pn %xcc, 2f
+ cmp %g1, %g7
+ bgeu,pn %xcc, 2f
+ nop
+ stxa %g0, [%l7] ASI_IMMU
+ membar #Sync
+ stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS
+ membar #Sync
+
+2: and %l0, (127 << 3), %g1
+ cmp %g1, (127 << 3)
+ blu,pt %xcc, 1b
+ add %l0, (1 << 3), %l0
+
+ /* Next, check DTLB */
+ set 2 << 16, %l0
+1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1
+ membar #Sync
+ andn %g1, %l2, %g1
+ cmp %g1, %g3
+ blu,pn %xcc, 2f
+ cmp %g1, %g7
+ bgeu,pn %xcc, 2f
+ nop
+ stxa %g0, [%l7] ASI_DMMU
+ membar #Sync
+ stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
+ membar #Sync
+
+2: and %l0, (511 << 3), %g1
+ cmp %g1, (511 << 3)
+ blu,pt %xcc, 1b
+ add %l0, (1 << 3), %l0
+
+ /* Now lock the TTE we created into ITLB-0 and DTLB-0,
+ * entry 15.
+ */
+ sethi %hi(KERNBASE), %g3
+ set (0 << 16) | (15 << 3), %g7
+ stxa %g3, [%l7] ASI_DMMU
+ membar #Sync
+ stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS
+ membar #Sync
+ stxa %g3, [%l7] ASI_IMMU
+ membar #Sync
+ stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS
+ membar #Sync
+ flush %g3
+ membar #Sync
+ ba,pt %xcc, 1f
+ nop
+
+1: set sun4u_init, %g2
+ jmpl %g2 + %g0, %g0
+ nop
+
+spitfire_boot:
/* Typically PROM has already enabled both MMU's and both on-chip
* caches, but we do it here anyway just to be paranoid.
*/
mov (LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM), %g1
stxa %g1, [%g0] ASI_LSU_CONTROL
+ membar #Sync
/*
* Make sure we are in privileged mode, have address masking,
@@ -93,7 +229,7 @@ sparc64_boot:
wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
wr %g0, 0, %fprs
-create_mappings:
+spitfire_create_mappings:
/* %g5 holds the tlb data */
sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
sllx %g5, 32, %g5
@@ -104,11 +240,11 @@ create_mappings:
*/
/* Put PADDR tlb data mask into %g3. */
- sethi %uhi(_PAGE_PADDR), %g3
- or %g3, %ulo(_PAGE_PADDR), %g3
+ sethi %uhi(_PAGE_PADDR_SF), %g3
+ or %g3, %ulo(_PAGE_PADDR_SF), %g3
sllx %g3, 32, %g3
- sethi %hi(_PAGE_PADDR), %g7
- or %g7, %lo(_PAGE_PADDR), %g7
+ sethi %hi(_PAGE_PADDR_SF), %g7
+ or %g7, %lo(_PAGE_PADDR_SF), %g7
or %g3, %g7, %g3
/* Walk through entire ITLB, looking for entry which maps
@@ -126,13 +262,13 @@ create_mappings:
nop
andn %g1, %l2, %g1 /* Get vaddr */
cmp %g1, %g2
- be,a,pn %xcc, got_tlbentry
+ be,a,pn %xcc, spitfire_got_tlbentry
ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1
cmp %l0, (63 << 3)
blu,pt %xcc, 1b
add %l0, (1 << 3), %l0
-got_tlbentry:
+spitfire_got_tlbentry:
/* Nops here again, perhaps Cheetah/Blackbird are better behaved... */
nop
nop
@@ -164,6 +300,7 @@ got_tlbentry:
nop
stxa %g0, [%l7] ASI_IMMU
stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS
+ membar #Sync
2:
cmp %l0, (63 << 3)
blu,pt %xcc, 1b
@@ -186,6 +323,7 @@ got_tlbentry:
nop
stxa %g0, [%l7] ASI_DMMU
stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
+ membar #Sync
2:
cmp %l0, (63 << 3)
blu,pt %xcc, 1b
@@ -235,7 +373,47 @@ sun4u_init:
mov TLB_TAG_ACCESS, %g2
stxa %g3, [%g2] ASI_IMMU
stxa %g3, [%g2] ASI_DMMU
+ membar #Sync
+
+ rdpr %ver, %g1
+ sethi %hi(0x003e0014), %g5
+ srlx %g1, 32, %g1
+ or %g5, %lo(0x003e0014), %g5
+ cmp %g1, %g5
+ bne,pt %icc, spitfire_tlb_fixup
+ nop
+
+cheetah_tlb_fixup:
+ set (0 << 16) | (15 << 3), %g7
+ ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1
+ andn %g1, (_PAGE_G), %g1
+ stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS
+ membar #Sync
+ ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1
+ andn %g1, (_PAGE_G), %g1
+ stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS
+ membar #Sync
+
+ /* Kill instruction prefetch queues. */
+ flush %g3
+ membar #Sync
+
+ /* Set TLB type to cheetah. */
+ mov 1, %g2
+ sethi %hi(tlb_type), %g5
+ stw %g2, [%g5 + %lo(tlb_type)]
+
+ /* Patch copy/page operations to cheetah optimized versions. */
+ call cheetah_patch_copyops
+ nop
+ call cheetah_patch_pgcopyops
+ nop
+
+ ba,pt %xcc, tlb_fixup_done
+ nop
+
+spitfire_tlb_fixup:
mov (63 << 3), %g7
ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1
andn %g1, (_PAGE_G), %g1
@@ -251,6 +429,12 @@ sun4u_init:
flush %g3
membar #Sync
+ /* Set TLB type to spitfire. */
+ mov 0, %g2
+ sethi %hi(tlb_type), %g5
+ stw %g2, [%g5 + %lo(tlb_type)]
+
+tlb_fixup_done:
sethi %hi(init_task_union), %g6
or %g6, %lo(init_task_union), %g6
mov %sp, %l6
@@ -285,28 +469,19 @@ sun4u_init:
wrpr %g0, 0x0, %tl
/* Clear the bss */
- sethi %hi(8191), %l2
- or %l2, %lo(8191), %l2
- sethi %hi(__bss_start), %l0
- or %l0, %lo(__bss_start), %l0
- sethi %hi(_end), %l1
- or %l1, %lo(_end), %l1
- add %l1, %l2, %l1
- andn %l1, %l2, %l1
- add %l2, 1, %l2
- add %l0, %g0, %o0
-1:
- mov %l2, %o1
+ sethi %hi(__bss_start), %o0
+ or %o0, %lo(__bss_start), %o0
+ sethi %hi(_end), %o1
+ or %o1, %lo(_end), %o1
call __bzero
- add %l0, %l2, %l0
- cmp %l0, %l1
- blu,pt %xcc, 1b
- add %l0, %g0, %o0
+ sub %o1, %o0, %o1
/* Now clear empty_zero_page */
- mov %l2, %o1
+ sethi %hi(8192), %o1
+ or %o1, %lo(8192), %o1
+ sethi %hi(KERNBASE), %g3
call __bzero
- mov %g3, %o0
+ or %g3, %lo(KERNBASE), %o0
mov %l6, %o1 ! OpenPROM stack
call prom_init
@@ -340,14 +515,16 @@ setup_tba: /* i0 = is_starfire */
wrpr %o1, (PSTATE_MG|PSTATE_IE), %pstate
/* Set fixed globals used by dTLB miss handler. */
-#define KERN_HIGHBITS ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000)
+#define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000)
#define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
-#ifdef THIS_IS_CHEETAH
-#error Dave, make sure you took care of other issues in rest of sparc64 code...
-#define VPTE_BASE 0xffe0000000000000
-#else /* Spitfire/Blackbird */
-#define VPTE_BASE 0xfffffffe00000000
+
+#define VPTE_BASE_SPITFIRE 0xfffffffe00000000
+#if 1
+#define VPTE_BASE_CHEETAH VPTE_BASE_SPITFIRE
+#else
+#define VPTE_BASE_CHEETAH 0xffe0000000000000
#endif
+
mov TSB_REG, %g1
stxa %g0, [%g1] ASI_DMMU
membar #Sync
@@ -356,13 +533,30 @@ setup_tba: /* i0 = is_starfire */
or %g2, %ulo(KERN_HIGHBITS), %g2
sllx %g2, 32, %g2
or %g2, KERN_LOWBITS, %g2
- sethi %uhi(VPTE_BASE), %g3
- or %g3, %ulo(VPTE_BASE), %g3
- sllx %g3, 32, %g3
+
+ rdpr %ver, %g3
+ sethi %hi(0x003e0014), %g7
+ srlx %g3, 32, %g3
+ or %g7, %lo(0x003e0014), %g7
+ cmp %g3, %g7
+ bne,pt %icc, 1f
+ nop
+
+ sethi %uhi(VPTE_BASE_CHEETAH), %g3
+ or %g3, %ulo(VPTE_BASE_CHEETAH), %g3
+ ba,pt %xcc, 2f
+ sllx %g3, 32, %g3
+1:
+ sethi %uhi(VPTE_BASE_SPITFIRE), %g3
+ or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3
+ sllx %g3, 32, %g3
+
+2:
clr %g7
#undef KERN_HIGHBITS
#undef KERN_LOWBITS
-#undef VPTE_BASE
+#undef VPTE_BASE_SPITFIRE
+#undef VPTE_BASE_CHEETAH
/* Setup Interrupt globals */
wrpr %o1, (PSTATE_IG|PSTATE_IE), %pstate
@@ -371,9 +565,6 @@ setup_tba: /* i0 = is_starfire */
or %g5, %lo(__up_workvec), %g6
#else
/* By definition of where we are, this is boot_cpu. */
- sethi %hi(cpu_data), %g5
- or %g5, %lo(cpu_data), %g5
-
brz,pt %i0, not_starfire
sethi %hi(0x1fff4000), %g1
or %g1, %lo(0x1fff4000), %g1
@@ -384,12 +575,27 @@ setup_tba: /* i0 = is_starfire */
nop
not_starfire:
+ rdpr %ver, %g1
+ sethi %hi(0x003e0014), %g5
+ srlx %g1, 32, %g1
+ or %g7, %lo(0x003e0014), %g5
+ cmp %g1, %g5
+ bne,pt %icc, not_cheetah
+ nop
+
+ ldxa [%g0] ASI_SAFARI_CONFIG, %g1
+ srlx %g1, 17, %g1
+ and %g1, 0x3ff, %g1 ! 10bit Safari Agent ID
+
+not_cheetah:
ldxa [%g0] ASI_UPA_CONFIG, %g1
srlx %g1, 17, %g1
and %g1, 0x1f, %g1
/* In theory this is: &(cpu_data[boot_cpu_id].irq_worklists[0]) */
set_worklist:
+ sethi %hi(cpu_data), %g5
+ or %g5, %lo(cpu_data), %g5
sllx %g1, 7, %g1
add %g5, %g1, %g5
add %g5, 64, %g6
@@ -398,9 +604,23 @@ set_worklist:
/* Kill PROM timer */
wr %g0, 0, %tick_cmpr
+ rdpr %ver, %g1
+ sethi %hi(0x003e0014), %g5
+ srlx %g1, 32, %g1
+ or %g7, %lo(0x003e0014), %g5
+ cmp %g1, %g5
+ bne,pt %icc, 1f
+ nop
+
+ /* Disable STICK_INT interrupts. */
+ sethi %hi(0x80000000), %g1
+ sllx %g1, 32, %g1
+ wr %g1, %asr25
+
/* Ok, we're done setting up all the state our trap mechanims needs,
* now get back into normal globals and let the PROM know what is up.
*/
+1:
wrpr %g0, %g0, %wstate
wrpr %o1, PSTATE_IE, %pstate
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index e2cdc3613..621e5762f 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.107 2001/02/13 01:16:44 davem Exp $
+/* $Id: ioctl32.c,v 1.110 2001/03/22 12:51:25 davem Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
@@ -48,6 +48,7 @@
#include <linux/blkpg.h>
#include <linux/blk.h>
#include <linux/elevator.h>
+#include <linux/rtc.h>
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
/* Ugh. This header really is not clean */
#define min min
@@ -67,7 +68,6 @@
#include <asm/fbio.h>
#include <asm/kbio.h>
#include <asm/vuid_event.h>
-#include <asm/rtc.h>
#include <asm/openpromio.h>
#include <asm/envctrl.h>
#include <asm/audioio.h>
@@ -2068,6 +2068,7 @@ typedef struct {
u32 proc;
u32 pv[ABS_MAX_PV + 1];
u32 lv[ABS_MAX_LV + 1];
+ uint8_t vg_uuid[UUID_LEN+1]; /* volume group UUID */
} vg32_t;
typedef struct {
@@ -2093,6 +2094,7 @@ typedef struct {
uint32_t pe_stale;
u32 pe;
u32 inode;
+ uint8_t pv_uuid[UUID_LEN+1];
} pv32_t;
typedef struct {
@@ -2103,9 +2105,16 @@ typedef struct {
typedef struct {
u32 lv_index;
u32 lv;
+ /* Transfer size because user space and kernel space differ */
+ uint16_t size;
} lv_status_byindex_req32_t;
typedef struct {
+ dev_t dev;
+ u32 lv;
+} lv_status_bydev_req32_t;
+
+typedef struct {
uint8_t lv_name[NAME_LEN];
kdev_t old_dev;
kdev_t new_dev;
@@ -2204,11 +2213,12 @@ static lv_t *get_lv_t(u32 p, int *errp)
if (l->lv_block_exception) {
lbe32 = (lv_block_exception32_t *)A(ptr2);
memset(lbe, 0, size);
- for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) {
- err |= get_user(lbe->rsector_org, &lbe32->rsector_org);
- err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);
- err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);
- err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);
+ for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) {
+ err |= get_user(lbe->rsector_org, &lbe32->rsector_org);
+ err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);
+ err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);
+ err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);
+
}
}
}
@@ -2239,8 +2249,9 @@ static int copy_lv_t(u32 ptr, lv_t *l)
err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr,
((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
size = l->lv_allocated_le * sizeof(pe_t);
- err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);
- return -EFAULT;
+ if (ptr1)
+ err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);
+ return err ? -EFAULT : 0;
}
static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -2250,7 +2261,8 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
lv_req_t lv_req;
le_remap_req_t le_remap;
lv_status_byindex_req_t lv_byindex;
- pv_status_req32_t pv_status;
+ lv_status_bydev_req_t lv_bydev;
+ pv_status_req_t pv_status;
} u;
pv_t p;
int err;
@@ -2273,6 +2285,11 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
kfree(v);
return -EFAULT;
}
+ if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {
+ kfree(v);
+ return -EFAULT;
+ }
+
karg = v;
memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv));
if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV)
@@ -2286,11 +2303,18 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
err = -ENOMEM;
break;
}
- err = copy_from_user(v->pv[i], (void *)A(ptr), sizeof(pv32_t) - 8);
+ err = copy_from_user(v->pv[i], (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err) {
err = -EFAULT;
break;
}
+ err = copy_from_user(v->pv[i]->pv_uuid, ((pv32_t *)A(ptr))->pv_uuid, UUID_LEN+1);
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+
+
v->pv[i]->pe = NULL; v->pv[i]->inode = NULL;
}
}
@@ -2309,8 +2333,9 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
case LV_EXTEND:
case LV_REDUCE:
case LV_REMOVE:
+ case LV_RENAME:
case LV_STATUS_BYNAME:
- err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
+ err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
if (err) return -EFAULT;
if (cmd != LV_REMOVE) {
err = __get_user(ptr, &((lv_req32_t *)arg)->lv);
@@ -2319,24 +2344,29 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
} else
u.lv_req.lv = NULL;
break;
+
+
case LV_STATUS_BYINDEX:
err = get_user(u.lv_byindex.lv_index, &((lv_status_byindex_req32_t *)arg)->lv_index);
err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);
if (err) return err;
u.lv_byindex.lv = get_lv_t(ptr, &err);
break;
+ case LV_STATUS_BYDEV:
+ err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);
+ u.lv_bydev.lv = get_lv_t(ptr, &err);
+ if (err) return err;
+ u.lv_bydev.lv = &p;
+ p.pe = NULL; p.inode = NULL;
+ break;
case VG_EXTEND:
- err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8);
+ err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
+ if (err) return -EFAULT;
+ err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
if (err) return -EFAULT;
p.pe = NULL; p.inode = NULL;
karg = &p;
break;
- case LE_REMAP:
- err = copy_from_user(&u.le_remap, (void *)arg, sizeof(le_remap_req32_t));
- if (err) return -EFAULT;
- u.le_remap.new_pe = ((le_remap_req32_t *)&u.le_remap)->new_pe;
- u.le_remap.old_pe = ((le_remap_req32_t *)&u.le_remap)->old_pe;
- break;
case PV_CHANGE:
case PV_STATUS:
err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));
@@ -2345,7 +2375,7 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
if (err) return err;
u.pv_status.pv = &p;
if (cmd == PV_CHANGE) {
- err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8);
+ err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err) return -EFAULT;
p.pe = NULL; p.inode = NULL;
}
@@ -2361,6 +2391,9 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc))
err = -EFAULT;
}
+ if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) {
+ err = -EFAULT;
+ }
kfree(v);
break;
case VG_CREATE:
@@ -2383,12 +2416,21 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
if (!err) err = copy_lv_t(ptr, u.lv_byindex.lv);
put_lv_t(u.lv_byindex.lv);
}
+ break;
case PV_STATUS:
if (!err) {
- err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8);
- if (err) return -EFAULT;
+ err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
+ if (err) return -EFAULT;
+ err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
+ if (err) return -EFAULT;
}
break;
+ case LV_STATUS_BYDEV:
+ if (!err) {
+ if (!err) err = copy_lv_t(ptr, u.lv_bydev.lv);
+ put_lv_t(u.lv_byindex.lv);
+ }
+ break;
}
return err;
}
@@ -3222,8 +3264,22 @@ COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int))
COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int))
COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int))
/* Little p (/dev/rtc, /dev/envctrl, etc.) */
-COMPATIBLE_IOCTL(RTCGET)
-COMPATIBLE_IOCTL(RTCSET)
+COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
+COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
+COMPATIBLE_IOCTL(RTC_AIE_ON)
+COMPATIBLE_IOCTL(RTC_AIE_OFF)
+COMPATIBLE_IOCTL(RTC_UIE_ON)
+COMPATIBLE_IOCTL(RTC_UIE_OFF)
+COMPATIBLE_IOCTL(RTC_PIE_ON)
+COMPATIBLE_IOCTL(RTC_PIE_OFF)
+COMPATIBLE_IOCTL(RTC_WIE_ON)
+COMPATIBLE_IOCTL(RTC_WIE_OFF)
+COMPATIBLE_IOCTL(RTC_ALM_SET)
+COMPATIBLE_IOCTL(RTC_ALM_READ)
+COMPATIBLE_IOCTL(RTC_RD_TIME)
+COMPATIBLE_IOCTL(RTC_SET_TIME)
+COMPATIBLE_IOCTL(RTC_WKALM_SET)
+COMPATIBLE_IOCTL(RTC_WKALM_RD)
COMPATIBLE_IOCTL(ENVCTRL_RD_WARNING_TEMPERATURE)
COMPATIBLE_IOCTL(ENVCTRL_RD_SHUTDOWN_TEMPERATURE)
COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_TEMPERATURE)
@@ -3331,6 +3387,7 @@ COMPATIBLE_IOCTL(PPPIOCSMRRU)
COMPATIBLE_IOCTL(PPPIOCCONNECT)
COMPATIBLE_IOCTL(PPPIOCDISCONN)
COMPATIBLE_IOCTL(PPPIOCATTCHAN)
+COMPATIBLE_IOCTL(PPPIOCGCHAN)
/* PPPOX */
COMPATIBLE_IOCTL(PPPOEIOCSFWD);
COMPATIBLE_IOCTL(PPPOEIOCDFWD);
@@ -3565,6 +3622,7 @@ COMPATIBLE_IOCTL(VG_SET_EXTENDABLE)
COMPATIBLE_IOCTL(VG_STATUS_GET_COUNT)
COMPATIBLE_IOCTL(VG_STATUS_GET_NAMELIST)
COMPATIBLE_IOCTL(VG_REMOVE)
+COMPATIBLE_IOCTL(VG_RENAME)
COMPATIBLE_IOCTL(VG_REDUCE)
COMPATIBLE_IOCTL(PE_LOCK_UNLOCK)
COMPATIBLE_IOCTL(PV_FLUSH)
@@ -3576,6 +3634,9 @@ COMPATIBLE_IOCTL(LVM_RESET)
COMPATIBLE_IOCTL(LV_SET_ACCESS)
COMPATIBLE_IOCTL(LV_SET_STATUS)
COMPATIBLE_IOCTL(LV_SET_ALLOCATION)
+COMPATIBLE_IOCTL(LE_REMAP)
+COMPATIBLE_IOCTL(LV_BMAP)
+COMPATIBLE_IOCTL(LV_SNAPSHOT_USE_RATE)
#endif /* LVM */
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)
@@ -3749,9 +3810,9 @@ HANDLE_IOCTL(LV_CREATE, do_lvm_ioctl)
HANDLE_IOCTL(LV_REMOVE, do_lvm_ioctl)
HANDLE_IOCTL(LV_EXTEND, do_lvm_ioctl)
HANDLE_IOCTL(LV_REDUCE, do_lvm_ioctl)
+HANDLE_IOCTL(LV_RENAME, do_lvm_ioctl)
HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl)
HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl)
-HANDLE_IOCTL(LE_REMAP, do_lvm_ioctl)
HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl)
HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
#endif /* LVM */
@@ -3766,6 +3827,12 @@ HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
#endif /* DRM */
+#if 0
+HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl)
+HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl)
+HANDLE_IOCTL(RTC32_EPOCH_READ, do_rtc_ioctl)
+HANDLE_IOCTL(RTC32_EPOCH_SET, do_rtc_ioctl)
+#endif
IOCTL_TABLE_END
unsigned int ioctl32_hash_table[1024];
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 1bd29505b..dbb55aaed 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.95 2001/02/13 01:16:44 davem Exp $
+/* $Id: irq.c,v 1.99 2001/03/22 02:19:23 davem Exp $
* irq.c: UltraSparc IRQ handling/init/registry.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -132,14 +132,23 @@ void enable_irq(unsigned int irq)
if (imap == 0UL)
return;
- if(this_is_starfire == 0) {
+ if (tlb_type == cheetah) {
+ /* We set it to our Safari AID. */
+ __asm__ __volatile__("ldxa [%%g0] %1, %0"
+ : "=r" (tid)
+ : "i" (ASI_SAFARI_CONFIG));
+ tid = ((tid & (0x3ffUL<<17)) << 9);
+ tid &= IMAP_AID_SAFARI;
+ } else if (this_is_starfire == 0) {
/* We set it to our UPA MID. */
__asm__ __volatile__("ldxa [%%g0] %1, %0"
: "=r" (tid)
: "i" (ASI_UPA_CONFIG));
tid = ((tid & UPA_CONFIG_MID) << 9);
+ tid &= IMAP_TID_UPA;
} else {
tid = (starfire_translate(imap, current->processor) << 26);
+ tid &= IMAP_TID_UPA;
}
/* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product
@@ -150,7 +159,7 @@ void enable_irq(unsigned int irq)
*
* Things like FFB can now be handled via the new IRQ mechanism.
*/
- upa_writel(IMAP_VALID | (tid & IMAP_TID), imap);
+ upa_writel(tid | IMAP_VALID, imap);
}
/* This now gets passed true ino's as well. */
@@ -729,6 +738,10 @@ void handler_irq(int irq, struct pt_regs *regs)
/* Voo-doo programming. */
if (cpu_data[buddy].idle_volume < FORWARD_VOLUME)
should_forward = 0;
+
+ /* This just so happens to be correct on Cheetah
+ * at the moment.
+ */
buddy <<= 26;
}
#endif
@@ -737,10 +750,23 @@ void handler_irq(int irq, struct pt_regs *regs)
/*
* Check for TICK_INT on level 14 softint.
*/
- if ((irq == 14) && (get_softint() & (1UL << 0)))
- irq = 0;
-#endif
+ {
+ unsigned long clr_mask = 1 << irq;
+ unsigned long tick_mask;
+
+ if (SPARC64_USE_STICK)
+ tick_mask = (1UL << 16);
+ else
+ tick_mask = (1UL << 0);
+ if ((irq == 14) && (get_softint() & tick_mask)) {
+ irq = 0;
+ clr_mask = tick_mask;
+ }
+ clear_softint(clr_mask);
+ }
+#else
clear_softint(1 << irq);
+#endif
irq_enter(cpu, irq);
kstat.irqs[cpu][irq]++;
@@ -952,8 +978,13 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *),
extern void smp_tick_init(void);
#endif
- node = linux_cpus[0].prom_node;
- *clock = prom_getint(node, "clock-frequency");
+ if (!SPARC64_USE_STICK) {
+ node = linux_cpus[0].prom_node;
+ *clock = prom_getint(node, "clock-frequency");
+ } else {
+ node = prom_root_node;
+ *clock = prom_getint(node, "stick-frequency");
+ }
timer_tick_offset = *clock / HZ;
#ifdef CONFIG_SMP
smp_tick_init();
@@ -1003,6 +1034,7 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *),
* at the start of an I-cache line, and perform a dummy
* read back from %tick_cmpr right after writing to it. -DaveM
*/
+ if (!SPARC64_USE_STICK) {
__asm__ __volatile__("
rd %%tick, %%g1
ba,pt %%xcc, 1f
@@ -1013,6 +1045,26 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *),
: /* no outputs */
: "r" (timer_tick_offset)
: "g1");
+ } else {
+ /* Let the user get at STICK too. */
+ __asm__ __volatile__("
+ sethi %%hi(0x80000000), %%g1
+ sllx %%g1, 32, %%g1
+ rd %%asr24, %%g2
+ andn %%g2, %%g1, %%g2
+ wr %%g2, 0, %%asr24"
+ : /* no outputs */
+ : /* no inputs */
+ : "g1", "g2");
+
+ __asm__ __volatile__("
+ rd %%asr24, %%g1
+ add %%g1, %0, %%g1
+ wr %%g1, 0x0, %%asr25"
+ : /* no outputs */
+ : "r" (timer_tick_offset)
+ : "g1");
+ }
/* Restore PSTATE_IE. */
__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
@@ -1033,12 +1085,17 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu)
if (bucket->pil == 12)
return goal_cpu;
- if(this_is_starfire == 0) {
+ if (tlb_type == cheetah) {
+ tid = __cpu_logical_map[goal_cpu] << 26;
+ tid &= IMAP_AID_SAFARI;
+ } else if (this_is_starfire == 0) {
tid = __cpu_logical_map[goal_cpu] << 26;
+ tid &= IMAP_TID_UPA;
} else {
tid = (starfire_translate(imap, __cpu_logical_map[goal_cpu]) << 26);
+ tid &= IMAP_TID_UPA;
}
- upa_writel(IMAP_VALID | (tid & IMAP_TID), imap);
+ upa_writel(tid | IMAP_VALID, imap);
goal_cpu++;
if(goal_cpu >= NR_CPUS ||
@@ -1120,7 +1177,7 @@ static void kill_prom_timer(void)
stxa %%g0, [%%g0] %0
membar #Sync
" : /* no outputs */
- : "i" (ASI_INTR_RECEIVE), "i" (ASI_UDB_INTR_R)
+ : "i" (ASI_INTR_RECEIVE), "i" (ASI_INTR_R)
: "g1", "g2");
}
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 009900165..fbdb39748 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.21 2001/01/10 18:22:59 davem Exp $
+/* $Id: pci.c,v 1.23 2001/03/14 04:17:14 davem Exp $
* pci.c: UltraSparc PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com)
@@ -78,9 +78,7 @@ volatile int pci_poke_faulted;
/* Probe for all PCI controllers in the system. */
extern void sabre_init(int);
extern void psycho_init(int);
-#if 0
extern void schizo_init(int);
-#endif
static struct {
char *model_name;
@@ -88,12 +86,11 @@ static struct {
} pci_controller_table[] = {
{ "SUNW,sabre", sabre_init },
{ "pci108e,a000", sabre_init },
+ { "pci108e,a001", sabre_init },
{ "SUNW,psycho", psycho_init },
- { "pci108e,8000", psycho_init }
-#if 0
+ { "pci108e,8000", psycho_init },
{ "SUNW,schizo", schizo_init },
{ "pci108e,8001", schizo_init }
-#endif
};
#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \
sizeof(pci_controller_table[0]))
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
index ff7060c0a..bcf950ee0 100644
--- a/arch/sparc64/kernel/pci_common.c
+++ b/arch/sparc64/kernel/pci_common.c
@@ -1,4 +1,4 @@
-/* $Id: pci_common.c,v 1.13 2001/02/13 01:16:44 davem Exp $
+/* $Id: pci_common.c,v 1.14 2001/02/28 03:28:55 davem Exp $
* pci_common.c: PCI controller common support.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -560,19 +560,19 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
/* Fully specified already? */
if (((prom_irq & PCI_IRQ_IGN) >> 6) == portid) {
- pdev->irq = p->irq_build(p, pdev, prom_irq);
+ pdev->irq = p->irq_build(pbm, pdev, prom_irq);
goto have_irq;
}
/* An onboard device? (bit 5 set) */
if ((prom_irq & PCI_IRQ_INO) & 0x20) {
- pdev->irq = p->irq_build(p, pdev, (portid << 6 | prom_irq));
+ pdev->irq = p->irq_build(pbm, pdev, (portid << 6 | prom_irq));
goto have_irq;
}
/* Can we find a matching entry in the interrupt-map? */
if (pci_intmap_match(pdev, &prom_irq)) {
- pdev->irq = p->irq_build(p, pdev, (portid << 6) | prom_irq);
+ pdev->irq = p->irq_build(pbm, pdev, (portid << 6) | prom_irq);
goto have_irq;
}
@@ -609,7 +609,7 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
}
slot = slot << 2;
- pdev->irq = p->irq_build(p, pdev,
+ pdev->irq = p->irq_build(pbm, pdev,
((portid << 6) & PCI_IRQ_IGN) |
(bus | slot | line));
}
@@ -632,17 +632,11 @@ void __init pci_fixup_irq(struct pci_pbm_info *pbm,
pci_fixup_irq(pbm, pci_bus_b(walk));
}
-#undef DEBUG_BUSMASTERING
-
static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz)
{
u16 cmd;
u8 hdr_type, min_gnt, ltimer;
-#ifdef DEBUG_BUSMASTERING
- printk("PCI: Checking DEV(%s), ", pdev->name);
-#endif
-
pci_read_config_word(pdev, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_MASTER;
pci_write_config_word(pdev, PCI_COMMAND, cmd);
@@ -652,43 +646,28 @@ static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz)
* mastering so we have nothing to do here.
*/
pci_read_config_word(pdev, PCI_COMMAND, &cmd);
- if ((cmd & PCI_COMMAND_MASTER) == 0) {
-#ifdef DEBUG_BUSMASTERING
- printk("no bus mastering...\n");
-#endif
+ if ((cmd & PCI_COMMAND_MASTER) == 0)
return;
- }
/* Set correct cache line size, 64-byte on all
* Sparc64 PCI systems. Note that the value is
* measured in 32-bit words.
*/
-#ifdef DEBUG_BUSMASTERING
- printk("set cachelinesize, ");
-#endif
pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
64 / sizeof(u32));
pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr_type);
hdr_type &= ~0x80;
- if (hdr_type != PCI_HEADER_TYPE_NORMAL) {
-#ifdef DEBUG_BUSMASTERING
- printk("hdr_type=%x, exit\n", hdr_type);
-#endif
+ if (hdr_type != PCI_HEADER_TYPE_NORMAL)
return;
- }
/* If the latency timer is already programmed with a non-zero
* value, assume whoever set it (OBP or whoever) knows what
* they are doing.
*/
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &ltimer);
- if (ltimer != 0) {
-#ifdef DEBUG_BUSMASTERING
- printk("ltimer was %x, exit\n", ltimer);
-#endif
+ if (ltimer != 0)
return;
- }
/* XXX Since I'm tipping off the min grant value to
* XXX choose a suitable latency timer value, I also
@@ -738,9 +717,6 @@ static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz)
}
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, ltimer);
-#ifdef DEBUG_BUSMASTERING
- printk("set ltimer to %x\n", ltimer);
-#endif
}
void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm,
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 08d5b8ee3..5e21a9649 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -1,4 +1,4 @@
-/* $Id: pci_iommu.c,v 1.12 2001/01/11 16:26:45 davem Exp $
+/* $Id: pci_iommu.c,v 1.13 2001/03/14 08:42:38 davem Exp $
* pci_iommu.c: UltraSparc PCI controller IOM/STC support.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -213,9 +213,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad
first_page += PAGE_SIZE;
}
- if (iommu->iommu_ctxflush) {
- pci_iommu_write(iommu->iommu_ctxflush, ctx);
- } else {
+ {
int i;
u32 daddr = *dma_addrp;
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 7a671158e..ac7f5ab81 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.19 2001/02/13 01:16:44 davem Exp $
+/* $Id: pci_psycho.c,v 1.21 2001/02/28 03:28:55 davem Exp $
* pci_psycho.c: PSYCHO/U2P specific PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -72,7 +72,7 @@
* ---------------------------------------------------------
*/
#define PSYCHO_CONFIG_BASE(PBM) \
- ((PBM)->parent->config_space | (1UL << 24))
+ ((PBM)->config_space | (1UL << 24))
#define PSYCHO_CONFIG_ENCODE(BUS, DEVFN, REG) \
(((unsigned long)(BUS) << 16) | \
((unsigned long)(DEVFN) << 8) | \
@@ -376,10 +376,11 @@ static int __init psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
return ret;
}
-static unsigned int __init psycho_irq_build(struct pci_controller_info *p,
+static unsigned int __init psycho_irq_build(struct pci_pbm_info *pbm,
struct pci_dev *pdev,
unsigned int ino)
{
+ struct pci_controller_info *p = pbm->parent;
struct ino_bucket *bucket;
unsigned long imap, iclr;
unsigned long imap_off, iclr_off;
@@ -1002,12 +1003,13 @@ static void psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
#define PSYCHO_PCIERR_B_INO 0x31
static void __init psycho_register_error_handlers(struct pci_controller_info *p)
{
+ struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
unsigned long base = p->controller_regs;
unsigned int irq, portid = p->portid;
u64 tmp;
/* Build IRQs and register handlers. */
- irq = psycho_irq_build(p, NULL, (portid << 6) | PSYCHO_UE_INO);
+ irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_UE_INO);
if (request_irq(irq, psycho_ue_intr,
SA_SHIRQ, "PSYCHO UE", p) < 0) {
prom_printf("PSYCHO%d: Cannot register UE interrupt.\n",
@@ -1015,7 +1017,7 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p)
prom_halt();
}
- irq = psycho_irq_build(p, NULL, (portid << 6) | PSYCHO_CE_INO);
+ irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_CE_INO);
if (request_irq(irq, psycho_ce_intr,
SA_SHIRQ, "PSYCHO CE", p) < 0) {
prom_printf("PSYCHO%d: Cannot register CE interrupt.\n",
@@ -1023,7 +1025,7 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p)
prom_halt();
}
- irq = psycho_irq_build(p, NULL, (portid << 6) | PSYCHO_PCIERR_A_INO);
+ irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_A_INO);
if (request_irq(irq, psycho_pcierr_intr,
SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_A) < 0) {
prom_printf("PSYCHO%d(PBMA): Cannot register PciERR interrupt.\n",
@@ -1031,7 +1033,7 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p)
prom_halt();
}
- irq = psycho_irq_build(p, NULL, (portid << 6) | PSYCHO_PCIERR_B_INO);
+ irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_B_INO);
if (request_irq(irq, psycho_pcierr_intr,
SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_B) < 0) {
prom_printf("PSYCHO%d(PBMB): Cannot register PciERR interrupt.\n",
@@ -1574,8 +1576,10 @@ void __init psycho_init(int node)
printk("PCI: Found PSYCHO, control regs at %016lx\n",
p->controller_regs);
- p->config_space = pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE;
- printk("PSYCHO: PCI config space at %016lx\n", p->config_space);
+ p->pbm_A.config_space = p->pbm_B.config_space =
+ (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE);
+ printk("PSYCHO: Shared PCI config space at %016lx\n",
+ p->pbm_A.config_space);
/*
* Psycho's PCI MEM space is mapped to a 2GB aligned area, so
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index cce2e5467..07632eaec 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.23 2001/02/13 01:16:44 davem Exp $
+/* $Id: pci_sabre.c,v 1.25 2001/02/28 03:28:55 davem Exp $
* pci_sabre.c: Sabre specific PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -209,7 +209,7 @@
* ---------------------------------------------------------
*/
#define SABRE_CONFIG_BASE(PBM) \
- ((PBM)->parent->config_space | (1UL << 24))
+ ((PBM)->config_space | (1UL << 24))
#define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG) \
(((unsigned long)(BUS) << 16) | \
((unsigned long)(DEVFN) << 8) | \
@@ -604,10 +604,11 @@ static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
return ret;
}
-static unsigned int __init sabre_irq_build(struct pci_controller_info *p,
+static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm,
struct pci_dev *pdev,
unsigned int ino)
{
+ struct pci_controller_info *p = pbm->parent;
struct ino_bucket *bucket;
unsigned long imap, iclr;
unsigned long imap_off, iclr_off;
@@ -961,6 +962,7 @@ static void sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
#define SABRE_PCIERR_INO 0x30
static void __init sabre_register_error_handlers(struct pci_controller_info *p)
{
+ struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
unsigned long base = p->controller_regs;
unsigned long irq, portid = p->portid;
u64 tmp;
@@ -973,7 +975,7 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p)
(SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR |
SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR |
SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE));
- irq = sabre_irq_build(p, NULL, (portid << 6) | SABRE_UE_INO);
+ irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_UE_INO);
if (request_irq(irq, sabre_ue_intr,
SA_SHIRQ, "SABRE UE", p) < 0) {
prom_printf("SABRE%d: Cannot register UE interrupt.\n",
@@ -984,7 +986,7 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p)
sabre_write(base + SABRE_CE_AFSR,
(SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR |
SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR));
- irq = sabre_irq_build(p, NULL, (portid << 6) | SABRE_CE_INO);
+ irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_CE_INO);
if (request_irq(irq, sabre_ce_intr,
SA_SHIRQ, "SABRE CE", p) < 0) {
prom_printf("SABRE%d: Cannot register CE interrupt.\n",
@@ -992,7 +994,7 @@ static void __init sabre_register_error_handlers(struct pci_controller_info *p)
prom_halt();
}
- irq = sabre_irq_build(p, NULL, (portid << 6) | SABRE_PCIERR_INO);
+ irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_PCIERR_INO);
if (request_irq(irq, sabre_pcierr_intr,
SA_SHIRQ, "SABRE PCIERR", p) < 0) {
prom_printf("SABRE%d: Cannot register PciERR interrupt.\n",
@@ -1434,8 +1436,10 @@ void __init sabre_init(int pnode)
SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN));
/* Now map in PCI config space for entire SABRE. */
- p->config_space = p->controller_regs + SABRE_CONFIGSPACE;
- printk("SABRE: PCI config space at %016lx\n", p->config_space);
+ p->pbm_A.config_space = p->pbm_B.config_space =
+ (p->controller_regs + SABRE_CONFIGSPACE);
+ printk("SABRE: Shared PCI config space at %016lx\n",
+ p->pbm_A.config_space);
err = prom_getproperty(pnode, "virtual-dma",
(char *)&vdma[0], sizeof(vdma));
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index daac0d783..ebeeb0bfa 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -1,4 +1,4 @@
-/* $Id: pci_schizo.c,v 1.3 2001/02/13 01:16:44 davem Exp $
+/* $Id: pci_schizo.c,v 1.13 2001/03/21 00:29:58 davem Exp $
* pci_schizo.c: SCHIZO specific PCI controller support.
*
* Copyright (C) 2001 David S. Miller (davem@redhat.com)
@@ -13,37 +13,244 @@
#include <asm/pbm.h>
#include <asm/iommu.h>
#include <asm/irq.h>
+#include <asm/upa.h>
#include "pci_impl.h"
+/* All SCHIZO registers are 64-bits. The following accessor
+ * routines are how they are accessed. The REG parameter
+ * is a physical address.
+ */
+#define schizo_read(__reg) \
+({ u64 __ret; \
+ __asm__ __volatile__("ldxa [%1] %2, %0" \
+ : "=r" (__ret) \
+ : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
+ : "memory"); \
+ __ret; \
+})
+#define schizo_write(__reg, __val) \
+ __asm__ __volatile__("stxa %0, [%1] %2" \
+ : /* no outputs */ \
+ : "r" (__val), "r" (__reg), \
+ "i" (ASI_PHYS_BYPASS_EC_E))
+
+/* This is a convention that at least Excalibur and Merlin
+ * follow. I suppose the SCHIZO used in Starcat and friends
+ * will do similar.
+ *
+ * The only way I could see this changing is if the newlink
+ * block requires more space in Schizo's address space than
+ * they predicted, thus requiring an address space reorg when
+ * the newer Schizo is taped out.
+ *
+ * These offsets look weird because I keep in p->controller_regs
+ * the second PROM register property minus 0x10000 which is the
+ * base of the Safari and UPA64S registers of SCHIZO.
+ */
+#define SCHIZO_PBM_A_REGS_OFF (0x600000UL - 0x400000UL)
+#define SCHIZO_PBM_B_REGS_OFF (0x700000UL - 0x400000UL)
+
+/* Streaming buffer control register. */
+#define SCHIZO_STRBUF_CTRL_LPTR 0x00000000000000f0UL /* LRU Lock Pointer */
+#define SCHIZO_STRBUF_CTRL_LENAB 0x0000000000000008UL /* LRU Lock Enable */
+#define SCHIZO_STRBUF_CTRL_RRDIS 0x0000000000000004UL /* Rerun Disable */
+#define SCHIZO_STRBUF_CTRL_DENAB 0x0000000000000002UL /* Diagnostic Mode Enable */
+#define SCHIZO_STRBUF_CTRL_ENAB 0x0000000000000001UL /* Streaming Buffer Enable */
+
+/* IOMMU control register. */
+#define SCHIZO_IOMMU_CTRL_RESV 0xfffffffff9000000 /* Reserved */
+#define SCHIZO_IOMMU_CTRL_XLTESTAT 0x0000000006000000 /* Translation Error Status */
+#define SCHIZO_IOMMU_CTRL_XLTEERR 0x0000000001000000 /* Translation Error encountered */
+#define SCHIZO_IOMMU_CTRL_LCKEN 0x0000000000800000 /* Enable translation locking */
+#define SCHIZO_IOMMU_CTRL_LCKPTR 0x0000000000780000 /* Translation lock pointer */
+#define SCHIZO_IOMMU_CTRL_TSBSZ 0x0000000000070000 /* TSB Size */
+#define SCHIZO_IOMMU_TSBSZ_1K 0x0000000000000000 /* TSB Table 1024 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_2K 0x0000000000010000 /* TSB Table 2048 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_4K 0x0000000000020000 /* TSB Table 4096 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_8K 0x0000000000030000 /* TSB Table 8192 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_16K 0x0000000000040000 /* TSB Table 16k 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_32K 0x0000000000050000 /* TSB Table 32k 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_64K 0x0000000000060000 /* TSB Table 64k 8-byte entries */
+#define SCHIZO_IOMMU_TSBSZ_128K 0x0000000000070000 /* TSB Table 128k 8-byte entries */
+#define SCHIZO_IOMMU_CTRL_RESV2 0x000000000000fff8 /* Reserved */
+#define SCHIZO_IOMMU_CTRL_TBWSZ 0x0000000000000004 /* Assumed page size, 0=8k 1=64k */
+#define SCHIZO_IOMMU_CTRL_DENAB 0x0000000000000002 /* Diagnostic mode enable */
+#define SCHIZO_IOMMU_CTRL_ENAB 0x0000000000000001 /* IOMMU Enable */
+
+/* Schizo config space address format is nearly identical to
+ * that of PSYCHO:
+ *
+ * 32 24 23 16 15 11 10 8 7 2 1 0
+ * ---------------------------------------------------------
+ * |0 0 0 0 0 0 0 0 0| bus | device | function | reg | 0 0 |
+ * ---------------------------------------------------------
+ */
+#define SCHIZO_CONFIG_BASE(PBM) ((PBM)->config_space)
+#define SCHIZO_CONFIG_ENCODE(BUS, DEVFN, REG) \
+ (((unsigned long)(BUS) << 16) | \
+ ((unsigned long)(DEVFN) << 8) | \
+ ((unsigned long)(REG)))
+
+static void *schizo_pci_config_mkaddr(struct pci_pbm_info *pbm,
+ unsigned char bus,
+ unsigned int devfn,
+ int where)
+{
+ if (!pbm)
+ return NULL;
+ return (void *)
+ (SCHIZO_CONFIG_BASE(pbm) |
+ SCHIZO_CONFIG_ENCODE(bus, devfn, where));
+}
+
+/* 4 slots on pbm A, and 6 slots on pbm B. In both cases
+ * slot 0 is the SCHIZO host bridge itself.
+ */
+static int schizo_out_of_range(struct pci_pbm_info *pbm,
+ unsigned char bus,
+ unsigned char devfn)
+{
+ return ((pbm->parent == 0) ||
+ ((pbm == &pbm->parent->pbm_B) &&
+ (bus == pbm->pci_first_busno) &&
+ PCI_SLOT(devfn) > 6) ||
+ ((pbm == &pbm->parent->pbm_A) &&
+ (bus == pbm->pci_first_busno) &&
+ PCI_SLOT(devfn) > 4));
+}
+
+/* SCHIZO PCI configuration space accessors. */
+
static int schizo_read_byte(struct pci_dev *dev, int where, u8 *value)
{
- /* IMPLEMENT ME */
+ struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
+ unsigned char bus = dev->bus->number;
+ unsigned int devfn = dev->devfn;
+ u8 *addr;
+
+ *value = 0xff;
+ addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
+ if (!addr)
+ return PCIBIOS_SUCCESSFUL;
+
+ if (schizo_out_of_range(pbm, bus, devfn))
+ return PCIBIOS_SUCCESSFUL;
+ pci_config_read8(addr, value);
+ return PCIBIOS_SUCCESSFUL;
}
static int schizo_read_word(struct pci_dev *dev, int where, u16 *value)
{
- /* IMPLEMENT ME */
+ struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
+ unsigned char bus = dev->bus->number;
+ unsigned int devfn = dev->devfn;
+ u16 *addr;
+
+ *value = 0xffff;
+ addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
+ if (!addr)
+ return PCIBIOS_SUCCESSFUL;
+
+ if (schizo_out_of_range(pbm, bus, devfn))
+ return PCIBIOS_SUCCESSFUL;
+
+ if (where & 0x01) {
+ printk("pcibios_read_config_word: misaligned reg [%x]\n",
+ where);
+ return PCIBIOS_SUCCESSFUL;
+ }
+ pci_config_read16(addr, value);
+ return PCIBIOS_SUCCESSFUL;
}
static int schizo_read_dword(struct pci_dev *dev, int where, u32 *value)
{
- /* IMPLEMENT ME */
+ struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
+ unsigned char bus = dev->bus->number;
+ unsigned int devfn = dev->devfn;
+ u32 *addr;
+
+ *value = 0xffffffff;
+ addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
+ if (!addr)
+ return PCIBIOS_SUCCESSFUL;
+
+ if (schizo_out_of_range(pbm, bus, devfn))
+ return PCIBIOS_SUCCESSFUL;
+
+ if (where & 0x03) {
+ printk("pcibios_read_config_dword: misaligned reg [%x]\n",
+ where);
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ pci_config_read32(addr, value);
+ return PCIBIOS_SUCCESSFUL;
}
static int schizo_write_byte(struct pci_dev *dev, int where, u8 value)
{
- /* IMPLEMENT ME */
+ struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
+ unsigned char bus = dev->bus->number;
+ unsigned int devfn = dev->devfn;
+ u8 *addr;
+
+ addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
+ if (!addr)
+ return PCIBIOS_SUCCESSFUL;
+
+ if (schizo_out_of_range(pbm, bus, devfn))
+ return PCIBIOS_SUCCESSFUL;
+
+ pci_config_write8(addr, value);
+ return PCIBIOS_SUCCESSFUL;
}
static int schizo_write_word(struct pci_dev *dev, int where, u16 value)
{
- /* IMPLEMENT ME */
+ struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
+ unsigned char bus = dev->bus->number;
+ unsigned int devfn = dev->devfn;
+ u16 *addr;
+
+ addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
+ if (!addr)
+ return PCIBIOS_SUCCESSFUL;
+
+ if (schizo_out_of_range(pbm, bus, devfn))
+ return PCIBIOS_SUCCESSFUL;
+
+ if (where & 0x01) {
+ printk("pcibios_write_config_word: misaligned reg [%x]\n",
+ where);
+ return PCIBIOS_SUCCESSFUL;
+ }
+ pci_config_write16(addr, value);
+ return PCIBIOS_SUCCESSFUL;
}
static int schizo_write_dword(struct pci_dev *dev, int where, u32 value)
{
- /* IMPLEMENT ME */
+ struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
+ unsigned char bus = dev->bus->number;
+ unsigned int devfn = dev->devfn;
+ u32 *addr;
+
+ addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
+ if (!addr)
+ return PCIBIOS_SUCCESSFUL;
+
+ if (schizo_out_of_range(pbm, bus, devfn))
+ return PCIBIOS_SUCCESSFUL;
+
+ if (where & 0x03) {
+ printk("pcibios_write_config_dword: misaligned reg [%x]\n",
+ where);
+ return PCIBIOS_SUCCESSFUL;
+ }
+ pci_config_write32(addr, value);
+ return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops schizo_ops = {
@@ -55,34 +262,1445 @@ static struct pci_ops schizo_ops = {
schizo_write_dword
};
-static void __init schizo_scan_bus(struct pci_controller_info *p)
+/* SCHIZO interrupt mapping support. Unlike Psycho, for this controller the
+ * imap/iclr registers are per-PBM.
+ */
+#define SCHIZO_IMAP_BASE 0x1000UL
+#define SCHIZO_ICLR_BASE 0x1400UL
+
+static unsigned long schizo_imap_offset(unsigned long ino)
{
- /* IMPLEMENT ME */
+ return SCHIZO_IMAP_BASE + (ino * 8UL);
}
-static unsigned int __init schizo_irq_build(struct pci_controller_info *p,
+static unsigned long schizo_iclr_offset(unsigned long ino)
+{
+ return SCHIZO_ICLR_BASE + (ino * 8UL);
+}
+
+/* PCI SCHIZO INO number to Sparc PIL level. This table only matters for
+ * INOs which will not have an associated PCI device struct, ie. onboard
+ * EBUS devices and PCI controller internal error interrupts.
+ */
+static unsigned char schizo_pil_table[] = {
+/*0x00*/0, 0, 0, 0, /* PCI slot 0 Int A, B, C, D */
+/*0x04*/0, 0, 0, 0, /* PCI slot 1 Int A, B, C, D */
+/*0x08*/0, 0, 0, 0, /* PCI slot 2 Int A, B, C, D */
+/*0x0c*/0, 0, 0, 0, /* PCI slot 3 Int A, B, C, D */
+/*0x10*/0, 0, 0, 0, /* PCI slot 4 Int A, B, C, D */
+/*0x14*/0, 0, 0, 0, /* PCI slot 5 Int A, B, C, D */
+/*0x18*/3, /* SCSI */
+/*0x19*/3, /* second SCSI */
+/*0x1a*/0, /* UNKNOWN */
+/*0x1b*/0, /* UNKNOWN */
+/*0x1c*/8, /* Parallel */
+/*0x1d*/5, /* Ethernet */
+/*0x1e*/8, /* Firewire-1394 */
+/*0x1f*/9, /* USB */
+/*0x20*/13, /* Audio Record */
+/*0x21*/14, /* Audio Playback */
+/*0x22*/12, /* Serial */
+/*0x23*/2, /* EBUS I2C */
+/*0x24*/10, /* RTC Clock */
+/*0x25*/11, /* Floppy */
+/*0x26*/0, /* UNKNOWN */
+/*0x27*/0, /* UNKNOWN */
+/*0x28*/0, /* UNKNOWN */
+/*0x29*/0, /* UNKNOWN */
+/*0x2a*/10, /* UPA 1 */
+/*0x2b*/10, /* UPA 2 */
+/*0x2c*/0, /* UNKNOWN */
+/*0x2d*/0, /* UNKNOWN */
+/*0x2e*/0, /* UNKNOWN */
+/*0x2f*/0, /* UNKNOWN */
+/*0x30*/15, /* Uncorrectable ECC */
+/*0x31*/15, /* Correctable ECC */
+/*0x32*/15, /* PCI Bus A Error */
+/*0x33*/15, /* PCI Bus B Error */
+/*0x34*/15, /* Safari Bus Error */
+/*0x35*/0, /* Reserved */
+/*0x36*/0, /* Reserved */
+/*0x37*/0, /* Reserved */
+/*0x38*/0, /* Reserved for NewLink */
+/*0x39*/0, /* Reserved for NewLink */
+/*0x3a*/0, /* Reserved for NewLink */
+/*0x3b*/0, /* Reserved for NewLink */
+/*0x3c*/0, /* Reserved for NewLink */
+/*0x3d*/0, /* Reserved for NewLink */
+/*0x3e*/0, /* Reserved for NewLink */
+/*0x3f*/0, /* Reserved for NewLink */
+};
+
+static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
+{
+ int ret;
+
+ ret = schizo_pil_table[ino];
+ if (ret == 0 && pdev == NULL) {
+ ret = 1;
+ } else if (ret == 0) {
+ switch ((pdev->class >> 16) & 0x0f) {
+ case PCI_BASE_CLASS_STORAGE:
+ ret = 4;
+
+ case PCI_BASE_CLASS_NETWORK:
+ ret = 6;
+
+ case PCI_BASE_CLASS_DISPLAY:
+ ret = 9;
+
+ case PCI_BASE_CLASS_MULTIMEDIA:
+ case PCI_BASE_CLASS_MEMORY:
+ case PCI_BASE_CLASS_BRIDGE:
+ ret = 10;
+
+ default:
+ ret = 1;
+ };
+ }
+
+ return ret;
+}
+
+static unsigned int __init schizo_irq_build(struct pci_pbm_info *pbm,
struct pci_dev *pdev,
unsigned int ino)
{
- /* IMPLEMENT ME */
+ struct pci_controller_info *p = pbm->parent;
+ struct ino_bucket *bucket;
+ unsigned long imap, iclr, pbm_off;
+ unsigned long imap_off, iclr_off;
+ int pil, inofixup = 0;
+
+ if (pbm == &p->pbm_A)
+ pbm_off = SCHIZO_PBM_A_REGS_OFF;
+ else
+ pbm_off = SCHIZO_PBM_B_REGS_OFF;
+
+ ino &= PCI_IRQ_INO;
+ imap_off = schizo_imap_offset(ino);
+
+ /* Now build the IRQ bucket. */
+ pil = schizo_ino_to_pil(pdev, ino);
+ imap = p->controller_regs + pbm_off + imap_off;
+ imap += 4;
+
+ iclr_off = schizo_iclr_offset(ino);
+ iclr = p->controller_regs + pbm_off + iclr_off;
+ iclr += 4;
+
+ if (ino < 0x18)
+ inofixup = ino & 0x03;
+
+ bucket = __bucket(build_irq(pil, inofixup, iclr, imap));
+ bucket->flags |= IBF_PCI;
+
+ return __irq(bucket);
+}
+
+/* SCHIZO error handling support. */
+enum schizo_error_type {
+ UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR
+};
+
+static spinlock_t stc_buf_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long stc_error_buf[128];
+static unsigned long stc_tag_buf[16];
+static unsigned long stc_line_buf[16];
+
+static void schizo_clear_other_err_intr(int irq)
+{
+ struct ino_bucket *bucket = __bucket(irq);
+ unsigned long iclr = bucket->iclr;
+
+ iclr += (SCHIZO_PBM_B_REGS_OFF - SCHIZO_PBM_A_REGS_OFF);
+ upa_writel(ICLR_IDLE, iclr);
+}
+
+#define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */
+#define SCHIZO_STC_TAG 0xba00UL /* --> 0xba80 */
+#define SCHIZO_STC_LINE 0xbb00UL /* --> 0xbb80 */
+
+#define SCHIZO_STCERR_WRITE 0x2UL
+#define SCHIZO_STCERR_READ 0x1UL
+
+#define SCHIZO_STCTAG_PPN 0x3fffffff00000000UL
+#define SCHIZO_STCTAG_VPN 0x00000000ffffe000UL
+#define SCHIZO_STCTAG_VALID 0x8000000000000000UL
+#define SCHIZO_STCTAG_READ 0x4000000000000000UL
+
+#define SCHIZO_STCLINE_LINDX 0x0000000007800000UL
+#define SCHIZO_STCLINE_SPTR 0x000000000007e000UL
+#define SCHIZO_STCLINE_LADDR 0x0000000000001fc0UL
+#define SCHIZO_STCLINE_EPTR 0x000000000000003fUL
+#define SCHIZO_STCLINE_VALID 0x0000000000600000UL
+#define SCHIZO_STCLINE_FOFN 0x0000000000180000UL
+
+static void __schizo_check_stc_error_pbm(struct pci_pbm_info *pbm,
+ enum schizo_error_type type)
+{
+ struct pci_controller_info *p = pbm->parent;
+ struct pci_strbuf *strbuf = &pbm->stc;
+ unsigned long regbase = p->controller_regs;
+ unsigned long err_base, tag_base, line_base;
+ u64 control;
+ char pbm_name = (pbm == &p->pbm_A ? 'A' : 'B');
+ int i;
+
+ if (pbm == &p->pbm_A)
+ regbase += SCHIZO_PBM_A_REGS_OFF;
+ else
+ regbase += SCHIZO_PBM_B_REGS_OFF;
+
+ err_base = regbase + SCHIZO_STC_ERR;
+ tag_base = regbase + SCHIZO_STC_TAG;
+ line_base = regbase + SCHIZO_STC_LINE;
+
+ spin_lock(&stc_buf_lock);
+
+ /* This is __REALLY__ dangerous. When we put the
+ * streaming buffer into diagnostic mode to probe
+ * it's tags and error status, we _must_ clear all
+ * of the line tag valid bits before re-enabling
+ * the streaming buffer. If any dirty data lives
+ * in the STC when we do this, we will end up
+ * invalidating it before it has a chance to reach
+ * main memory.
+ */
+ control = schizo_read(strbuf->strbuf_control);
+ schizo_write(strbuf->strbuf_control,
+ (control | SCHIZO_STRBUF_CTRL_DENAB));
+ for (i = 0; i < 128; i++) {
+ unsigned long val;
+
+ val = schizo_read(err_base + (i * 8UL));
+ schizo_write(err_base + (i * 8UL), 0UL);
+ stc_error_buf[i] = val;
+ }
+ for (i = 0; i < 16; i++) {
+ stc_tag_buf[i] = schizo_read(tag_base + (i * 8UL));
+ stc_line_buf[i] = schizo_read(line_base + (i * 8UL));
+ schizo_write(tag_base + (i * 8UL), 0UL);
+ schizo_write(line_base + (i * 8UL), 0UL);
+ }
+
+ /* OK, state is logged, exit diagnostic mode. */
+ schizo_write(strbuf->strbuf_control, control);
+
+ for (i = 0; i < 16; i++) {
+ int j, saw_error, first, last;
+
+ saw_error = 0;
+ first = i * 8;
+ last = first + 8;
+ for (j = first; j < last; j++) {
+ unsigned long errval = stc_error_buf[j];
+ if (errval != 0) {
+ saw_error++;
+ printk("SCHIZO%d: PBM-%c STC_ERR(%d)[wr(%d)rd(%d)]\n",
+ p->index, pbm_name,
+ j,
+ (errval & SCHIZO_STCERR_WRITE) ? 1 : 0,
+ (errval & SCHIZO_STCERR_READ) ? 1 : 0);
+ }
+ }
+ if (saw_error != 0) {
+ unsigned long tagval = stc_tag_buf[i];
+ unsigned long lineval = stc_line_buf[i];
+ printk("SCHIZO%d: PBM-%c STC_TAG(%d)[PA(%016lx)VA(%08lx)V(%d)R(%d)]\n",
+ p->index, pbm_name,
+ i,
+ ((tagval & SCHIZO_STCTAG_PPN) >> 19UL),
+ (tagval & SCHIZO_STCTAG_VPN),
+ ((tagval & SCHIZO_STCTAG_VALID) ? 1 : 0),
+ ((tagval & SCHIZO_STCTAG_READ) ? 1 : 0));
+
+ /* XXX Should spit out per-bank error information... -DaveM */
+ printk("SCHIZO%d: PBM-%c STC_LINE(%d)[LIDX(%lx)SP(%lx)LADDR(%lx)EP(%lx)"
+ "V(%d)FOFN(%d)]\n",
+ p->index, pbm_name,
+ i,
+ ((lineval & SCHIZO_STCLINE_LINDX) >> 23UL),
+ ((lineval & SCHIZO_STCLINE_SPTR) >> 13UL),
+ ((lineval & SCHIZO_STCLINE_LADDR) >> 6UL),
+ ((lineval & SCHIZO_STCLINE_EPTR) >> 0UL),
+ ((lineval & SCHIZO_STCLINE_VALID) ? 1 : 0),
+ ((lineval & SCHIZO_STCLINE_FOFN) ? 1 : 0));
+ }
+ }
+
+ spin_unlock(&stc_buf_lock);
+}
+
+/* IOMMU is per-PBM in Schizo, so interrogate both for anonymous
+ * controller level errors.
+ */
+
+#define SCHIZO_IOMMU_TAG 0xa580UL
+#define SCHIZO_IOMMU_DATA 0xa600UL
+
+#define SCHIZO_IOMMU_TAG_CTXT 0x0000001ffe000000UL
+#define SCHIZO_IOMMU_TAG_ERRSTS 0x0000000001800000UL
+#define SCHIZO_IOMMU_TAG_ERR 0x0000000000400000UL
+#define SCHIZO_IOMMU_TAG_WRITE 0x0000000000200000UL
+#define SCHIZO_IOMMU_TAG_STREAM 0x0000000000100000UL
+#define SCHIZO_IOMMU_TAG_SIZE 0x0000000000080000UL
+#define SCHIZO_IOMMU_TAG_VPAGE 0x000000000007ffffUL
+
+#define SCHIZO_IOMMU_DATA_VALID 0x0000000100000000UL
+#define SCHIZO_IOMMU_DATA_CACHE 0x0000000040000000UL
+#define SCHIZO_IOMMU_DATA_PPAGE 0x000000003fffffffUL
+
+static void schizo_check_iommu_error_pbm(struct pci_pbm_info *pbm,
+ enum schizo_error_type type)
+{
+ struct pci_controller_info *p = pbm->parent;
+ struct pci_iommu *iommu = pbm->iommu;
+ unsigned long iommu_tag[16];
+ unsigned long iommu_data[16];
+ unsigned long flags;
+ u64 control;
+ char pbm_name = (pbm == &p->pbm_A ? 'A' : 'B');
+ int i;
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ control = schizo_read(iommu->iommu_control);
+ if (control & SCHIZO_IOMMU_CTRL_XLTEERR) {
+ unsigned long base;
+ char *type_string;
+
+ /* Clear the error encountered bit. */
+ control &= ~SCHIZO_IOMMU_CTRL_XLTEERR;
+ schizo_write(iommu->iommu_control, control);
+
+ switch((control & SCHIZO_IOMMU_CTRL_XLTESTAT) >> 25UL) {
+ case 0:
+ type_string = "Protection Error";
+ break;
+ case 1:
+ type_string = "Invalid Error";
+ break;
+ case 2:
+ type_string = "TimeOut Error";
+ break;
+ case 3:
+ default:
+ type_string = "ECC Error";
+ break;
+ };
+ printk("SCHIZO%d: PBM-%c IOMMU Error, type[%s]\n",
+ p->index, pbm_name, type_string);
+
+ /* Put the IOMMU into diagnostic mode and probe
+ * it's TLB for entries with error status.
+ *
+ * It is very possible for another DVMA to occur
+ * while we do this probe, and corrupt the system
+ * further. But we are so screwed at this point
+ * that we are likely to crash hard anyways, so
+ * get as much diagnostic information to the
+ * console as we can.
+ */
+ schizo_write(iommu->iommu_control,
+ control | SCHIZO_IOMMU_CTRL_DENAB);
+
+ base = p->controller_regs;
+ if (pbm == &p->pbm_A)
+ base += SCHIZO_PBM_A_REGS_OFF;
+ else
+ base += SCHIZO_PBM_B_REGS_OFF;
+
+ for (i = 0; i < 16; i++) {
+ iommu_tag[i] =
+ schizo_read(base + SCHIZO_IOMMU_TAG + (i * 8UL));
+ iommu_data[i] =
+ schizo_read(base + SCHIZO_IOMMU_DATA + (i * 8UL));
+
+ /* Now clear out the entry. */
+ schizo_write(base + SCHIZO_IOMMU_TAG + (i * 8UL), 0);
+ schizo_write(base + SCHIZO_IOMMU_DATA + (i * 8UL), 0);
+ }
+
+ /* Leave diagnostic mode. */
+ schizo_write(iommu->iommu_control, control);
+
+ for (i = 0; i < 16; i++) {
+ unsigned long tag, data;
+
+ tag = iommu_tag[i];
+ if (!(tag & SCHIZO_IOMMU_TAG_ERR))
+ continue;
+
+ data = iommu_data[i];
+ switch((tag & SCHIZO_IOMMU_TAG_ERRSTS) >> 23UL) {
+ case 0:
+ type_string = "Protection Error";
+ break;
+ case 1:
+ type_string = "Invalid Error";
+ break;
+ case 2:
+ type_string = "TimeOut Error";
+ break;
+ case 3:
+ default:
+ type_string = "ECC Error";
+ break;
+ };
+ printk("SCHIZO%d: PBM-%c IOMMU TAG(%d)[error(%s) ctx(%x) wr(%d) str(%d) "
+ "sz(%dK) vpg(%08lx)]\n",
+ p->index, pbm_name, i, type_string,
+ (int)((tag & SCHIZO_IOMMU_TAG_CTXT) >> 25UL),
+ ((tag & SCHIZO_IOMMU_TAG_WRITE) ? 1 : 0),
+ ((tag & SCHIZO_IOMMU_TAG_STREAM) ? 1 : 0),
+ ((tag & SCHIZO_IOMMU_TAG_SIZE) ? 64 : 8),
+ (tag & SCHIZO_IOMMU_TAG_VPAGE) << PAGE_SHIFT);
+ printk("SCHIZO%d: PBM-%c IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n",
+ p->index, pbm_name, i,
+ ((data & SCHIZO_IOMMU_DATA_VALID) ? 1 : 0),
+ ((data & SCHIZO_IOMMU_DATA_CACHE) ? 1 : 0),
+ (data & SCHIZO_IOMMU_DATA_PPAGE) << PAGE_SHIFT);
+ }
+ }
+ __schizo_check_stc_error_pbm(pbm, type);
+ spin_unlock_irqrestore(&iommu->lock, flags);
+}
+
+static void schizo_check_iommu_error(struct pci_controller_info *p,
+ enum schizo_error_type type)
+{
+ schizo_check_iommu_error_pbm(&p->pbm_A, type);
+ schizo_check_iommu_error_pbm(&p->pbm_B, type);
+}
+
+/* Uncorrectable ECC error status gathering. */
+#define SCHIZO_UE_AFSR 0x10030UL
+#define SCHIZO_UE_AFAR 0x10038UL
+
+#define SCHIZO_UEAFSR_PPIO 0x8000000000000000UL
+#define SCHIZO_UEAFSR_PDRD 0x4000000000000000UL
+#define SCHIZO_UEAFSR_PDWR 0x2000000000000000UL
+#define SCHIZO_UEAFSR_SPIO 0x1000000000000000UL
+#define SCHIZO_UEAFSR_SDMA 0x0800000000000000UL
+#define SCHIZO_UEAFSR_ERRPNDG 0x0300000000000000UL
+#define SCHIZO_UEAFSR_BMSK 0x000003ff00000000UL
+#define SCHIZO_UEAFSR_QOFF 0x00000000c0000000UL
+#define SCHIZO_UEAFSR_AID 0x000000001f000000UL
+#define SCHIZO_UEAFSR_PARTIAL 0x0000000000800000UL
+#define SCHIZO_UEAFSR_OWNEDIN 0x0000000000400000UL
+#define SCHIZO_UEAFSR_MTAGSYND 0x00000000000f0000UL
+#define SCHIZO_UEAFSR_MTAG 0x000000000000e000UL
+#define SCHIZO_UEAFSR_ECCSYND 0x00000000000001ffUL
+
+static void schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct pci_controller_info *p = dev_id;
+ unsigned long afsr_reg = p->controller_regs + SCHIZO_UE_AFSR;
+ unsigned long afar_reg = p->controller_regs + SCHIZO_UE_AFAR;
+ unsigned long afsr, afar, error_bits;
+ int reported, limit;
+
+ /* Latch uncorrectable error status. */
+ afar = schizo_read(afar_reg);
+
+ /* If either of the error pending bits are set in the
+ * AFSR, the error status is being actively updated by
+ * the hardware and we must re-read to get a clean value.
+ */
+ limit = 1000;
+ do {
+ afsr = schizo_read(afsr_reg);
+ } while ((afsr & SCHIZO_UEAFSR_ERRPNDG) != 0 && --limit);
+
+ /* Clear the primary/secondary error status bits. */
+ error_bits = afsr &
+ (SCHIZO_UEAFSR_PPIO | SCHIZO_UEAFSR_PDRD | SCHIZO_UEAFSR_PDWR |
+ SCHIZO_UEAFSR_SPIO | SCHIZO_UEAFSR_SDMA);
+ schizo_write(afsr_reg, error_bits);
+
+ /* Log the error. */
+ printk("SCHIZO%d: Uncorrectable Error, primary error type[%s]\n",
+ p->index,
+ (((error_bits & SCHIZO_UEAFSR_PPIO) ?
+ "PIO" :
+ ((error_bits & SCHIZO_UEAFSR_PDRD) ?
+ "DMA Read" :
+ ((error_bits & SCHIZO_UEAFSR_PDWR) ?
+ "DMA Write" : "???")))));
+ printk("SCHIZO%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n",
+ p->index,
+ (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL,
+ (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL,
+ (afsr & SCHIZO_UEAFSR_AID) >> 24UL);
+ printk("SCHIZO%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n",
+ p->index,
+ (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0,
+ (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0,
+ (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL,
+ (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL,
+ (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL);
+ printk("SCHIZO%d: UE AFAR [%016lx]\n", p->index, afar);
+ printk("SCHIZO%d: UE Secondary errors [", p->index);
+ reported = 0;
+ if (afsr & SCHIZO_UEAFSR_SPIO) {
+ reported++;
+ printk("(PIO)");
+ }
+ if (afsr & SCHIZO_UEAFSR_SDMA) {
+ reported++;
+ printk("(DMA)");
+ }
+ if (!reported)
+ printk("(none)");
+ printk("]\n");
+
+ /* Interrogate IOMMU for error status. */
+ schizo_check_iommu_error(p, UE_ERR);
+
+ schizo_clear_other_err_intr(irq);
+}
+
+#define SCHIZO_CE_AFSR 0x10040UL
+#define SCHIZO_CE_AFAR 0x10048UL
+
+#define SCHIZO_CEAFSR_PPIO 0x8000000000000000UL
+#define SCHIZO_CEAFSR_PDRD 0x4000000000000000UL
+#define SCHIZO_CEAFSR_PDWR 0x2000000000000000UL
+#define SCHIZO_CEAFSR_SPIO 0x1000000000000000UL
+#define SCHIZO_CEAFSR_SDMA 0x0800000000000000UL
+#define SCHIZO_CEAFSR_ERRPNDG 0x0300000000000000UL
+#define SCHIZO_CEAFSR_BMSK 0x000003ff00000000UL
+#define SCHIZO_CEAFSR_QOFF 0x00000000c0000000UL
+#define SCHIZO_CEAFSR_AID 0x000000001f000000UL
+#define SCHIZO_CEAFSR_PARTIAL 0x0000000000800000UL
+#define SCHIZO_CEAFSR_OWNEDIN 0x0000000000400000UL
+#define SCHIZO_CEAFSR_MTAGSYND 0x00000000000f0000UL
+#define SCHIZO_CEAFSR_MTAG 0x000000000000e000UL
+#define SCHIZO_CEAFSR_ECCSYND 0x00000000000001ffUL
+
+static void schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct pci_controller_info *p = dev_id;
+ unsigned long afsr_reg = p->controller_regs + SCHIZO_CE_AFSR;
+ unsigned long afar_reg = p->controller_regs + SCHIZO_CE_AFAR;
+ unsigned long afsr, afar, error_bits;
+ int reported, limit;
+
+ /* Latch error status. */
+ afar = schizo_read(afar_reg);
+
+ /* If either of the error pending bits are set in the
+ * AFSR, the error status is being actively updated by
+ * the hardware and we must re-read to get a clean value.
+ */
+ limit = 1000;
+ do {
+ afsr = schizo_read(afsr_reg);
+ } while ((afsr & SCHIZO_UEAFSR_ERRPNDG) != 0 && --limit);
+
+ /* Clear primary/secondary error status bits. */
+ error_bits = afsr &
+ (SCHIZO_CEAFSR_PPIO | SCHIZO_CEAFSR_PDRD | SCHIZO_CEAFSR_PDWR |
+ SCHIZO_CEAFSR_SPIO | SCHIZO_CEAFSR_SDMA);
+ schizo_write(afsr_reg, error_bits);
+
+ /* Log the error. */
+ printk("SCHIZO%d: Correctable Error, primary error type[%s]\n",
+ p->index,
+ (((error_bits & SCHIZO_CEAFSR_PPIO) ?
+ "PIO" :
+ ((error_bits & SCHIZO_CEAFSR_PDRD) ?
+ "DMA Read" :
+ ((error_bits & SCHIZO_CEAFSR_PDWR) ?
+ "DMA Write" : "???")))));
+
+ /* XXX Use syndrome and afar to print out module string just like
+ * XXX UDB CE trap handler does... -DaveM
+ */
+ printk("SCHIZO%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n",
+ p->index,
+ (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL,
+ (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL,
+ (afsr & SCHIZO_UEAFSR_AID) >> 24UL);
+ printk("SCHIZO%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n",
+ p->index,
+ (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0,
+ (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0,
+ (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL,
+ (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL,
+ (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL);
+ printk("SCHIZO%d: CE AFAR [%016lx]\n", p->index, afar);
+ printk("SCHIZO%d: CE Secondary errors [", p->index);
+ reported = 0;
+ if (afsr & SCHIZO_CEAFSR_SPIO) {
+ reported++;
+ printk("(PIO)");
+ }
+ if (afsr & SCHIZO_CEAFSR_SDMA) {
+ reported++;
+ printk("(DMA)");
+ }
+ if (!reported)
+ printk("(none)");
+ printk("]\n");
+
+ schizo_clear_other_err_intr(irq);
+}
+
+#define SCHIZO_PCI_AFSR 0x2010UL
+#define SCHIZO_PCI_AFAR 0x2018UL
+
+#define SCHIZO_PCIAFSR_PMA 0x8000000000000000UL
+#define SCHIZO_PCIAFSR_PTA 0x4000000000000000UL
+#define SCHIZO_PCIAFSR_PRTRY 0x2000000000000000UL
+#define SCHIZO_PCIAFSR_PPERR 0x1000000000000000UL
+#define SCHIZO_PCIAFSR_PTTO 0x0800000000000000UL
+#define SCHIZO_PCIAFSR_PUNUS 0x0400000000000000UL
+#define SCHIZO_PCIAFSR_SMA 0x0200000000000000UL
+#define SCHIZO_PCIAFSR_STA 0x0100000000000000UL
+#define SCHIZO_PCIAFSR_SRTRY 0x0080000000000000UL
+#define SCHIZO_PCIAFSR_SPERR 0x0040000000000000UL
+#define SCHIZO_PCIAFSR_STTO 0x0020000000000000UL
+#define SCHIZO_PCIAFSR_SUNUS 0x0010000000000000UL
+#define SCHIZO_PCIAFSR_BMSK 0x000003ff00000000UL
+#define SCHIZO_PCIAFSR_BLK 0x0000000080000000UL
+#define SCHIZO_PCIAFSR_CFG 0x0000000040000000UL
+#define SCHIZO_PCIAFSR_MEM 0x0000000020000000UL
+#define SCHIZO_PCIAFSR_IO 0x0000000010000000UL
+
+static void schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct pci_pbm_info *pbm = dev_id;
+ struct pci_controller_info *p = pbm->parent;
+ unsigned long afsr_reg, afar_reg, base;
+ unsigned long afsr, afar, error_bits;
+ int reported;
+ char pbm_name;
+
+ base = p->controller_regs;
+ if (pbm == &pbm->parent->pbm_A) {
+ base += SCHIZO_PBM_A_REGS_OFF;
+ pbm_name = 'A';
+ } else {
+ base += SCHIZO_PBM_B_REGS_OFF;
+ pbm_name = 'B';
+ }
+
+ afsr_reg = base + SCHIZO_PCI_AFSR;
+ afar_reg = base + SCHIZO_PCI_AFAR;
+
+ /* Latch error status. */
+ afar = schizo_read(afar_reg);
+ afsr = schizo_read(afsr_reg);
+
+ /* Clear primary/secondary error status bits. */
+ error_bits = afsr &
+ (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA |
+ SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR |
+ SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS |
+ SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |
+ SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |
+ SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS);
+ schizo_write(afsr_reg, error_bits);
+
+ /* Log the error. */
+ printk("SCHIZO%d: PBM-%c PCI Error, primary error type[%s]\n",
+ p->index, pbm_name,
+ (((error_bits & SCHIZO_PCIAFSR_PMA) ?
+ "Master Abort" :
+ ((error_bits & SCHIZO_PCIAFSR_PTA) ?
+ "Target Abort" :
+ ((error_bits & SCHIZO_PCIAFSR_PRTRY) ?
+ "Excessive Retries" :
+ ((error_bits & SCHIZO_PCIAFSR_PPERR) ?
+ "Parity Error" :
+ ((error_bits & SCHIZO_PCIAFSR_PTTO) ?
+ "Timeout" :
+ ((error_bits & SCHIZO_PCIAFSR_PUNUS) ?
+ "Bus Unusable" : "???"))))))));
+ printk("SCHIZO%d: PBM-%c bytemask[%04lx] was_block(%d) space(%s)\n",
+ p->index, pbm_name,
+ (afsr & SCHIZO_PCIAFSR_BMSK) >> 32UL,
+ (afsr & SCHIZO_PCIAFSR_BLK) ? 1 : 0,
+ ((afsr & SCHIZO_PCIAFSR_CFG) ?
+ "Config" :
+ ((afsr & SCHIZO_PCIAFSR_MEM) ?
+ "Memory" :
+ ((afsr & SCHIZO_PCIAFSR_IO) ?
+ "I/O" : "???"))));
+ printk("SCHIZO%d: PBM-%c PCI AFAR [%016lx]\n",
+ p->index, pbm_name, afar);
+ printk("SCHIZO%d: PBM-%c PCI Secondary errors [",
+ p->index, pbm_name);
+ reported = 0;
+ if (afsr & SCHIZO_PCIAFSR_SMA) {
+ reported++;
+ printk("(Master Abort)");
+ }
+ if (afsr & SCHIZO_PCIAFSR_STA) {
+ reported++;
+ printk("(Target Abort)");
+ }
+ if (afsr & SCHIZO_PCIAFSR_SRTRY) {
+ reported++;
+ printk("(Excessive Retries)");
+ }
+ if (afsr & SCHIZO_PCIAFSR_SPERR) {
+ reported++;
+ printk("(Parity Error)");
+ }
+ if (afsr & SCHIZO_PCIAFSR_STTO) {
+ reported++;
+ printk("(Timeout)");
+ }
+ if (afsr & SCHIZO_PCIAFSR_SUNUS) {
+ reported++;
+ printk("(Bus Unusable)");
+ }
+ if (!reported)
+ printk("(none)");
+ printk("]\n");
+
+ /* For the error types shown, scan PBM's PCI bus for devices
+ * which have logged that error type.
+ */
+
+ /* If we see a Target Abort, this could be the result of an
+ * IOMMU translation error of some sort. It is extremely
+ * useful to log this information as usually it indicates
+ * a bug in the IOMMU support code or a PCI device driver.
+ */
+ if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) {
+ schizo_check_iommu_error(p, PCI_ERR);
+ pci_scan_for_target_abort(p, pbm, pbm->pci_bus);
+ }
+ if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA))
+ pci_scan_for_master_abort(p, pbm, pbm->pci_bus);
+
+ /* For excessive retries, PSYCHO/PBM will abort the device
+ * and there is no way to specifically check for excessive
+ * retries in the config space status registers. So what
+ * we hope is that we'll catch it via the master/target
+ * abort events.
+ */
+
+ if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR))
+ pci_scan_for_parity_error(p, pbm, pbm->pci_bus);
+
+ schizo_clear_other_err_intr(irq);
+}
+
+#define SCHIZO_SAFARI_ERRLOG 0x10018UL
+
+#define SAFARI_ERRLOG_ERROUT 0x8000000000000000UL
+
+#define SAFARI_ERROR_BADCMD 0x4000000000000000UL
+#define SAFARI_ERROR_SSMDIS 0x2000000000000000UL
+#define SAFARI_ERROR_BADMA 0x1000000000000000UL
+#define SAFARI_ERROR_BADMB 0x0800000000000000UL
+#define SAFARI_ERROR_BADMC 0x0400000000000000UL
+#define SAFARI_ERROR_CPU1PS 0x0000000000002000UL
+#define SAFARI_ERROR_CPU1PB 0x0000000000001000UL
+#define SAFARI_ERROR_CPU0PS 0x0000000000000800UL
+#define SAFARI_ERROR_CPU0PB 0x0000000000000400UL
+#define SAFARI_ERROR_CIQTO 0x0000000000000200UL
+#define SAFARI_ERROR_LPQTO 0x0000000000000100UL
+#define SAFARI_ERROR_SFPQTO 0x0000000000000080UL
+#define SAFARI_ERROR_UFPQTO 0x0000000000000040UL
+#define SAFARI_ERROR_APERR 0x0000000000000020UL
+#define SAFARI_ERROR_UNMAP 0x0000000000000010UL
+#define SAFARI_ERROR_BUSERR 0x0000000000000004UL
+#define SAFARI_ERROR_TIMEOUT 0x0000000000000002UL
+#define SAFARI_ERROR_ILL 0x0000000000000001UL
+
+/* We only expect UNMAP errors here. The rest of the Safari errors
+ * are marked fatal and thus cause a system reset.
+ */
+static void schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct pci_controller_info *p = dev_id;
+ u64 errlog;
+
+ errlog = schizo_read(p->controller_regs + SCHIZO_SAFARI_ERRLOG);
+ schizo_write(p->controller_regs + SCHIZO_SAFARI_ERRLOG,
+ errlog & ~(SAFARI_ERRLOG_ERROUT));
+
+ if (!(errlog & SAFARI_ERROR_UNMAP)) {
+ printk("SCHIZO%d: Unexpected Safari error interrupt, errlog[%016lx]\n",
+ p->index, errlog);
+
+ schizo_clear_other_err_intr(irq);
+ return;
+ }
+
+ printk("SCHIZO%d: Safari interrupt, UNMAPPED error, interrogating IOMMUs.\n",
+ p->index);
+ schizo_check_iommu_error(p, SAFARI_ERR);
+
+ schizo_clear_other_err_intr(irq);
+}
+
+/* Nearly identical to PSYCHO equivalents... */
+#define SCHIZO_ECC_CTRL 0x10020UL
+#define SCHIZO_ECCCTRL_EE 0x8000000000000000 /* Enable ECC Checking */
+#define SCHIZO_ECCCTRL_UE 0x4000000000000000 /* Enable UE Interrupts */
+#define SCHIZO_ECCCTRL_CE 0x2000000000000000 /* Enable CE INterrupts */
+
+#define SCHIZO_SAFARI_ERRCTRL 0x10008UL
+#define SCHIZO_SAFERRCTRL_EN 0x8000000000000000UL
+#define SCHIZO_SAFARI_IRQCTRL 0x10010UL
+#define SCHIZO_SAFIRQCTRL_EN 0x8000000000000000UL
+
+#define SCHIZO_UE_INO 0x30 /* Uncorrectable ECC error */
+#define SCHIZO_CE_INO 0x31 /* Correctable ECC error */
+#define SCHIZO_PCIERR_A_INO 0x32 /* PBM A PCI bus error */
+#define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */
+#define SCHIZO_SERR_INO 0x34 /* Safari interface error */
+
+#define SCHIZO_PCIA_CTRL (SCHIZO_PBM_A_REGS_OFF + 0x2000UL)
+#define SCHIZO_PCIB_CTRL (SCHIZO_PBM_B_REGS_OFF + 0x2000UL)
+#define SCHIZO_PCICTRL_BUNUS (1UL << 63UL)
+#define SCHIZO_PCICTRL_ESLCK (1UL << 51UL)
+#define SCHIZO_PCICTRL_TTO_ERR (1UL << 38UL)
+#define SCHIZO_PCICTRL_RTRY_ERR (1UL << 37UL)
+#define SCHIZO_PCICTRL_DTO_ERR (1UL << 36UL)
+#define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL)
+#define SCHIZO_PCICTRL_SERR (1UL << 34UL)
+#define SCHIZO_PCICTRL_SBH_INT (1UL << 18UL)
+#define SCHIZO_PCICTRL_EEN (1UL << 17UL)
+
+static void __init schizo_register_error_handlers(struct pci_controller_info *p)
+{
+ struct pci_pbm_info *pbm_a = &p->pbm_A;
+ struct pci_pbm_info *pbm_b = &p->pbm_B;
+ unsigned long base = p->controller_regs;
+ unsigned int irq, portid = p->portid;
+ struct ino_bucket *bucket;
+ u64 tmp;
+
+ /* Build IRQs and register handlers. */
+ irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_UE_INO);
+ if (request_irq(irq, schizo_ue_intr,
+ SA_SHIRQ, "SCHIZO UE", p) < 0) {
+ prom_printf("SCHIZO%d: Cannot register UE interrupt.\n",
+ p->index);
+ prom_halt();
+ }
+ bucket = __bucket(irq);
+ tmp = readl(bucket->imap);
+ upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_UE_INO) + 4));
+
+ irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_CE_INO);
+ if (request_irq(irq, schizo_ce_intr,
+ SA_SHIRQ, "SCHIZO CE", p) < 0) {
+ prom_printf("SCHIZO%d: Cannot register CE interrupt.\n",
+ p->index);
+ prom_halt();
+ }
+ bucket = __bucket(irq);
+ tmp = upa_readl(bucket->imap);
+ upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_CE_INO) + 4));
+
+ irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_PCIERR_A_INO);
+ if (request_irq(irq, schizo_pcierr_intr,
+ SA_SHIRQ, "SCHIZO PCIERR", pbm_a) < 0) {
+ prom_printf("SCHIZO%d(PBMA): Cannot register PciERR interrupt.\n",
+ p->index);
+ prom_halt();
+ }
+ bucket = __bucket(irq);
+ tmp = upa_readl(bucket->imap);
+ upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4));
+
+ irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_PCIERR_B_INO);
+ if (request_irq(irq, schizo_pcierr_intr,
+ SA_SHIRQ, "SCHIZO PCIERR", pbm_b) < 0) {
+ prom_printf("SCHIZO%d(PBMB): Cannot register PciERR interrupt.\n",
+ p->index);
+ prom_halt();
+ }
+ bucket = __bucket(irq);
+ tmp = upa_readl(bucket->imap);
+ upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4));
+
+ irq = schizo_irq_build(pbm_a, NULL, (portid << 6) | SCHIZO_SERR_INO);
+ if (request_irq(irq, schizo_safarierr_intr,
+ SA_SHIRQ, "SCHIZO SERR", p) < 0) {
+ prom_printf("SCHIZO%d(PBMB): Cannot register SafariERR interrupt.\n",
+ p->index);
+ prom_halt();
+ }
+ bucket = __bucket(irq);
+ tmp = upa_readl(bucket->imap);
+ upa_writel(tmp, (base + SCHIZO_PBM_B_REGS_OFF + schizo_imap_offset(SCHIZO_SERR_INO) + 4));
+
+ /* Enable UE and CE interrupts for controller. */
+ schizo_write(base + SCHIZO_ECC_CTRL,
+ (SCHIZO_ECCCTRL_EE |
+ SCHIZO_ECCCTRL_UE |
+ SCHIZO_ECCCTRL_CE));
+
+ /* Enable PCI Error interrupts and clear error
+ * bits for each PBM.
+ */
+ tmp = schizo_read(base + SCHIZO_PCIA_CTRL);
+ tmp |= (SCHIZO_PCICTRL_BUNUS |
+ SCHIZO_PCICTRL_ESLCK |
+ SCHIZO_PCICTRL_TTO_ERR |
+ SCHIZO_PCICTRL_RTRY_ERR |
+ SCHIZO_PCICTRL_DTO_ERR |
+ SCHIZO_PCICTRL_SBH_ERR |
+ SCHIZO_PCICTRL_SERR |
+ SCHIZO_PCICTRL_SBH_INT |
+ SCHIZO_PCICTRL_EEN);
+ schizo_write(base + SCHIZO_PCIA_CTRL, tmp);
+
+ tmp = schizo_read(base + SCHIZO_PCIB_CTRL);
+ tmp |= (SCHIZO_PCICTRL_BUNUS |
+ SCHIZO_PCICTRL_ESLCK |
+ SCHIZO_PCICTRL_TTO_ERR |
+ SCHIZO_PCICTRL_RTRY_ERR |
+ SCHIZO_PCICTRL_DTO_ERR |
+ SCHIZO_PCICTRL_SBH_ERR |
+ SCHIZO_PCICTRL_SERR |
+ SCHIZO_PCICTRL_SBH_INT |
+ SCHIZO_PCICTRL_EEN);
+ schizo_write(base + SCHIZO_PCIB_CTRL, tmp);
+
+ schizo_write(base + SCHIZO_PBM_A_REGS_OFF + SCHIZO_PCI_AFSR,
+ (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA |
+ SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR |
+ SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS |
+ SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |
+ SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |
+ SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS));
+ schizo_write(base + SCHIZO_PBM_B_REGS_OFF + SCHIZO_PCI_AFSR,
+ (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA |
+ SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR |
+ SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS |
+ SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |
+ SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |
+ SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS));
+
+ /* Make all Safari error conditions fatal except unmapped errors
+ * which we make generate interrupts.
+ */
+ schizo_write(base + SCHIZO_SAFARI_ERRCTRL,
+ (SCHIZO_SAFERRCTRL_EN |
+ (SAFARI_ERROR_BADCMD | SAFARI_ERROR_SSMDIS |
+ SAFARI_ERROR_BADMA | SAFARI_ERROR_BADMB |
+ SAFARI_ERROR_BADMC | SAFARI_ERROR_CPU1PS |
+ SAFARI_ERROR_CPU1PB | SAFARI_ERROR_CPU0PS |
+ SAFARI_ERROR_CPU0PB | SAFARI_ERROR_CIQTO |
+ SAFARI_ERROR_LPQTO | SAFARI_ERROR_SFPQTO |
+ SAFARI_ERROR_UFPQTO | SAFARI_ERROR_APERR |
+ SAFARI_ERROR_BUSERR | SAFARI_ERROR_TIMEOUT |
+ SAFARI_ERROR_ILL)));
+
+ schizo_write(base + SCHIZO_SAFARI_IRQCTRL,
+ (SCHIZO_SAFIRQCTRL_EN | (SAFARI_ERROR_UNMAP)));
+}
+
+/* We have to do the config space accesses by hand, thus... */
+#define PBM_BRIDGE_BUS 0x40
+#define PBM_BRIDGE_SUBORDINATE 0x41
+static void __init pbm_renumber(struct pci_pbm_info *pbm, u8 orig_busno)
+{
+ u8 *addr, busno;
+ int nbus;
+
+ busno = pci_highest_busnum;
+ nbus = pbm->pci_last_busno - pbm->pci_first_busno;
+
+ addr = schizo_pci_config_mkaddr(pbm, orig_busno,
+ 0, PBM_BRIDGE_BUS);
+ pci_config_write8(addr, busno);
+ addr = schizo_pci_config_mkaddr(pbm, busno,
+ 0, PBM_BRIDGE_SUBORDINATE);
+ pci_config_write8(addr, busno + nbus);
+
+ pbm->pci_first_busno = busno;
+ pbm->pci_last_busno = busno + nbus;
+ pci_highest_busnum = busno + nbus + 1;
+
+ do {
+ pci_bus2pbm[busno++] = pbm;
+ } while (nbus--);
+}
+
+/* We have to do the config space accesses by hand here since
+ * the pci_bus2pbm array is not ready yet.
+ */
+static void __init pbm_pci_bridge_renumber(struct pci_pbm_info *pbm,
+ u8 busno)
+{
+ u32 devfn, l, class;
+ u8 hdr_type;
+ int is_multi = 0;
+
+ for(devfn = 0; devfn < 0xff; ++devfn) {
+ u32 *dwaddr;
+ u8 *baddr;
+
+ if (PCI_FUNC(devfn) != 0 && is_multi == 0)
+ continue;
+
+ /* Anything there? */
+ dwaddr = schizo_pci_config_mkaddr(pbm, busno, devfn, PCI_VENDOR_ID);
+ l = 0xffffffff;
+ pci_config_read32(dwaddr, &l);
+ if (l == 0xffffffff || l == 0x00000000 ||
+ l == 0x0000ffff || l == 0xffff0000) {
+ is_multi = 0;
+ continue;
+ }
+
+ baddr = schizo_pci_config_mkaddr(pbm, busno, devfn, PCI_HEADER_TYPE);
+ pci_config_read8(baddr, &hdr_type);
+ if (PCI_FUNC(devfn) == 0)
+ is_multi = hdr_type & 0x80;
+
+ dwaddr = schizo_pci_config_mkaddr(pbm, busno, devfn, PCI_CLASS_REVISION);
+ class = 0xffffffff;
+ pci_config_read32(dwaddr, &class);
+ if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) {
+ u32 buses = 0xffffffff;
+
+ dwaddr = schizo_pci_config_mkaddr(pbm, busno, devfn,
+ PCI_PRIMARY_BUS);
+ pci_config_read32(dwaddr, &buses);
+ pbm_pci_bridge_renumber(pbm, (buses >> 8) & 0xff);
+ buses &= 0xff000000;
+ pci_config_write32(dwaddr, buses);
+ }
+ }
+}
+
+static void __init pbm_bridge_reconfigure(struct pci_controller_info *p)
+{
+ struct pci_pbm_info *pbm;
+ u8 *addr;
+
+ /* Clear out primary/secondary/subordinate bus numbers on
+ * all PCI-to-PCI bridges under each PBM. The generic bus
+ * probing will fix them up.
+ */
+ pbm_pci_bridge_renumber(&p->pbm_B, p->pbm_B.pci_first_busno);
+ pbm_pci_bridge_renumber(&p->pbm_A, p->pbm_A.pci_first_busno);
+
+ /* Move PBM A out of the way. */
+ pbm = &p->pbm_A;
+ addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno,
+ 0, PBM_BRIDGE_BUS);
+ pci_config_write8(addr, 0xff);
+ addr = schizo_pci_config_mkaddr(pbm, 0xff,
+ 0, PBM_BRIDGE_SUBORDINATE);
+ pci_config_write8(addr, 0xff);
+
+ /* Now we can safely renumber both PBMs. */
+ pbm_renumber(&p->pbm_B, p->pbm_B.pci_first_busno);
+ pbm_renumber(&p->pbm_A, 0xff);
+}
+
+static void __init pbm_config_busmastering(struct pci_pbm_info *pbm)
+{
+ u8 *addr;
+
+ /* Set cache-line size to 64 bytes, this is actually
+ * a nop but I do it for completeness.
+ */
+ addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno,
+ 0, PCI_CACHE_LINE_SIZE);
+ pci_config_write8(addr, 64 / sizeof(u32));
+
+ /* Set PBM latency timer to 64 PCI clocks. */
+ addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno,
+ 0, PCI_LATENCY_TIMER);
+ pci_config_write8(addr, 64);
+}
+
+static void __init pbm_scan_bus(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
+{
+ pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno,
+ p->pci_ops,
+ pbm);
+ pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
+ pci_record_assignments(pbm, pbm->pci_bus);
+ pci_assign_unassigned(pbm, pbm->pci_bus);
+ pci_fixup_irq(pbm, pbm->pci_bus);
+ pci_determine_66mhz_disposition(pbm, pbm->pci_bus);
+ pci_setup_busmastering(pbm, pbm->pci_bus);
+}
+
+static void __init schizo_scan_bus(struct pci_controller_info *p)
+{
+ pbm_bridge_reconfigure(p);
+ pbm_config_busmastering(&p->pbm_B);
+ p->pbm_B.is_66mhz_capable = 0;
+ pbm_config_busmastering(&p->pbm_A);
+ p->pbm_A.is_66mhz_capable = 1;
+ pbm_scan_bus(p, &p->pbm_B);
+ pbm_scan_bus(p, &p->pbm_A);
+
+ /* After the PCI bus scan is complete, we can register
+ * the error interrupt handlers.
+ */
+ schizo_register_error_handlers(p);
}
static void __init schizo_base_address_update(struct pci_dev *pdev, int resource)
{
- /* IMPLEMENT ME */
+ struct pcidev_cookie *pcp = pdev->sysdata;
+ struct pci_pbm_info *pbm = pcp->pbm;
+ struct resource *res, *root;
+ u32 reg;
+ int where, size, is_64bit;
+
+ res = &pdev->resource[resource];
+ where = PCI_BASE_ADDRESS_0 + (resource * 4);
+
+ is_64bit = 0;
+ if (res->flags & IORESOURCE_IO)
+ root = &pbm->io_space;
+ else {
+ root = &pbm->mem_space;
+ if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
+ == PCI_BASE_ADDRESS_MEM_TYPE_64)
+ is_64bit = 1;
+ }
+
+ size = res->end - res->start;
+ pci_read_config_dword(pdev, where, &reg);
+ reg = ((reg & size) |
+ (((u32)(res->start - root->start)) & ~size));
+ pci_write_config_dword(pdev, where, reg);
+
+ /* This knows that the upper 32-bits of the address
+ * must be zero. Our PCI common layer enforces this.
+ */
+ if (is_64bit)
+ pci_write_config_dword(pdev, where + 4, 0);
}
static void __init schizo_resource_adjust(struct pci_dev *pdev,
struct resource *res,
struct resource *root)
{
- /* IMPLEMENT ME */
+ res->start += root->start;
+ res->end += root->start;
+}
+
+/* Interrogate Safari match/mask registers to figure out where
+ * PCI MEM, I/O, and Config space are for this PCI bus module.
+ */
+
+#define SCHIZO_PCI_A_MEM_MATCH 0x00040UL
+#define SCHIZO_PCI_A_MEM_MASK 0x00048UL
+#define SCHIZO_PCI_A_IO_MATCH 0x00050UL
+#define SCHIZO_PCI_A_IO_MASK 0x00058UL
+#define SCHIZO_PCI_B_MEM_MATCH 0x00060UL
+#define SCHIZO_PCI_B_MEM_MASK 0x00068UL
+#define SCHIZO_PCI_B_IO_MATCH 0x00070UL
+#define SCHIZO_PCI_B_IO_MASK 0x00078UL
+
+/* VAL must be non-zero. */
+static unsigned long strip_to_lowest_bit_set(unsigned long val)
+{
+ unsigned long tmp;
+
+ tmp = 1UL;
+ while (!(tmp & val))
+ tmp <<= 1UL;
+
+ return tmp;
+}
+
+static void schizo_determine_mem_io_space(struct pci_pbm_info *pbm,
+ int is_pbm_a, unsigned long reg_base)
+{
+ u64 mem_match, mem_mask;
+ u64 io_match;
+ u64 long a, b;
+
+ if (is_pbm_a) {
+ mem_match = reg_base + SCHIZO_PCI_A_MEM_MATCH;
+ io_match = reg_base + SCHIZO_PCI_A_IO_MATCH;
+ } else {
+ mem_match = reg_base + SCHIZO_PCI_B_MEM_MATCH;
+ io_match = reg_base + SCHIZO_PCI_B_IO_MATCH;
+ }
+ mem_mask = mem_match + 0x8UL;
+
+ a = schizo_read(mem_match) & ~0x8000000000000000UL;
+ b = strip_to_lowest_bit_set(schizo_read(mem_mask));
+
+ /* It should be 2GB in size. */
+ pbm->mem_space.start = a;
+ pbm->mem_space.end = a + (b - 1UL);
+ pbm->mem_space.flags = IORESOURCE_MEM;
+
+ /* This 32MB area is divided into two pieces. The first
+ * 16MB is Config space, the next 16MB is I/O space.
+ */
+
+ a = schizo_read(io_match) & ~0x8000000000000000UL;
+ pbm->config_space = a;
+ printk("SCHIZO PBM%c: Local PCI config space at %016lx\n",
+ (is_pbm_a ? 'A' : 'B'), pbm->config_space);
+
+ a += (16UL * 1024UL * 1024UL);
+ pbm->io_space.start = a;
+ pbm->io_space.end = a + ((16UL * 1024UL * 1024UL) - 1UL);
+ pbm->io_space.flags = IORESOURCE_IO;
+}
+
+static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
+{
+ char *name = pbm->name;
+
+ sprintf(name, "SCHIZO%d PBM%c",
+ p->index,
+ (pbm == &p->pbm_A ? 'A' : 'B'));
+ pbm->io_space.name = pbm->mem_space.name = name;
+
+ request_resource(&ioport_resource, &pbm->io_space);
+ request_resource(&iomem_resource, &pbm->mem_space);
+}
+
+#define SCHIZO_STRBUF_CONTROL_A (SCHIZO_PBM_A_REGS_OFF + 0x02800UL)
+#define SCHIZO_STRBUF_FLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x02808UL)
+#define SCHIZO_STRBUF_FSYNC_A (SCHIZO_PBM_A_REGS_OFF + 0x02810UL)
+#define SCHIZO_STRBUF_CTXFLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x02818UL)
+#define SCHIZO_STRBUF_CTXMATCH_A (SCHIZO_PBM_A_REGS_OFF + 0x10000UL)
+
+#define SCHIZO_STRBUF_CONTROL_B (SCHIZO_PBM_B_REGS_OFF + 0x02800UL)
+#define SCHIZO_STRBUF_FLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x02808UL)
+#define SCHIZO_STRBUF_FSYNC_B (SCHIZO_PBM_B_REGS_OFF + 0x02810UL)
+#define SCHIZO_STRBUF_CTXFLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x02818UL)
+#define SCHIZO_STRBUF_CTXMATCH_B (SCHIZO_PBM_B_REGS_OFF + 0x10000UL)
+
+static void schizo_pbm_strbuf_init(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm,
+ int is_pbm_a)
+{
+ unsigned long base = p->controller_regs;
+ u64 control;
+
+ /* SCHIZO has context flushing. */
+ if (is_pbm_a) {
+ pbm->stc.strbuf_control = base + SCHIZO_STRBUF_CONTROL_A;
+ pbm->stc.strbuf_pflush = base + SCHIZO_STRBUF_FLUSH_A;
+ pbm->stc.strbuf_fsync = base + SCHIZO_STRBUF_FSYNC_A;
+ pbm->stc.strbuf_ctxflush = base + SCHIZO_STRBUF_CTXFLUSH_A;
+ pbm->stc.strbuf_ctxmatch_base = base + SCHIZO_STRBUF_CTXMATCH_A;
+ } else {
+ pbm->stc.strbuf_control = base + SCHIZO_STRBUF_CONTROL_B;
+ pbm->stc.strbuf_pflush = base + SCHIZO_STRBUF_FLUSH_B;
+ pbm->stc.strbuf_fsync = base + SCHIZO_STRBUF_FSYNC_B;
+ pbm->stc.strbuf_ctxflush = base + SCHIZO_STRBUF_CTXFLUSH_B;
+ pbm->stc.strbuf_ctxmatch_base = base + SCHIZO_STRBUF_CTXMATCH_B;
+ }
+
+ pbm->stc.strbuf_flushflag = (volatile unsigned long *)
+ ((((unsigned long)&pbm->stc.__flushflag_buf[0])
+ + 63UL)
+ & ~63UL);
+ pbm->stc.strbuf_flushflag_pa = (unsigned long)
+ __pa(pbm->stc.strbuf_flushflag);
+
+ /* Turn off LRU locking and diag mode, enable the
+ * streaming buffer and leave the rerun-disable
+ * setting however OBP set it.
+ */
+ control = schizo_read(pbm->stc.strbuf_control);
+ control &= ~(SCHIZO_STRBUF_CTRL_LPTR |
+ SCHIZO_STRBUF_CTRL_LENAB |
+ SCHIZO_STRBUF_CTRL_DENAB);
+ control |= SCHIZO_STRBUF_CTRL_ENAB;
+ schizo_write(pbm->stc.strbuf_control, control);
+
+ pbm->stc.strbuf_enabled = 1;
+}
+
+#define SCHIZO_IOMMU_CONTROL_A (SCHIZO_PBM_A_REGS_OFF + 0x00200UL)
+#define SCHIZO_IOMMU_TSBBASE_A (SCHIZO_PBM_A_REGS_OFF + 0x00208UL)
+#define SCHIZO_IOMMU_FLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x00210UL)
+#define SCHIZO_IOMMU_CTXFLUSH_A (SCHIZO_PBM_A_REGS_OFF + 0x00218UL)
+#define SCHIZO_IOMMU_TAG_A (SCHIZO_PBM_A_REGS_OFF + 0x0a580UL)
+#define SCHIZO_IOMMU_DATA_A (SCHIZO_PBM_A_REGS_OFF + 0x0a600UL)
+#define SCHIZO_IOMMU_CONTROL_B (SCHIZO_PBM_B_REGS_OFF + 0x00200UL)
+#define SCHIZO_IOMMU_TSBBASE_B (SCHIZO_PBM_B_REGS_OFF + 0x00208UL)
+#define SCHIZO_IOMMU_FLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x00210UL)
+#define SCHIZO_IOMMU_CTXFLUSH_B (SCHIZO_PBM_B_REGS_OFF + 0x00218UL)
+#define SCHIZO_IOMMU_TAG_B (SCHIZO_PBM_B_REGS_OFF + 0x0a580UL)
+#define SCHIZO_IOMMU_DATA_B (SCHIZO_PBM_B_REGS_OFF + 0x0a600UL)
+
+static void schizo_pbm_iommu_init(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm,
+ int is_pbm_a)
+{
+ struct pci_iommu *iommu = pbm->iommu;
+ unsigned long tsbbase, i, tagbase, database;
+ u64 control;
+
+ /* Setup initial software IOMMU state. */
+ spin_lock_init(&iommu->lock);
+ iommu->iommu_cur_ctx = 0;
+
+ /* Register addresses, SCHIZO has iommu ctx flushing. */
+ if (is_pbm_a) {
+ iommu->iommu_control = p->controller_regs + SCHIZO_IOMMU_CONTROL_A;
+ iommu->iommu_tsbbase = p->controller_regs + SCHIZO_IOMMU_TSBBASE_A;
+ iommu->iommu_flush = p->controller_regs + SCHIZO_IOMMU_FLUSH_A;
+ iommu->iommu_ctxflush = p->controller_regs + SCHIZO_IOMMU_CTXFLUSH_A;
+ } else {
+ iommu->iommu_control = p->controller_regs + SCHIZO_IOMMU_CONTROL_B;
+ iommu->iommu_tsbbase = p->controller_regs + SCHIZO_IOMMU_TSBBASE_B;
+ iommu->iommu_flush = p->controller_regs + SCHIZO_IOMMU_FLUSH_B;
+ iommu->iommu_ctxflush = p->controller_regs + SCHIZO_IOMMU_CTXFLUSH_B;
+ }
+
+ /* We use the main control/status register of SCHIZO as the write
+ * completion register.
+ */
+ iommu->write_complete_reg = p->controller_regs + 0x10000UL;
+
+ /*
+ * Invalidate TLB Entries.
+ */
+ control = schizo_read(iommu->iommu_control);
+ control |= SCHIZO_IOMMU_CTRL_DENAB;
+ schizo_write(iommu->iommu_control, control);
+
+ if (is_pbm_a)
+ tagbase = SCHIZO_IOMMU_TAG_A, database = SCHIZO_IOMMU_DATA_A;
+ else
+ tagbase = SCHIZO_IOMMU_TAG_B, database = SCHIZO_IOMMU_DATA_B;
+ for(i = 0; i < 16; i++) {
+ schizo_write(p->controller_regs + tagbase + (i * 8UL), 0);
+ schizo_write(p->controller_regs + database + (i * 8UL), 0);
+ }
+
+ /* Leave diag mode enabled for full-flushing done
+ * in pci_iommu.c
+ */
+
+ /* Using assumed page size 8K with 128K entries we need 1MB iommu page
+ * table (128K ioptes * 8 bytes per iopte). This is
+ * page order 7 on UltraSparc.
+ */
+ tsbbase = __get_free_pages(GFP_KERNEL, 7);
+ if (!tsbbase) {
+ prom_printf("SCHIZO_IOMMU: Error, gfp(tsb) failed.\n");
+ prom_halt();
+ }
+ iommu->page_table = (iopte_t *)tsbbase;
+ iommu->page_table_sz_bits = 17;
+ iommu->page_table_map_base = 0xc0000000;
+ iommu->dma_addr_mask = 0xffffffff;
+ memset((char *)tsbbase, 0, PAGE_SIZE << 7);
+
+ /* We start with no consistent mappings. */
+ iommu->lowest_consistent_map =
+ 1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
+
+ for (i = 0; i < PBM_NCLUSTERS; i++) {
+ iommu->alloc_info[i].flush = 0;
+ iommu->alloc_info[i].next = 0;
+ }
+
+ schizo_write(iommu->iommu_tsbbase, __pa(tsbbase));
+
+ control = schizo_read(iommu->iommu_control);
+ control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ);
+ control |= (SCHIZO_IOMMU_TSBSZ_128K | SCHIZO_IOMMU_CTRL_ENAB);
+ schizo_write(iommu->iommu_control, control);
}
static void schizo_pbm_init(struct pci_controller_info *p,
int prom_node, int is_pbm_a)
{
- /* IMPLEMENT ME */
+ unsigned int busrange[2];
+ struct pci_pbm_info *pbm;
+ int err;
+
+ if (is_pbm_a)
+ pbm = &p->pbm_A;
+ else
+ pbm = &p->pbm_B;
+
+ schizo_determine_mem_io_space(pbm, is_pbm_a, p->controller_regs);
+ pbm_register_toplevel_resources(p, pbm);
+
+ pbm->parent = p;
+ pbm->prom_node = prom_node;
+ prom_getstring(prom_node, "name",
+ pbm->prom_name,
+ sizeof(pbm->prom_name));
+
+ err = prom_getproperty(prom_node, "ranges",
+ (char *) pbm->pbm_ranges,
+ sizeof(pbm->pbm_ranges));
+ if (err != -1)
+ pbm->num_pbm_ranges =
+ (err / sizeof(struct linux_prom_pci_ranges));
+ else
+ pbm->num_pbm_ranges = 0;
+
+ err = prom_getproperty(prom_node, "interrupt-map",
+ (char *)pbm->pbm_intmap,
+ sizeof(pbm->pbm_intmap));
+ if (err != -1) {
+ pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap));
+ err = prom_getproperty(prom_node, "interrupt-map-mask",
+ (char *)&pbm->pbm_intmask,
+ sizeof(pbm->pbm_intmask));
+ if (err == -1) {
+ prom_printf("SCHIZO-PBM: Fatal error, no "
+ "interrupt-map-mask.\n");
+ prom_halt();
+ }
+ } else {
+ pbm->num_pbm_intmap = 0;
+ memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
+ }
+
+ err = prom_getproperty(prom_node, "bus-range",
+ (char *)&busrange[0],
+ sizeof(busrange));
+ if (err == 0 || err == -1) {
+ prom_printf("SCHIZO-PBM: Fatal error, no bus-range.\n");
+ prom_halt();
+ }
+ pbm->pci_first_busno = busrange[0];
+ pbm->pci_last_busno = busrange[1];
+
+ schizo_pbm_iommu_init(p, pbm, is_pbm_a);
+ schizo_pbm_strbuf_init(p, pbm, is_pbm_a);
+}
+
+static void schizo_controller_hwinit(struct pci_controller_info *p)
+{
+ unsigned long pbm_a_base, pbm_b_base;
+ u64 tmp;
+
+ pbm_a_base = p->controller_regs + SCHIZO_PBM_A_REGS_OFF;
+ pbm_b_base = p->controller_regs + SCHIZO_PBM_B_REGS_OFF;
+
+ /* Set IRQ retry to infinity. */
+ schizo_write(pbm_a_base + 0x1a00UL, 0xff);
+ schizo_write(pbm_b_base + 0x1a00UL, 0xff);
+
+ /* Enable arbiter for all PCI slots. */
+ tmp = schizo_read(pbm_a_base + 0x2000UL);
+ tmp |= 0x3fUL;
+ schizo_write(pbm_a_base + 0x2000UL, tmp);
+
+ tmp = schizo_read(pbm_b_base + 0x2000UL);
+ tmp |= 0x3fUL;
+ schizo_write(pbm_b_base + 0x2000UL, tmp);
}
void __init schizo_init(int node)
@@ -90,6 +1708,7 @@ void __init schizo_init(int node)
struct linux_prom64_registers pr_regs[3];
struct pci_controller_info *p;
struct pci_iommu *iommu;
+ unsigned long flags;
u32 portid;
int is_pbm_a, err;
@@ -142,11 +1761,10 @@ void __init schizo_init(int node)
p->resource_adjust = schizo_resource_adjust;
p->pci_ops = &schizo_ops;
-pbm_init:
/* Three OBP regs:
* 1) PBM controller regs
* 2) Schizo front-end controller regs (same for both PBMs)
- * 3) Unknown... (0x7ffec000000 and 0x7ffee000000 on Excalibur)
+ * 3) PBM PCI config space
*/
err = prom_getproperty(node, "reg",
(char *)&pr_regs[0],
@@ -156,14 +1774,16 @@ pbm_init:
prom_halt();
}
- /* XXX Read REG base, record in controller/pbm structures. */
-
- /* XXX Report controller to console. */
+ p->controller_regs = pr_regs[1].phys_addr - 0x10000UL;
+ printk("PCI: Found SCHIZO, control regs at %016lx\n",
+ p->controller_regs);
- /* XXX Setup pci_memspace_mask */
+ /* Like PSYCHO we have a 2GB aligned area for memory space. */
+ pci_memspace_mask = 0x7fffffffUL;
- /* XXX Init core controller and IOMMU */
+ /* Init core controller. */
+ schizo_controller_hwinit(p);
- is_pbm_a = XXX; /* Figure out this test */
+ is_pbm_a = ((pr_regs[0].phys_addr & 0x00700000) == 0x00600000);
schizo_pbm_init(p, node, is_pbm_a);
}
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 3fc337d71..e0930d55e 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.114 2001/02/13 01:16:44 davem Exp $
+/* $Id: process.c,v 1.116 2001/03/24 09:36:01 davem Exp $
* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -416,14 +416,14 @@ void flush_thread(void)
unsigned long pgd_cache;
if (pgd_none(*pgd0)) {
- pmd_t *page = get_pmd_fast();
+ pmd_t *page = pmd_alloc_one_fast(NULL, 0);
if (!page)
- (void) get_pmd_slow(pgd0, 0);
- else
- pgd_set(pgd0, page);
+ page = pmd_alloc_one(NULL, 0);
+ pgd_set(pgd0, page);
}
pgd_cache = pgd_val(*pgd0) << 11UL;
- __asm__ __volatile__("stxa %0, [%1] %2"
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "membar #Sync"
: /* no outputs */
: "r" (pgd_cache),
"r" (TSB_REG),
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index 7f791c4d0..031ec5582 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -53,10 +53,10 @@ static inline void
pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr)
{
if (current->thread.flags & SPARC_FLAG_32BIT) {
- if(put_user(value, (unsigned int *)addr))
+ if (put_user(value, (unsigned int *)addr))
return pt_error_return(regs, EFAULT);
} else {
- if(put_user(value, addr))
+ if (put_user(value, addr))
return pt_error_return(regs, EFAULT);
}
regs->u_regs[UREG_I0] = 0;
@@ -137,7 +137,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
s, request, pid, addr, data, addr2);
}
#endif
- if(request == PTRACE_TRACEME) {
+ if (request == PTRACE_TRACEME) {
/* are we already being traced? */
if (current->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
@@ -149,7 +149,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
goto out;
}
#ifndef ALLOW_INIT_TRACING
- if(pid == 1) {
+ if (pid == 1) {
/* Can't dork with init. */
pt_error_return(regs, EPERM);
goto out;
@@ -157,9 +157,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
#endif
read_lock(&tasklist_lock);
child = find_task_by_pid(pid);
+ if (child)
+ get_task_struct(child);
read_unlock(&tasklist_lock);
- if(!child) {
+ if (!child) {
pt_error_return(regs, ESRCH);
goto out;
}
@@ -168,32 +170,32 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
|| (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
unsigned long flags;
- if(child == current) {
+ if (child == current) {
/* Try this under SunOS/Solaris, bwa haha
* You'll never be able to kill the process. ;-)
*/
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
- if((!child->dumpable ||
- (current->uid != child->euid) ||
- (current->uid != child->uid) ||
- (current->uid != child->suid) ||
- (current->gid != child->egid) ||
- (current->gid != child->sgid) ||
- (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
- (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) {
+ if ((!child->dumpable ||
+ (current->uid != child->euid) ||
+ (current->uid != child->uid) ||
+ (current->uid != child->suid) ||
+ (current->gid != child->egid) ||
+ (current->gid != child->sgid) ||
+ (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
+ (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) {
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
- goto out;
+ goto out_tsk;
}
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
- if(child->p_pptr != current) {
+ if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
@@ -201,32 +203,32 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
write_unlock_irqrestore(&tasklist_lock, flags);
send_sig(SIGSTOP, child, 1);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
if (!(child->ptrace & PT_PTRACED)) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
- if(child->state != TASK_STOPPED) {
- if(request != PTRACE_KILL) {
+ if (child->state != TASK_STOPPED) {
+ if (request != PTRACE_KILL) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
}
- if(child->p_pptr != current) {
+ if (child->p_pptr != current) {
pt_error_return(regs, ESRCH);
- goto out;
+ goto out_tsk;
}
- if(!(child->thread.flags & SPARC_FLAG_32BIT) &&
- ((request == PTRACE_READDATA64) ||
- (request == PTRACE_WRITEDATA64) ||
- (request == PTRACE_READTEXT64) ||
- (request == PTRACE_WRITETEXT64) ||
- (request == PTRACE_PEEKTEXT64) ||
- (request == PTRACE_POKETEXT64) ||
- (request == PTRACE_PEEKDATA64) ||
- (request == PTRACE_POKEDATA64))) {
+ if (!(child->thread.flags & SPARC_FLAG_32BIT) &&
+ ((request == PTRACE_READDATA64) ||
+ (request == PTRACE_WRITEDATA64) ||
+ (request == PTRACE_READTEXT64) ||
+ (request == PTRACE_WRITETEXT64) ||
+ (request == PTRACE_PEEKTEXT64) ||
+ (request == PTRACE_POKETEXT64) ||
+ (request == PTRACE_PEEKDATA64) ||
+ (request == PTRACE_POKEDATA64))) {
addr = regs->u_regs[UREG_G2];
addr2 = regs->u_regs[UREG_G3];
request -= 30; /* wheee... */
@@ -278,7 +280,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
if (copied == sizeof(tmp64))
res = 0;
}
- if(res < 0)
+ if (res < 0)
pt_error_return(regs, -res);
else
pt_succ_return(regs, res);
@@ -295,42 +297,45 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
__put_user(cregs->tnpc, (&pregs->npc)) ||
__put_user(cregs->y, (&pregs->y))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
- for(rval = 1; rval < 16; rval++)
+ for (rval = 1; rval < 16; rval++)
if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
pt_succ_return(regs, 0);
#ifdef DEBUG_PTRACE
printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
#endif
- goto out;
+ goto out_tsk;
}
case PTRACE_GETREGS64: {
struct pt_regs *pregs = (struct pt_regs *) addr;
struct pt_regs *cregs = child->thread.kregs;
+ unsigned long tpc = cregs->tpc;
int rval;
+ if ((child->thread.flags & SPARC_FLAG_32BIT) != 0)
+ tpc &= 0xffffffff;
if (__put_user(cregs->tstate, (&pregs->tstate)) ||
- __put_user(cregs->tpc, (&pregs->tpc)) ||
+ __put_user(tpc, (&pregs->tpc)) ||
__put_user(cregs->tnpc, (&pregs->tnpc)) ||
__put_user(cregs->y, (&pregs->y))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
- for(rval = 1; rval < 16; rval++)
+ for (rval = 1; rval < 16; rval++)
if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
pt_succ_return(regs, 0);
#ifdef DEBUG_PTRACE
printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
#endif
- goto out;
+ goto out_tsk;
}
case PTRACE_SETREGS: {
@@ -347,23 +352,23 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
__get_user(npc, (&pregs->npc)) ||
__get_user(y, (&pregs->y))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
cregs->tstate &= ~(TSTATE_ICC);
cregs->tstate |= psr_to_tstate_icc(psr);
- if(!((pc | npc) & 3)) {
+ if (!((pc | npc) & 3)) {
cregs->tpc = pc;
cregs->tnpc = npc;
}
cregs->y = y;
- for(i = 1; i < 16; i++) {
+ for (i = 1; i < 16; i++) {
if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SETREGS64: {
@@ -380,24 +385,28 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
__get_user(tnpc, (&pregs->tnpc)) ||
__get_user(y, (&pregs->y))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
+ }
+ if ((child->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ tpc &= 0xffffffff;
+ tnpc &= 0xffffffff;
}
tstate &= (TSTATE_ICC | TSTATE_XCC);
cregs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
cregs->tstate |= tstate;
- if(!((tpc | tnpc) & 3)) {
+ if (!((tpc | tnpc) & 3)) {
cregs->tpc = tpc;
cregs->tnpc = tnpc;
}
cregs->y = y;
- for(i = 1; i < 16; i++) {
+ for (i = 1; i < 16; i++) {
if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_GETFPREGS: {
@@ -422,10 +431,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
__put_user(0, (&fps->extra)) ||
clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_GETFPREGS64: {
@@ -439,10 +448,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
(64 * sizeof(unsigned int))) ||
__put_user(child->thread.xfsr[0], (&fps->fsr))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SETFPREGS: {
@@ -464,7 +473,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
(32 * sizeof(unsigned int))) ||
__get_user(fsr, (&fps->fsr))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
child->thread.xfsr[0] &= 0xffffffff00000000UL;
child->thread.xfsr[0] |= fsr;
@@ -472,7 +481,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
child->thread.gsr[0] = 0;
child->thread.fpsaved[0] |= (FPRS_FEF | FPRS_DL);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SETFPREGS64: {
@@ -486,13 +495,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
(64 * sizeof(unsigned int))) ||
__get_user(child->thread.xfsr[0], (&fps->fsr))) {
pt_error_return(regs, EFAULT);
- goto out;
+ goto out_tsk;
}
if (!(child->thread.fpsaved[0] & FPRS_FEF))
child->thread.gsr[0] = 0;
child->thread.fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_READTEXT:
@@ -528,19 +537,24 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
case PTRACE_CONT: { /* restart after signal. */
if (data > _NSIG) {
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
if (addr != 1) {
+ unsigned long pc_mask = ~0UL;
+
+ if ((child->thread.flags & SPARC_FLAG_32BIT) != 0)
+ pc_mask = 0xffffffff;
+
if (addr & 3) {
pt_error_return(regs, EINVAL);
- goto out;
+ goto out_tsk;
}
#ifdef DEBUG_PTRACE
printk ("Original: %016lx %016lx\n", child->thread.kregs->tpc, child->thread.kregs->tnpc);
printk ("Continuing with %016lx %016lx\n", addr, addr+4);
#endif
- child->thread.kregs->tpc = addr;
- child->thread.kregs->tnpc = addr + 4;
+ child->thread.kregs->tpc = (addr & pc_mask);
+ child->thread.kregs->tnpc = ((addr + 4) & pc_mask);
}
if (request == PTRACE_SYSCALL)
@@ -558,7 +572,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
#endif
wake_up_process(child);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/*
@@ -569,12 +583,12 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
case PTRACE_KILL: {
if (child->state == TASK_ZOMBIE) { /* already dead */
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
child->exit_code = SIGKILL;
wake_up_process(child);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
case PTRACE_SUNDETACH: { /* detach a process that was attached. */
@@ -582,7 +596,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
if ((unsigned long) data > _NSIG) {
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
@@ -595,29 +609,39 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
wake_up_process(child);
pt_succ_return(regs, 0);
- goto out;
+ goto out_tsk;
}
/* PTRACE_DUMPCORE unsupported... */
default:
pt_error_return(regs, EIO);
- goto out;
+ goto out_tsk;
}
flush_and_out:
{
unsigned long va;
- for(va = 0; va < (PAGE_SIZE << 1); va += 32)
- spitfire_put_dcache_tag(va, 0x0);
- if (request == PTRACE_PEEKTEXT ||
- request == PTRACE_POKETEXT ||
- request == PTRACE_READTEXT ||
- request == PTRACE_WRITETEXT) {
- for(va = 0; va < (PAGE_SIZE << 1); va += 32)
- spitfire_put_icache_tag(va, 0x0);
- __asm__ __volatile__("flush %g6");
+
+ if (tlb_type == cheetah) {
+ for (va = 0; va < (1 << 16); va += (1 << 5))
+ spitfire_put_dcache_tag(va, 0x0);
+ /* No need to mess with I-cache on Cheetah. */
+ } else {
+ for (va = 0; va < (PAGE_SIZE << 1); va += 32)
+ spitfire_put_dcache_tag(va, 0x0);
+ if (request == PTRACE_PEEKTEXT ||
+ request == PTRACE_POKETEXT ||
+ request == PTRACE_READTEXT ||
+ request == PTRACE_WRITETEXT) {
+ for (va = 0; va < (PAGE_SIZE << 1); va += 32)
+ spitfire_put_icache_tag(va, 0x0);
+ __asm__ __volatile__("flush %g6");
+ }
}
}
+out_tsk:
+ if (child)
+ free_task_struct(child);
out:
unlock_kernel();
}
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index 729ecd911..952f0caa5 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.53 2000/08/06 05:20:35 davem Exp $
+/* $Id: rtrap.S,v 1.54 2001/03/08 22:08:51 davem Exp $
* rtrap.S: Preparing for return from trap on Sparc V9.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -192,7 +192,7 @@ to_kernel: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5
rd %fprs, %g5
wr %g5, FPRS_FEF, %fprs
- ldub [%o1 + %o0], %g5
+ ldx [%o1 + %o5], %g5
add %g6, AOFF_task_thread + AOFF_thread_xfsr, %o1
membar #StoreLoad | #LoadLoad
sll %o0, 8, %o2
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 7817f4566..cf6bbb896 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.59 2001/02/13 01:16:44 davem Exp $
+/* $Id: setup.c,v 1.63 2001/03/09 22:04:25 davem Exp $
* linux/arch/sparc64/kernel/setup.c
*
* Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
@@ -43,8 +43,6 @@
#include <net/ipconfig.h>
#endif
-#undef PROM_DEBUG_CONSOLE
-
struct screen_info screen_info = {
0, 0, /* orig-x, orig-y */
0, /* unused */
@@ -166,10 +164,14 @@ int prom_callback(long *args)
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
/*
- * Locked down tlb entry 63.
+ * Locked down tlb entry.
*/
- tte = spitfire_get_dtlb_data(63);
+ if (tlb_type == spitfire)
+ tte = spitfire_get_dtlb_data(SPITFIRE_HIGHEST_LOCKED_TLBENT);
+ else if (tlb_type == cheetah)
+ tte = cheetah_get_ldtlb_data(CHEETAH_HIGHEST_LOCKED_TLBENT);
+
res = PROM_TRUE;
goto done;
}
@@ -253,7 +255,7 @@ int prom_callback(long *args)
unsigned long tte;
tte = args[3];
- prom_printf("%lx ", (tte & _PAGE_SOFT2) >> 50);
+ prom_printf("%lx ", (tte & 0x07FC000000000000) >> 50);
args[2] = 2;
args[args[1] + 3] = 0;
@@ -285,14 +287,12 @@ static int console_fb __initdata = 0;
/* Exported for mm/init.c:paging_init. */
unsigned long cmdline_memory_size = 0;
-#ifdef PROM_DEBUG_CONSOLE
static struct console prom_debug_console = {
name: "debug",
write: prom_console_write,
flags: CON_PRINTBUFFER,
index: -1,
};
-#endif
/* XXX Implement this at some point... */
void kernel_enter_debugger(void)
@@ -326,6 +326,10 @@ static void __init process_switch(char c)
prom_printf("boot_flags_init: Halt!\n");
prom_halt();
break;
+ case 'p':
+ /* Use PROM debug console. */
+ register_console(&prom_debug_console);
+ break;
default:
printk("Unknown boot switch (-%c)\n", c);
break;
@@ -454,10 +458,6 @@ void __init setup_arch(char **cmdline_p)
*cmdline_p = prom_getbootargs();
strcpy(saved_command_line, *cmdline_p);
-#ifdef PROM_DEBUG_CONSOLE
- register_console(&prom_debug_console);
-#endif
-
printk("ARCH: SUN4U\n");
#ifdef CONFIG_DUMMY_CONSOLE
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 23d0774b4..354021278 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.55 2001/01/24 21:05:13 davem Exp $
+/* $Id: signal.c,v 1.56 2001/03/21 11:46:20 davem Exp $
* arch/sparc64/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -108,6 +108,10 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
}
+ if ((tp->flags & SPARC_FLAG_32BIT) != 0) {
+ pc &= 0xffffffff;
+ npc &= 0xffffffff;
+ }
regs->tpc = pc;
regs->tnpc = npc;
err |= __get_user(regs->y, &((*grp)[MC_Y]));
@@ -190,9 +194,13 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs)
grp = &mcp->mc_gregs;
/* Skip over the trap instruction, first. */
- regs->tpc = regs->tnpc;
- regs->tnpc += 4;
-
+ if ((tp->flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc = (regs->tnpc & 0xffffffff);
+ regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
+ } else {
+ regs->tpc = regs->tnpc;
+ regs->tnpc += 4;
+ }
err = 0;
if (_NSIG_WORDS == 1)
err |= __put_user(current->blocked.sig[0],
@@ -289,8 +297,13 @@ asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
- regs->tpc = regs->tnpc;
- regs->tnpc += 4;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc = (regs->tnpc & 0xffffffff);
+ regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
+ } else {
+ regs->tpc = regs->tnpc;
+ regs->tnpc += 4;
+ }
/* Condition codes and return value where set here for sigpause,
* and so got used by setup_frame, which again causes sigreturn()
@@ -344,8 +357,13 @@ asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize, struct pt_re
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
- regs->tpc = regs->tnpc;
- regs->tnpc += 4;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc = (regs->tnpc & 0xffffffff);
+ regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
+ } else {
+ regs->tpc = regs->tnpc;
+ regs->tnpc += 4;
+ }
/* Condition codes and return value where set here for sigpause,
* and so got used by setup_frame, which again causes sigreturn()
@@ -407,6 +425,10 @@ void do_rt_sigreturn(struct pt_regs *regs)
err = get_user(tpc, &sf->regs.tpc);
err |= __get_user(tnpc, &sf->regs.tnpc);
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ tpc &= 0xffffffff;
+ tnpc &= 0xffffffff;
+ }
err |= ((tpc | tnpc) & 3);
/* 2. Restore the state */
@@ -555,7 +577,10 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
/* 5. signal handler */
regs->tpc = (unsigned long) ka->sa.sa_handler;
regs->tnpc = (regs->tpc + 4);
-
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
/* 4. return to kernel instructions */
regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
return;
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 0886d9d39..9613c7869 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/* $Id: signal32.c,v 1.68 2001/01/24 21:05:13 davem Exp $
+/* $Id: signal32.c,v 1.69 2001/03/21 11:46:20 davem Exp $
* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -155,6 +155,10 @@ asmlinkage void _sigpause32_common(old_sigset_t32 set, struct pt_regs *regs)
regs->tpc = regs->tnpc;
regs->tnpc += 4;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
/* Condition codes and return value where set here for sigpause,
* and so got used by setup_frame, which again causes sigreturn()
@@ -206,6 +210,10 @@ asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *
regs->tpc = regs->tnpc;
regs->tnpc += 4;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
/* Condition codes and return value where set here for sigpause,
* and so got used by setup_frame, which again causes sigreturn()
@@ -268,6 +276,10 @@ void do_new_sigreturn32(struct pt_regs *regs)
if ((pc | npc) & 3)
goto segv;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ pc &= 0xffffffff;
+ npc &= 0xffffffff;
+ }
regs->tpc = pc;
regs->tnpc = npc;
@@ -355,6 +367,10 @@ asmlinkage void do_sigreturn32(struct pt_regs *regs)
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ pc &= 0xffffffff;
+ npc &= 0xffffffff;
+ }
regs->tpc = pc;
regs->tnpc = npc;
err = __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp);
@@ -398,6 +414,10 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
if ((pc | npc) & 3)
goto segv;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ pc &= 0xffffffff;
+ npc &= 0xffffffff;
+ }
regs->tpc = pc;
regs->tnpc = npc;
@@ -489,6 +509,11 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
#endif
unsigned psr;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ pc &= 0xffffffff;
+ npc &= 0xffffffff;
+ }
+
synchronize_user_stack();
save_and_clear_fpu();
@@ -615,6 +640,10 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
regs->u_regs[UREG_FP] = (unsigned long) sframep;
regs->tpc = (unsigned long) sa->sa_handler;
regs->tnpc = (regs->tpc + 4);
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
return;
sigsegv:
@@ -678,6 +707,10 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg
}
/* 2. Save the current process state */
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
err = put_user(regs->tpc, &sf->info.si_regs.pc);
err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
err |= __put_user(regs->y, &sf->info.si_regs.y);
@@ -728,11 +761,15 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg
/* 4. signal handler */
regs->tpc = (unsigned long) ka->sa.sa_handler;
regs->tnpc = (regs->tpc + 4);
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
/* 5. return to kernel instructions */
- if (ka->ka_restorer)
+ if (ka->ka_restorer) {
regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
- else {
+ } else {
/* Flush instruction space. */
unsigned long address = ((unsigned long)&(sf->insns[0]));
pgd_t *pgdp = pgd_offset(current->mm, address);
@@ -819,6 +856,10 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
/* Store registers */
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
err |= __put_user(regs->tpc, &((*gr) [SVR4_PC]));
err |= __put_user(regs->tnpc, &((*gr) [SVR4_NPC]));
psr = tstate_to_psr (regs->tstate);
@@ -883,6 +924,10 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->u_regs[UREG_FP] = (unsigned long) sfp;
regs->tpc = (unsigned long) sa->sa_handler;
regs->tnpc = (regs->tpc + 4);
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
#ifdef DEBUG_SIGNALS
printk ("Solaris-frame: %x %x\n", (int) regs->tpc, (int) regs->tnpc);
@@ -940,6 +985,10 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
/* Store registers */
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
err |= __put_user(regs->tpc, &uc->mcontext.greg [SVR4_PC]);
err |= __put_user(regs->tnpc, &uc->mcontext.greg [SVR4_NPC]);
#if 1
@@ -1037,6 +1086,10 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
spin_unlock_irq(&current->sigmask_lock);
regs->tpc = pc;
regs->tnpc = npc | 1;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
err |= __get_user(regs->y, &((*gr) [SVR4_Y]));
err |= __get_user(psr, &((*gr) [SVR4_PSR]));
regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
@@ -1095,6 +1148,10 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs
}
/* 2. Save the current process state */
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
err = put_user(regs->tpc, &sf->regs.pc);
err |= __put_user(regs->tnpc, &sf->regs.npc);
err |= __put_user(regs->y, &sf->regs.y);
@@ -1150,6 +1207,10 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs
/* 4. signal handler */
regs->tpc = (unsigned long) ka->sa.sa_handler;
regs->tnpc = (regs->tpc + 4);
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
/* 5. return to kernel instructions */
if (ka->ka_restorer)
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 76045d0d2..bceac6597 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -65,7 +65,7 @@ int smp_info(char *buf)
strcpy(buf, "State:\n");
for (i = 0; i < NR_CPUS; i++)
- if(cpu_present_map & (1UL << i))
+ if (cpu_present_map & (1UL << i))
len += sprintf(buf + len,
"CPU%d:\t\tonline\n", i);
return len;
@@ -76,7 +76,7 @@ int smp_bogo(char *buf)
int len = 0, i;
for (i = 0; i < NR_CPUS; i++)
- if(cpu_present_map & (1UL << i))
+ if (cpu_present_map & (1UL << i))
len += sprintf(buf + len,
"Cpu%dBogo\t: %lu.%02lu\n",
i, cpu_data[i].udelay_val / (500000/HZ),
@@ -99,7 +99,7 @@ void __init smp_store_cpu_info(int id)
cpu_data[id].pgd_cache = NULL;
cpu_data[id].idle_volume = 1;
- for(i = 0; i < 16; i++)
+ for (i = 0; i < 16; i++)
cpu_data[id].irq_worklists[i] = 0;
}
@@ -153,6 +153,19 @@ void __init smp_callin(void)
: /* no inputs */
: "g1", "g2");
+ if (SPARC64_USE_STICK) {
+ /* Let the user get at STICK too. */
+ __asm__ __volatile__("
+ sethi %%hi(0x80000000), %%g1
+ sllx %%g1, 32, %%g1
+ rd %%asr24, %%g2
+ andn %%g2, %%g1, %%g2
+ wr %%g2, 0, %%asr24"
+ : /* no outputs */
+ : /* no inputs */
+ : "g1", "g2");
+ }
+
/* Restore PSTATE_IE. */
__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
: /* no outputs */
@@ -177,7 +190,7 @@ void __init smp_callin(void)
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
- while(!smp_processors_ready)
+ while (!smp_processors_ready)
membar("#LoadLoad");
}
@@ -222,14 +235,14 @@ void __init smp_boot_cpus(void)
smp_tune_scheduling();
init_idle();
- if(linux_num_cpus == 1)
+ if (linux_num_cpus == 1)
return;
- for(i = 0; i < NR_CPUS; i++) {
- if(i == boot_cpu_id)
+ for (i = 0; i < NR_CPUS; i++) {
+ if (i == boot_cpu_id)
continue;
- if(cpu_present_map & (1UL << i)) {
+ if (cpu_present_map & (1UL << i)) {
unsigned long entry = (unsigned long)(&sparc64_cpu_startup);
unsigned long cookie = (unsigned long)(&cpu_new_task);
struct task_struct *p;
@@ -256,12 +269,12 @@ void __init smp_boot_cpus(void)
cpu_new_task = p;
prom_startcpu(linux_cpus[no].prom_node,
entry, cookie);
- for(timeout = 0; timeout < 5000000; timeout++) {
- if(callin_flag)
+ for (timeout = 0; timeout < 5000000; timeout++) {
+ if (callin_flag)
break;
udelay(100);
}
- if(callin_flag) {
+ if (callin_flag) {
__cpu_number_map[i] = cpucount;
__cpu_logical_map[cpucount] = i;
prom_cpu_nodes[i] = linux_cpus[no].prom_node;
@@ -272,20 +285,20 @@ void __init smp_boot_cpus(void)
prom_printf("FAILED\n");
}
}
- if(!callin_flag) {
+ if (!callin_flag) {
cpu_present_map &= ~(1UL << i);
__cpu_number_map[i] = -1;
}
}
cpu_new_task = NULL;
- if(cpucount == 0) {
+ if (cpucount == 0) {
printk("Error: only one processor found.\n");
cpu_present_map = (1UL << smp_processor_id());
} else {
unsigned long bogosum = 0;
- for(i = 0; i < NR_CPUS; i++) {
- if(cpu_present_map & (1UL << i))
+ for (i = 0; i < NR_CPUS; i++) {
+ if (cpu_present_map & (1UL << i))
bogosum += cpu_data[i].udelay_val;
}
printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
@@ -299,9 +312,7 @@ void __init smp_boot_cpus(void)
membar("#StoreStore | #StoreLoad");
}
-/* #define XCALL_DEBUG */
-
-static inline void xcall_deliver(u64 data0, u64 data1, u64 data2, u64 pstate, unsigned long cpu)
+static void spitfire_xcall_helper(u64 data0, u64 data1, u64 data2, u64 pstate, unsigned long cpu)
{
u64 result, target;
int stuck, tmp;
@@ -314,10 +325,6 @@ static inline void xcall_deliver(u64 data0, u64 data1, u64 data2, u64 pstate, un
}
target = (cpu << 14) | 0x70;
-#ifdef XCALL_DEBUG
- printk("CPU[%d]: xcall(data[%016lx:%016lx:%016lx],tgt[%016lx])\n",
- smp_processor_id(), data0, data1, data2, target);
-#endif
again:
/* Ok, this is the real Spitfire Errata #54.
* One must read back from a UDB internal register
@@ -340,7 +347,7 @@ again:
ldxa [%%g1] 0x7f, %%g0
membar #Sync"
: "=r" (tmp)
- : "r" (pstate), "i" (PSTATE_IE), "i" (ASI_UDB_INTR_W),
+ : "r" (pstate), "i" (PSTATE_IE), "i" (ASI_INTR_W),
"r" (data0), "r" (data1), "r" (data2), "r" (target), "r" (0x10), "0" (tmp)
: "g1");
@@ -350,46 +357,155 @@ again:
__asm__ __volatile__("ldxa [%%g0] %1, %0"
: "=r" (result)
: "i" (ASI_INTR_DISPATCH_STAT));
- if(result == 0) {
+ if (result == 0) {
__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
: : "r" (pstate));
return;
}
stuck -= 1;
- if(stuck == 0)
+ if (stuck == 0)
break;
- } while(result & 0x1);
+ } while (result & 0x1);
__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
: : "r" (pstate));
- if(stuck == 0) {
-#ifdef XCALL_DEBUG
+ if (stuck == 0) {
printk("CPU[%d]: mondo stuckage result[%016lx]\n",
smp_processor_id(), result);
-#endif
} else {
-#ifdef XCALL_DEBUG
- printk("CPU[%d]: Penguin %d NACK's master.\n", smp_processor_id(), cpu);
-#endif
udelay(2);
goto again;
}
}
-void smp_cross_call(unsigned long *func, u32 ctx, u64 data1, u64 data2)
+static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, unsigned long mask)
{
- if(smp_processors_ready) {
- unsigned long mask = (cpu_present_map & ~(1UL<<smp_processor_id()));
- u64 pstate, data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff));
+ int ncpus = smp_num_cpus - 1;
+ int i;
+ u64 pstate;
+
+ __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
+ for (i = 0; (i < NR_CPUS) && ncpus; i++) {
+ if (mask & (1UL << i)) {
+ spitfire_xcall_helper(data0, data1, data2, pstate, i);
+ ncpus--;
+ }
+ }
+}
+
+/* Cheetah now allows to send the whole 64-bytes of data in the interrupt
+ * packet, but we have no use for that. However we do take advantage of
+ * the new pipelining feature (ie. dispatch to multiple cpus simultaneously).
+ */
+#if NR_CPUS > 32
+#error Fixup cheetah_xcall_deliver Dave...
+#endif
+static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, unsigned long mask)
+{
+ u64 pstate;
+ int nack_busy_id;
+
+ if (!mask)
+ return;
+
+ __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
+
+retry:
+ __asm__ __volatile__("wrpr %0, %1, %%pstate\n\t"
+ : : "r" (pstate), "i" (PSTATE_IE));
+
+ /* Setup the dispatch data registers. */
+ __asm__ __volatile__("stxa %0, [%3] %6\n\t"
+ "membar #Sync\n\t"
+ "stxa %1, [%4] %6\n\t"
+ "membar #Sync\n\t"
+ "stxa %2, [%5] %6\n\t"
+ "membar #Sync\n\t"
+ : /* no outputs */
+ : "r" (data0), "r" (data1), "r" (data2),
+ "r" (0x40), "r" (0x50), "r" (0x60),
+ "i" (ASI_INTR_W));
+
+ nack_busy_id = 0;
+ {
int i, ncpus = smp_num_cpus - 1;
- __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
- for(i = 0; i < NR_CPUS; i++) {
- if(mask & (1UL << i)) {
- xcall_deliver(data0, data1, data2, pstate, i);
+ for (i = 0; (i < NR_CPUS) && ncpus; i++) {
+ if (mask & (1UL << i)) {
+ u64 target = (i << 14) | 0x70;
+
+ target |= (nack_busy_id++ << 24);
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync\n\t"
+ : /* no outputs */
+ : "r" (target), "i" (ASI_INTR_W));
ncpus--;
}
- if (!ncpus) break;
}
+ }
+
+ /* Now, poll for completion. */
+ {
+ u64 dispatch_stat;
+ long stuck;
+
+ stuck = 100000 * nack_busy_id;
+ do {
+ __asm__ __volatile__("ldxa [%%g0] %1, %0"
+ : "=r" (dispatch_stat)
+ : "i" (ASI_INTR_DISPATCH_STAT));
+ if (dispatch_stat == 0UL) {
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
+ : : "r" (pstate));
+ return;
+ }
+ if (!--stuck)
+ break;
+ } while (dispatch_stat & 0x5555555555555555UL);
+
+ __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
+ : : "r" (pstate));
+
+ if ((stuck & ~(0x5555555555555555UL)) == 0) {
+ /* Busy bits will not clear, continue instead
+ * of freezing up on this cpu.
+ */
+ printk("CPU[%d]: mondo stuckage result[%016lx]\n",
+ smp_processor_id(), dispatch_stat);
+ } else {
+ int i, this_busy_nack = 0;
+
+ /* Delay some random time with interrupts enabled
+ * to prevent deadlock.
+ */
+ udelay(2 * nack_busy_id);
+
+ /* Clear out the mask bits for cpus which did not
+ * NACK us.
+ */
+ for (i = 0; i < NR_CPUS; i++) {
+ if (mask & (1UL << i)) {
+ if ((dispatch_stat & (0x2 << this_busy_nack)) == 0)
+ mask &= ~(1UL << i);
+ this_busy_nack += 2;
+ }
+ }
+
+ goto retry;
+ }
+ }
+}
+
+void smp_cross_call(unsigned long *func, u32 ctx, u64 data1, u64 data2)
+{
+ if (smp_processors_ready) {
+ unsigned long mask = (cpu_present_map & ~(1UL<<smp_processor_id()));
+ u64 data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff));
+
+ if (tlb_type == spitfire)
+ spitfire_xcall_deliver(data0, data1, data2, mask);
+ else
+ cheetah_xcall_deliver(data0, data1, data2, mask);
+
/* NOTE: Caller runs local copy on master. */
}
}
@@ -445,11 +561,17 @@ extern unsigned long xcall_receive_signal;
void smp_receive_signal(int cpu)
{
- if(smp_processors_ready &&
- (cpu_present_map & (1UL<<cpu)) != 0) {
- u64 pstate, data0 = (((u64)&xcall_receive_signal) & 0xffffffff);
- __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
- xcall_deliver(data0, 0, 0, pstate, cpu);
+ if (smp_processors_ready) {
+ unsigned long mask = 1UL << cpu;
+
+ if ((cpu_present_map & mask) != 0) {
+ u64 data0 = (((u64)&xcall_receive_signal) & 0xffffffff);
+
+ if (tlb_type == spitfire)
+ spitfire_xcall_deliver(data0, 0, 0, mask);
+ else
+ cheetah_xcall_deliver(data0, 0, 0, mask);
+ }
}
}
@@ -609,7 +731,7 @@ void smp_capture(void)
int result = __atomic_add(1, &smp_capture_depth);
membar("#StoreStore | #LoadStore");
- if(result == 1) {
+ if (result == 1) {
int ncpus = smp_num_cpus;
#ifdef CAPTURE_DEBUG
@@ -620,7 +742,7 @@ void smp_capture(void)
membar("#StoreStore | #LoadStore");
atomic_inc(&smp_capture_registry);
smp_cross_call(&xcall_capture, 0, 0, 0);
- while(atomic_read(&smp_capture_registry) != ncpus)
+ while (atomic_read(&smp_capture_registry) != ncpus)
membar("#LoadLoad");
#ifdef CAPTURE_DEBUG
printk("done\n");
@@ -631,8 +753,8 @@ void smp_capture(void)
void smp_release(void)
{
- if(smp_processors_ready) {
- if(atomic_dec_and_test(&smp_capture_depth)) {
+ if (smp_processors_ready) {
+ if (atomic_dec_and_test(&smp_capture_depth)) {
#ifdef CAPTURE_DEBUG
printk("CPU[%d]: Giving pardon to imprisoned penguins\n",
smp_processor_id());
@@ -659,7 +781,7 @@ void smp_penguin_jailcell(void)
prom_world(1);
atomic_inc(&smp_capture_registry);
membar("#StoreLoad | #StoreStore");
- while(penguins_are_doing_time)
+ while (penguins_are_doing_time)
membar("#LoadLoad");
restore_alternate_globals(global_save);
atomic_dec(&smp_capture_registry);
@@ -690,14 +812,23 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs)
/*
* Check for level 14 softint.
*/
- if (!(get_softint() & (1UL << 0))) {
- extern void handler_irq(int, struct pt_regs *);
+ {
+ unsigned long tick_mask;
- handler_irq(14, regs);
- return;
+ if (SPARC64_USE_STICK)
+ tick_mask = (1UL << 16);
+ else
+ tick_mask = (1UL << 0);
+
+ if (!(get_softint() & tick_mask)) {
+ extern void handler_irq(int, struct pt_regs *);
+
+ handler_irq(14, regs);
+ return;
+ }
+ clear_softint(tick_mask);
}
- clear_softint((1UL << 0));
do {
if (!user)
sparc64_do_profile(regs->tpc, regs->u_regs[UREG_RETPC]);
@@ -740,6 +871,7 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs)
* that %tick is not prone to this bug, but I am not
* taking any chances.
*/
+ if (!SPARC64_USE_STICK) {
__asm__ __volatile__("rd %%tick_cmpr, %0\n\t"
"ba,pt %%xcc, 1f\n\t"
" add %0, %2, %0\n\t"
@@ -750,6 +882,14 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs)
"mov %1, %1"
: "=&r" (compare), "=r" (tick)
: "r" (current_tick_offset));
+ } else {
+ __asm__ __volatile__("rd %%asr25, %0\n\t"
+ "add %0, %2, %0\n\t"
+ "wr %0, 0x0, %%asr25\n\t"
+ "rd %%asr24, %1\n\t"
+ : "=&r" (compare), "=r" (tick)
+ : "r" (current_tick_offset));
+ }
/* Restore PSTATE_IE. */
__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
@@ -782,6 +922,7 @@ static void __init smp_setup_percpu_timer(void)
* at the start of an I-cache line, and perform a dummy
* read back from %tick_cmpr right after writing to it. -DaveM
*/
+ if (!SPARC64_USE_STICK) {
__asm__ __volatile__("
rd %%tick, %%g1
ba,pt %%xcc, 1f
@@ -792,6 +933,15 @@ static void __init smp_setup_percpu_timer(void)
: /* no outputs */
: "r" (current_tick_offset)
: "g1");
+ } else {
+ __asm__ __volatile__("
+ rd %%asr24, %%g1
+ add %%g1, %0, %%g1
+ wr %%g1, 0x0, %%asr25"
+ : /* no outputs */
+ : "r" (current_tick_offset)
+ : "g1");
+ }
/* Restore PSTATE_IE. */
__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
@@ -806,9 +956,9 @@ void __init smp_tick_init(void)
boot_cpu_id = hard_smp_processor_id();
current_tick_offset = timer_tick_offset;
cpu_present_map = 0;
- for(i = 0; i < linux_num_cpus; i++)
+ for (i = 0; i < linux_num_cpus; i++)
cpu_present_map |= (1UL << linux_cpus[i].mid);
- for(i = 0; i < NR_CPUS; i++) {
+ for (i = 0; i < NR_CPUS; i++) {
__cpu_number_map[i] = -1;
__cpu_logical_map[i] = -1;
}
@@ -827,11 +977,11 @@ static inline unsigned long find_flush_base(unsigned long size)
size = PAGE_ALIGN(size);
found = size;
base = (unsigned long) page_address(p);
- while(found != 0) {
+ while (found != 0) {
/* Failure. */
- if(p >= (mem_map + max_mapnr))
+ if (p >= (mem_map + max_mapnr))
return 0UL;
- if(PageReserved(p)) {
+ if (PageReserved(p)) {
found = size;
base = (unsigned long) page_address(p);
} else {
@@ -924,12 +1074,12 @@ int setup_profiling_timer(unsigned int multiplier)
unsigned long flags;
int i;
- if((!multiplier) || (timer_tick_offset / multiplier) < 1000)
+ if ((!multiplier) || (timer_tick_offset / multiplier) < 1000)
return -EINVAL;
save_and_cli(flags);
- for(i = 0; i < NR_CPUS; i++) {
- if(cpu_present_map & (1UL << i))
+ for (i = 0; i < NR_CPUS; i++) {
+ if (cpu_present_map & (1UL << i))
prof_multiplier(i) = multiplier;
}
current_tick_offset = (timer_tick_offset / multiplier);
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index f35e38a5d..2dc8ddb4f 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.100 2001/01/11 15:07:09 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.102 2001/03/24 09:36:01 davem Exp $
* arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -179,6 +179,8 @@ EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(__flushw_user);
+EXPORT_SYMBOL(tlb_type);
+
EXPORT_SYMBOL(flush_icache_range);
EXPORT_SYMBOL(__flush_dcache_page);
@@ -232,8 +234,7 @@ EXPORT_SYMBOL(_sigpause_common);
/* Should really be in linux/kernel/ksyms.c */
EXPORT_SYMBOL(dump_thread);
EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(get_pmd_slow);
-EXPORT_SYMBOL(get_pte_slow);
+EXPORT_SYMBOL(pte_alloc_one);
#ifndef CONFIG_SMP
EXPORT_SYMBOL(pgt_quicklists);
#endif
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index e3cd81c97..16c9e7e19 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.48 2001/02/13 01:16:44 davem Exp $
+/* $Id: sys_sparc.c,v 1.50 2001/03/24 09:36:10 davem Exp $
* linux/arch/sparc64/kernel/sys_sparc.c
*
* This file contains various random system calls that
@@ -243,9 +243,9 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
if (flags & MAP_SHARED)
current->thread.flags |= SPARC_FLAG_MMAPSHARED;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
retval = do_mmap(file, addr, len, prot, flags, off);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED);
@@ -263,9 +263,9 @@ asmlinkage long sys64_munmap(unsigned long addr, size_t len)
if (len > -PAGE_OFFSET ||
(addr < PAGE_OFFSET && addr + len > -PAGE_OFFSET))
return -EINVAL;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
ret = do_munmap(current->mm, addr, len);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
return ret;
}
@@ -285,7 +285,7 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr,
goto out;
if (addr < PAGE_OFFSET && addr + old_len > -PAGE_OFFSET)
goto out;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
vma = find_vma(current->mm, addr);
if (vma && (vma->vm_flags & VM_SHARED))
current->thread.flags |= SPARC_FLAG_MMAPSHARED;
@@ -305,7 +305,7 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr,
ret = do_mremap(addr, old_len, new_len, flags, new_addr);
out_sem:
current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
out:
return ret;
}
@@ -335,6 +335,10 @@ sparc_breakpoint (struct pt_regs *regs)
{
siginfo_t info;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
#ifdef DEBUG_SPARC_BREAKPOINT
printk ("TRAP: Entering kernel PC=%lx, nPC=%lx\n", regs->tpc, regs->tnpc);
#endif
@@ -384,6 +388,10 @@ asmlinkage int solaris_syscall(struct pt_regs *regs)
regs->tpc = regs->tnpc;
regs->tnpc += 4;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
if(++count <= 5) {
printk ("For Solaris binary emulation you need solaris module loaded\n");
show_regs (regs);
@@ -400,6 +408,10 @@ asmlinkage int sunos_syscall(struct pt_regs *regs)
regs->tpc = regs->tnpc;
regs->tnpc += 4;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
if(++count <= 20)
printk ("SunOS binary emulation not compiled in\n");
force_sig(SIGSEGV, current);
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index d68b75cab..571826a12 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.173 2001/02/13 01:16:44 davem Exp $
+/* $Id: sys_sparc32.c,v 1.174 2001/03/24 09:36:10 davem Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -4133,7 +4133,7 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr,
goto out;
if (addr > 0xf0000000UL - old_len)
goto out;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
vma = find_vma(current->mm, addr);
if (vma && (vma->vm_flags & VM_SHARED))
current->thread.flags |= SPARC_FLAG_MMAPSHARED;
@@ -4152,7 +4152,7 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr,
ret = do_mremap(addr, old_len, new_len, flags, new_addr);
out_sem:
current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
out:
return ret;
}
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index bfbd8841c..a51b69783 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos32.c,v 1.57 2001/02/13 01:16:44 davem Exp $
+/* $Id: sys_sunos32.c,v 1.59 2001/03/24 09:36:11 davem Exp $
* sys_sunos32.c: SunOS binary compatability layer on sparc64.
*
* Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -100,12 +100,12 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of
flags &= ~_MAP_NEW;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
retval = do_mmap(file,
(unsigned long) addr, (unsigned long) len,
(unsigned long) prot, (unsigned long) flags,
(unsigned long) off);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if(!ret_type)
retval = ((retval < 0xf0000000) ? 0 : retval);
out_putf:
@@ -126,7 +126,7 @@ asmlinkage int sunos_brk(u32 baddr)
unsigned long rlim;
unsigned long newbrk, oldbrk, brk = (unsigned long) baddr;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
if (brk < current->mm->end_code)
goto out;
newbrk = PAGE_ALIGN(brk);
@@ -170,7 +170,7 @@ asmlinkage int sunos_brk(u32 baddr)
do_brk(oldbrk, newbrk-oldbrk);
retval = 0;
out:
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
return retval;
}
@@ -456,6 +456,10 @@ asmlinkage int sunos_nosys(void)
static int cnt;
regs = current->thread.kregs;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
info.si_signo = SIGSYS;
info.si_errno = 0;
info.si_code = __SI_FAULT|0x100;
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index a3340f54a..f369368d2 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.33 2001/01/11 15:07:09 davem Exp $
+/* $Id: time.c,v 1.36 2001/03/15 08:51:24 anton Exp $
* time.c: UltraSparc timer and TOD clock support.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -20,6 +20,8 @@
#include <linux/timex.h>
#include <linux/init.h>
#include <linux/ioport.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
#include <asm/oplib.h>
#include <asm/mostek.h>
@@ -35,7 +37,11 @@
extern rwlock_t xtime_lock;
spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
unsigned long mstk48t02_regs = 0UL;
+#ifdef CONFIG_PCI
+unsigned long ds1287_regs = 0UL;
+#endif
static unsigned long mstk48t08_regs = 0UL;
static unsigned long mstk48t59_regs = 0UL;
@@ -77,6 +83,7 @@ void sparc64_do_profile(unsigned long pc, unsigned long o7)
extern int rwlock_impl_begin, rwlock_impl_end;
extern int atomic_impl_begin, atomic_impl_end;
extern int __memcpy_begin, __memcpy_end;
+ extern int __bzero_begin, __bzero_end;
extern int __bitops_begin, __bitops_end;
if ((pc >= (unsigned long) &atomic_impl_begin &&
@@ -85,6 +92,8 @@ void sparc64_do_profile(unsigned long pc, unsigned long o7)
pc < (unsigned long) &rwlock_impl_end) ||
(pc >= (unsigned long) &__memcpy_begin &&
pc < (unsigned long) &__memcpy_end) ||
+ (pc >= (unsigned long) &__bzero_begin &&
+ pc < (unsigned long) &__bzero_end) ||
(pc >= (unsigned long) &__bitops_begin &&
pc < (unsigned long) &__bitops_end))
pc = o7;
@@ -135,6 +144,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
* that %tick is not prone to this bug, but I am not
* taking any chances.
*/
+ if (!SPARC64_USE_STICK) {
__asm__ __volatile__("
rd %%tick_cmpr, %0
ba,pt %%xcc, 1f
@@ -146,6 +156,15 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
mov %1, %1"
: "=&r" (timer_tick_compare), "=r" (ticks)
: "r" (timer_tick_offset));
+ } else {
+ __asm__ __volatile__("
+ rd %%asr25, %0
+ add %0, %2, %0
+ wr %0, 0, %%asr25
+ rd %%asr24, %1"
+ : "=&r" (timer_tick_compare), "=r" (ticks)
+ : "r" (timer_tick_offset));
+ }
/* Restore PSTATE_IE. */
__asm__ __volatile__("wrpr %0, 0x0, %%pstate"
@@ -168,11 +187,19 @@ void timer_tick_interrupt(struct pt_regs *regs)
/*
* Only keep timer_tick_offset uptodate, but don't set TICK_CMPR.
*/
+ if (!SPARC64_USE_STICK) {
__asm__ __volatile__("
rd %%tick_cmpr, %0
add %0, %1, %0"
: "=&r" (timer_tick_compare)
: "r" (timer_tick_offset));
+ } else {
+ __asm__ __volatile__("
+ rd %%asr25, %0
+ add %0, %1, %0"
+ : "=&r" (timer_tick_compare)
+ : "r" (timer_tick_offset));
+ }
timer_check_rtc();
@@ -282,41 +309,95 @@ static int __init has_low_battery(void)
return (data1 == data2); /* Was the write blocked? */
}
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
+#endif
/* Probe for the real time clock chip. */
static void __init set_system_time(void)
{
unsigned int year, mon, day, hour, min, sec;
unsigned long mregs = mstk48t02_regs;
+#ifdef CONFIG_PCI
+ unsigned long dregs = ds1287_regs;
+#else
+ unsigned long dregs = 0UL;
+#endif
u8 tmp;
do_get_fast_time = do_gettimeofday;
- if(!mregs) {
+ if (!mregs && !dregs) {
prom_printf("Something wrong, clock regs not mapped yet.\n");
prom_halt();
}
- spin_lock_irq(&mostek_lock);
+ if (mregs) {
+ spin_lock_irq(&mostek_lock);
- tmp = mostek_read(mregs + MOSTEK_CREG);
- tmp |= MSTK_CREG_READ;
- mostek_write(mregs + MOSTEK_CREG, tmp);
+ /* Traditional Mostek chip. */
+ tmp = mostek_read(mregs + MOSTEK_CREG);
+ tmp |= MSTK_CREG_READ;
+ mostek_write(mregs + MOSTEK_CREG, tmp);
+
+ sec = MSTK_REG_SEC(mregs);
+ min = MSTK_REG_MIN(mregs);
+ hour = MSTK_REG_HOUR(mregs);
+ day = MSTK_REG_DOM(mregs);
+ mon = MSTK_REG_MONTH(mregs);
+ year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
+ } else {
+ int i;
+
+ /* Dallas 12887 RTC chip. */
+
+ /* Stolen from arch/i386/kernel/time.c, see there for
+ * credits and descriptive comments.
+ */
+ for (i = 0; i < 1000000; i++) {
+ if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+ break;
+ udelay(10);
+ }
+ for (i = 0; i < 1000000; i++) {
+ if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+ break;
+ udelay(10);
+ }
+ do {
+ 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));
+ if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ BCD_TO_BIN(sec);
+ BCD_TO_BIN(min);
+ BCD_TO_BIN(hour);
+ BCD_TO_BIN(day);
+ BCD_TO_BIN(mon);
+ BCD_TO_BIN(year);
+ }
+ if ((year += 1900) < 1970)
+ year += 100;
+ }
- sec = MSTK_REG_SEC(mregs);
- min = MSTK_REG_MIN(mregs);
- hour = MSTK_REG_HOUR(mregs);
- day = MSTK_REG_DOM(mregs);
- mon = MSTK_REG_MONTH(mregs);
- year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_usec = 0;
- tmp = mostek_read(mregs + MOSTEK_CREG);
- tmp &= ~MSTK_CREG_READ;
- mostek_write(mregs + MOSTEK_CREG, tmp);
+ if (mregs) {
+ tmp = mostek_read(mregs + MOSTEK_CREG);
+ tmp &= ~MSTK_CREG_READ;
+ mostek_write(mregs + MOSTEK_CREG, tmp);
- spin_unlock_irq(&mostek_lock);
+ spin_unlock_irq(&mostek_lock);
+ }
}
void __init clock_probe(void)
@@ -358,21 +439,22 @@ void __init clock_probe(void)
busnd = sbus_root->prom_node;
}
- if(busnd == -1) {
+ if (busnd == -1) {
prom_printf("clock_probe: problem, cannot find bus to search.\n");
prom_halt();
}
node = prom_getchild(busnd);
- while(1) {
+ while (1) {
if (!node)
model[0] = 0;
else
prom_getstring(node, "model", model, sizeof(model));
- if(strcmp(model, "mk48t02") &&
- strcmp(model, "mk48t08") &&
- strcmp(model, "mk48t59")) {
+ if (strcmp(model, "mk48t02") &&
+ strcmp(model, "mk48t08") &&
+ strcmp(model, "mk48t59") &&
+ strcmp(model, "ds1287")) {
if (node)
node = prom_getsibling(node);
#ifdef CONFIG_PCI
@@ -384,7 +466,7 @@ void __init clock_probe(void)
}
}
#endif
- if(node == 0) {
+ if (node == 0) {
prom_printf("clock_probe: Cannot find timer chip\n");
prom_halt();
}
@@ -415,8 +497,12 @@ void __init clock_probe(void)
prom_halt();
}
- mstk48t59_regs = edev->resource[0].start;
- mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
+ if (!strcmp(model, "ds1287")) {
+ ds1287_regs = edev->resource[0].start;
+ } else {
+ mstk48t59_regs = edev->resource[0].start;
+ mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
+ }
break;
}
#endif
@@ -456,27 +542,21 @@ void __init clock_probe(void)
break;
}
- /* Report a low battery voltage condition. */
- if (has_low_battery())
- prom_printf("NVRAM: Low battery voltage!\n");
+ if (mstk48t02_regs != 0UL) {
+ /* Report a low battery voltage condition. */
+ if (has_low_battery())
+ prom_printf("NVRAM: Low battery voltage!\n");
- /* Kick start the clock if it is completely stopped. */
- if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
- kick_start_clock();
+ /* Kick start the clock if it is completely stopped. */
+ if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
+ kick_start_clock();
+ }
set_system_time();
__restore_flags(flags);
}
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
-#endif
-
extern void init_timers(void (*func)(int, void *, struct pt_regs *),
unsigned long *);
@@ -497,6 +577,7 @@ static __inline__ unsigned long do_gettimeoffset(void)
{
unsigned long ticks;
+ if (!SPARC64_USE_STICK) {
__asm__ __volatile__("
rd %%tick, %%g1
add %1, %%g1, %0
@@ -505,6 +586,14 @@ static __inline__ unsigned long do_gettimeoffset(void)
: "=r" (ticks)
: "r" (timer_tick_offset), "r" (timer_tick_compare)
: "g1", "g2");
+ } else {
+ __asm__ __volatile__("rd %%asr24, %%g1\n\t"
+ "add %1, %%g1, %0\n\t"
+ "sub %0, %2, %0\n\t"
+ : "=&r" (ticks)
+ : "r" (timer_tick_offset), "r" (timer_tick_compare)
+ : "g1");
+ }
return (ticks * timer_ticks_per_usec_quotient) >> 32UL;
}
@@ -533,8 +622,13 @@ void do_settimeofday(struct timeval *tv)
static int set_rtc_mmss(unsigned long nowtime)
{
- int real_seconds, real_minutes, mostek_minutes;
- unsigned long regs = mstk48t02_regs;
+ int real_seconds, real_minutes, chip_minutes;
+ unsigned long mregs = mstk48t02_regs;
+#ifdef CONFIG_PCI
+ unsigned long dregs = ds1287_regs;
+#else
+ unsigned long dregs = 0UL;
+#endif
unsigned long flags;
u8 tmp;
@@ -542,52 +636,96 @@ static int set_rtc_mmss(unsigned long nowtime)
* Not having a register set can lead to trouble.
* Also starfire doesnt have a tod clock.
*/
- if (!regs)
+ if (!mregs && !dregs)
return -1;
- spin_lock_irqsave(&mostek_lock, flags);
+ if (mregs) {
+ spin_lock_irqsave(&mostek_lock, flags);
- /* Read the current RTC minutes. */
- tmp = mostek_read(regs + MOSTEK_CREG);
- tmp |= MSTK_CREG_READ;
- mostek_write(regs + MOSTEK_CREG, tmp);
+ /* Read the current RTC minutes. */
+ tmp = mostek_read(mregs + MOSTEK_CREG);
+ tmp |= MSTK_CREG_READ;
+ mostek_write(mregs + MOSTEK_CREG, tmp);
- mostek_minutes = MSTK_REG_MIN(regs);
+ chip_minutes = MSTK_REG_MIN(mregs);
- tmp = mostek_read(regs + MOSTEK_CREG);
- tmp &= ~MSTK_CREG_READ;
- mostek_write(regs + MOSTEK_CREG, tmp);
+ tmp = mostek_read(mregs + MOSTEK_CREG);
+ tmp &= ~MSTK_CREG_READ;
+ mostek_write(mregs + MOSTEK_CREG, tmp);
- /*
- * since we're only adjusting minutes and seconds,
- * don't interfere with hour overflow. This avoids
- * messing with unknown time zones but requires your
- * RTC not to be off by more than 15 minutes
- */
- real_seconds = nowtime % 60;
- real_minutes = nowtime / 60;
- if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1)
- real_minutes += 30; /* correct for half hour time zone */
- real_minutes %= 60;
+ /*
+ * since we're only adjusting minutes and seconds,
+ * don't interfere with hour overflow. This avoids
+ * messing with unknown time zones but requires your
+ * RTC not to be off by more than 15 minutes
+ */
+ real_seconds = nowtime % 60;
+ real_minutes = nowtime / 60;
+ if (((abs(real_minutes - chip_minutes) + 15)/30) & 1)
+ real_minutes += 30; /* correct for half hour time zone */
+ real_minutes %= 60;
- if (abs(real_minutes - mostek_minutes) < 30) {
- tmp = mostek_read(regs + MOSTEK_CREG);
- tmp |= MSTK_CREG_WRITE;
- mostek_write(regs + MOSTEK_CREG, tmp);
+ if (abs(real_minutes - chip_minutes) < 30) {
+ tmp = mostek_read(mregs + MOSTEK_CREG);
+ tmp |= MSTK_CREG_WRITE;
+ mostek_write(mregs + MOSTEK_CREG, tmp);
- MSTK_SET_REG_SEC(regs,real_seconds);
- MSTK_SET_REG_MIN(regs,real_minutes);
+ MSTK_SET_REG_SEC(mregs,real_seconds);
+ MSTK_SET_REG_MIN(mregs,real_minutes);
- tmp = mostek_read(regs + MOSTEK_CREG);
- tmp &= ~MSTK_CREG_WRITE;
- mostek_write(regs + MOSTEK_CREG, tmp);
+ tmp = mostek_read(mregs + MOSTEK_CREG);
+ tmp &= ~MSTK_CREG_WRITE;
+ mostek_write(mregs + MOSTEK_CREG, tmp);
+
+ spin_unlock_irqrestore(&mostek_lock, flags);
- spin_unlock_irqrestore(&mostek_lock, flags);
+ return 0;
+ } else {
+ spin_unlock_irqrestore(&mostek_lock, flags);
- return 0;
+ return -1;
+ }
} else {
- spin_unlock_irqrestore(&mostek_lock, flags);
+ int retval = 0;
+ unsigned char save_control, save_freq_select;
- return -1;
+ /* Stolen from arch/i386/kernel/time.c, see there for
+ * credits and descriptive comments.
+ */
+ spin_lock_irqsave(&rtc_lock, flags);
+ save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
+ CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+ save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
+ CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+ chip_minutes = CMOS_READ(RTC_MINUTES);
+ if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+ BCD_TO_BIN(chip_minutes);
+ real_seconds = nowtime % 60;
+ real_minutes = nowtime / 60;
+ if (((abs(real_minutes - chip_minutes) + 15)/30) & 1)
+ real_minutes += 30;
+ real_minutes %= 60;
+
+ if (abs(real_minutes - chip_minutes) < 30) {
+ if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ BIN_TO_BCD(real_seconds);
+ BIN_TO_BCD(real_minutes);
+ }
+ CMOS_WRITE(real_seconds,RTC_SECONDS);
+ CMOS_WRITE(real_minutes,RTC_MINUTES);
+ } else {
+ printk(KERN_WARNING
+ "set_rtc_mmss: can't update from %d to %d\n",
+ chip_minutes, real_minutes);
+ retval = -1;
+ }
+
+ CMOS_WRITE(save_control, RTC_CONTROL);
+ CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ return retval;
}
}
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
index 4f2606c97..578a5ae80 100644
--- a/arch/sparc64/kernel/trampoline.S
+++ b/arch/sparc64/kernel/trampoline.S
@@ -1,4 +1,4 @@
-/* $Id: trampoline.S,v 1.12 1999/12/15 15:45:12 davem Exp $
+/* $Id: trampoline.S,v 1.19 2001/03/22 09:54:26 davem Exp $
* trampoline.S: Jump start slave processors on sparc64.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -7,6 +7,8 @@
#include <asm/head.h>
#include <asm/asi.h>
#include <asm/lsu.h>
+#include <asm/dcr.h>
+#include <asm/dcu.h>
#include <asm/pstate.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -30,177 +32,246 @@ dtlb_load:
sparc64_cpu_startup:
flushw
- mov (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
- stxa %g1, [%g0] ASI_LSU_CONTROL
- membar #Sync
+ rdpr %ver, %g1
+ sethi %hi(0x003e0014), %g5
+ srlx %g1, 32, %g1
+ or %g5, %lo(0x003e0014), %g5
+ cmp %g1, %g5
+ bne,pt %icc, spitfire_startup
+ nop
+
+cheetah_startup:
+ mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
+ wr %g1, %asr18
+
+ sethi %uhi(DCU_ME | DCU_RE | DCU_PE | DCU_HPE | DCU_SPE | DCU_SL | DCU_WE), %g5
+ or %g5, %ulo(DCU_ME | DCU_RE | DCU_PE | DCU_HPE | DCU_SPE | DCU_SL | DCU_WE), %g5
+ sllx %g5, 32, %g5
+ or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
+ ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
+ or %g5, %g3, %g5
+ stxa %g5, [%g0] ASI_DCU_CONTROL_REG
+ membar #Sync
+
+ /* Disable STICK_INT interrupts. */
+ sethi %hi(0x80000000), %g5
+ sllx %g5, 32, %g5
+ wr %g5, %asr25
+
+ ba,pt %xcc, startup_continue
+ nop
- wrpr %g0, 15, %pil
- wr %g0, 0, %tick_cmpr
+spitfire_startup:
+ mov (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
+ stxa %g1, [%g0] ASI_LSU_CONTROL
+ membar #Sync
+
+startup_continue:
+ wrpr %g0, 15, %pil
+ wr %g0, 0, %tick_cmpr
/* Call OBP by hand to lock KERNBASE into i/d tlbs. */
- mov %o0, %l0
-
- sethi %hi(prom_entry_lock), %g2
-1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
- brnz,pn %g1, 1b
- membar #StoreLoad | #StoreStore
-
- sethi %hi(p1275buf), %g2
- or %g2, %lo(p1275buf), %g2
- ldx [%g2 + 0x10], %l2
- mov %sp, %l1
- add %l2, -(192 + 128), %sp
+ mov %o0, %l0
+
+ sethi %hi(prom_entry_lock), %g2
+1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
+ brnz,pn %g1, 1b
+ membar #StoreLoad | #StoreStore
+
+ sethi %hi(p1275buf), %g2
+ or %g2, %lo(p1275buf), %g2
+ ldx [%g2 + 0x10], %l2
+ mov %sp, %l1
+ add %l2, -(192 + 128), %sp
flushw
- sethi %hi(call_method), %g2
- or %g2, %lo(call_method), %g2
- stx %g2, [%sp + 2047 + 128 + 0x00]
- mov 5, %g2
- stx %g2, [%sp + 2047 + 128 + 0x08]
- mov 1, %g2
- stx %g2, [%sp + 2047 + 128 + 0x10]
- sethi %hi(itlb_load), %g2
- or %g2, %lo(itlb_load), %g2
- stx %g2, [%sp + 2047 + 128 + 0x18]
- sethi %hi(mmu_ihandle_cache), %g2
- lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
- stx %g2, [%sp + 2047 + 128 + 0x20]
- sethi %hi(KERNBASE), %g2
- stx %g2, [%sp + 2047 + 128 + 0x28]
- sethi %hi(kern_locked_tte_data), %g2
- ldx [%g2 + %lo(kern_locked_tte_data)], %g2
- stx %g2, [%sp + 2047 + 128 + 0x30]
- mov 63, %g2
- stx %g2, [%sp + 2047 + 128 + 0x38]
- sethi %hi(p1275buf), %g2
- or %g2, %lo(p1275buf), %g2
- ldx [%g2 + 0x08], %o1
- call %o1
- add %sp, (2047 + 128), %o0
-
- sethi %hi(call_method), %g2
- or %g2, %lo(call_method), %g2
- stx %g2, [%sp + 2047 + 128 + 0x00]
- mov 5, %g2
- stx %g2, [%sp + 2047 + 128 + 0x08]
- mov 1, %g2
- stx %g2, [%sp + 2047 + 128 + 0x10]
- sethi %hi(dtlb_load), %g2
- or %g2, %lo(dtlb_load), %g2
- stx %g2, [%sp + 2047 + 128 + 0x18]
- sethi %hi(mmu_ihandle_cache), %g2
- lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
- stx %g2, [%sp + 2047 + 128 + 0x20]
- sethi %hi(KERNBASE), %g2
- stx %g2, [%sp + 2047 + 128 + 0x28]
- sethi %hi(kern_locked_tte_data), %g2
- ldx [%g2 + %lo(kern_locked_tte_data)], %g2
- stx %g2, [%sp + 2047 + 128 + 0x30]
- mov 63, %g2
- stx %g2, [%sp + 2047 + 128 + 0x38]
- sethi %hi(p1275buf), %g2
- or %g2, %lo(p1275buf), %g2
- ldx [%g2 + 0x08], %o1
- call %o1
- add %sp, (2047 + 128), %o0
-
- sethi %hi(prom_entry_lock), %g2
- stb %g0, [%g2 + %lo(prom_entry_lock)]
- membar #StoreStore | #StoreLoad
-
- mov %l1, %sp
+ sethi %hi(call_method), %g2
+ or %g2, %lo(call_method), %g2
+ stx %g2, [%sp + 2047 + 128 + 0x00]
+ mov 5, %g2
+ stx %g2, [%sp + 2047 + 128 + 0x08]
+ mov 1, %g2
+ stx %g2, [%sp + 2047 + 128 + 0x10]
+ sethi %hi(itlb_load), %g2
+ or %g2, %lo(itlb_load), %g2
+ stx %g2, [%sp + 2047 + 128 + 0x18]
+ sethi %hi(mmu_ihandle_cache), %g2
+ lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
+ stx %g2, [%sp + 2047 + 128 + 0x20]
+ sethi %hi(KERNBASE), %g2
+ stx %g2, [%sp + 2047 + 128 + 0x28]
+ sethi %hi(kern_locked_tte_data), %g2
+ ldx [%g2 + %lo(kern_locked_tte_data)], %g2
+ stx %g2, [%sp + 2047 + 128 + 0x30]
+
+ rdpr %ver, %g1
+ sethi %hi(0x003e0014), %g5
+ srlx %g1, 32, %g1
+ or %g5, %lo(0x003e0014), %g5
+ cmp %g1, %g5
+ bne,a,pt %icc, 1f
+ mov 63, %g2
+ mov 15, %g2
+1:
+ stx %g2, [%sp + 2047 + 128 + 0x38]
+ sethi %hi(p1275buf), %g2
+ or %g2, %lo(p1275buf), %g2
+ ldx [%g2 + 0x08], %o1
+ call %o1
+ add %sp, (2047 + 128), %o0
+
+ sethi %hi(call_method), %g2
+ or %g2, %lo(call_method), %g2
+ stx %g2, [%sp + 2047 + 128 + 0x00]
+ mov 5, %g2
+ stx %g2, [%sp + 2047 + 128 + 0x08]
+ mov 1, %g2
+ stx %g2, [%sp + 2047 + 128 + 0x10]
+ sethi %hi(dtlb_load), %g2
+ or %g2, %lo(dtlb_load), %g2
+ stx %g2, [%sp + 2047 + 128 + 0x18]
+ sethi %hi(mmu_ihandle_cache), %g2
+ lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
+ stx %g2, [%sp + 2047 + 128 + 0x20]
+ sethi %hi(KERNBASE), %g2
+ stx %g2, [%sp + 2047 + 128 + 0x28]
+ sethi %hi(kern_locked_tte_data), %g2
+ ldx [%g2 + %lo(kern_locked_tte_data)], %g2
+ stx %g2, [%sp + 2047 + 128 + 0x30]
+
+ rdpr %ver, %g1
+ sethi %hi(0x003e0014), %g5
+ srlx %g1, 32, %g1
+ or %g5, %lo(0x003e0014), %g5
+ cmp %g1, %g5
+ bne,a,pt %icc, 1f
+ mov 63, %g2
+ mov 15, %g2
+1:
+
+ stx %g2, [%sp + 2047 + 128 + 0x38]
+ sethi %hi(p1275buf), %g2
+ or %g2, %lo(p1275buf), %g2
+ ldx [%g2 + 0x08], %o1
+ call %o1
+ add %sp, (2047 + 128), %o0
+
+ sethi %hi(prom_entry_lock), %g2
+ stb %g0, [%g2 + %lo(prom_entry_lock)]
+ membar #StoreStore | #StoreLoad
+
+ mov %l1, %sp
flushw
- mov %l0, %o0
+ mov %l0, %o0
- wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
- wr %g0, 0, %fprs
+ wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
+ wr %g0, 0, %fprs
- sethi %uhi(PAGE_OFFSET), %g4
- sllx %g4, 32, %g4
+ sethi %uhi(PAGE_OFFSET), %g4
+ sllx %g4, 32, %g4
/* XXX Buggy PROM... */
- srl %o0, 0, %o0
- ldx [%o0], %g6
+ srl %o0, 0, %o0
+ ldx [%o0], %g6
- wr %g0, ASI_P, %asi
+ wr %g0, ASI_P, %asi
- mov PRIMARY_CONTEXT, %g7
- stxa %g0, [%g7] ASI_DMMU
- membar #Sync
- mov SECONDARY_CONTEXT, %g7
- stxa %g0, [%g7] ASI_DMMU
- membar #Sync
+ mov PRIMARY_CONTEXT, %g7
+ stxa %g0, [%g7] ASI_DMMU
+ membar #Sync
+ mov SECONDARY_CONTEXT, %g7
+ stxa %g0, [%g7] ASI_DMMU
+ membar #Sync
- mov 1, %g5
- sllx %g5, (PAGE_SHIFT + 1), %g5
- sub %g5, (REGWIN_SZ + STACK_BIAS), %g5
- add %g6, %g5, %sp
- mov 0, %fp
+ mov 1, %g5
+ sllx %g5, (PAGE_SHIFT + 1), %g5
+ sub %g5, (REGWIN_SZ + STACK_BIAS), %g5
+ add %g6, %g5, %sp
+ mov 0, %fp
- wrpr %g0, 0, %wstate
- wrpr %g0, 0, %tl
+ wrpr %g0, 0, %wstate
+ wrpr %g0, 0, %tl
/* Setup the trap globals, then we can resurface. */
- rdpr %pstate, %o1
- mov %g6, %o2
- wrpr %o1, PSTATE_AG, %pstate
- sethi %hi(sparc64_ttable_tl0), %g5
- wrpr %g5, %tba
- mov %o2, %g6
-
- wrpr %o1, PSTATE_MG, %pstate
-#define KERN_HIGHBITS ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000)
+ rdpr %pstate, %o1
+ mov %g6, %o2
+ wrpr %o1, PSTATE_AG, %pstate
+ sethi %hi(sparc64_ttable_tl0), %g5
+ wrpr %g5, %tba
+ mov %o2, %g6
+
+ wrpr %o1, PSTATE_MG, %pstate
+#define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000)
#define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
-#ifdef THIS_IS_CHEETAH
-#error Dave, make sure you took care of other issues in rest of sparc64 code...
-#define VPTE_BASE 0xffe0000000000000
-#else /* Spitfire/Blackbird */
-#define VPTE_BASE 0xfffffffe00000000
+
+#define VPTE_BASE_SPITFIRE 0xfffffffe00000000
+#if 1
+#define VPTE_BASE_CHEETAH VPTE_BASE_SPITFIRE
+#else
+#define VPTE_BASE_CHEETAH 0xffe0000000000000
#endif
- mov TSB_REG, %g1
- stxa %g0, [%g1] ASI_DMMU
- membar #Sync
- mov TLB_SFSR, %g1
- sethi %uhi(KERN_HIGHBITS), %g2
- or %g2, %ulo(KERN_HIGHBITS), %g2
- sllx %g2, 32, %g2
- or %g2, KERN_LOWBITS, %g2
- sethi %uhi(VPTE_BASE), %g3
- or %g3, %ulo(VPTE_BASE), %g3
- sllx %g3, 32, %g3
+
+ mov TSB_REG, %g1
+ stxa %g0, [%g1] ASI_DMMU
+ membar #Sync
+ mov TLB_SFSR, %g1
+ sethi %uhi(KERN_HIGHBITS), %g2
+ or %g2, %ulo(KERN_HIGHBITS), %g2
+ sllx %g2, 32, %g2
+ or %g2, KERN_LOWBITS, %g2
+
+ rdpr %ver, %g3
+ sethi %hi(0x003e0014), %g7
+ srlx %g3, 32, %g3
+ or %g7, %lo(0x003e0014), %g7
+ cmp %g3, %g7
+ bne,pt %icc, 1f
+ nop
+
+ sethi %uhi(VPTE_BASE_CHEETAH), %g3
+ or %g3, %ulo(VPTE_BASE_CHEETAH), %g3
+ ba,pt %xcc, 2f
+ sllx %g3, 32, %g3
+1:
+ sethi %uhi(VPTE_BASE_SPITFIRE), %g3
+ or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3
+ sllx %g3, 32, %g3
+
+2:
clr %g7
#undef KERN_HIGHBITS
#undef KERN_LOWBITS
-#undef VPTE_BASE
+#undef VPTE_BASE_SPITFIRE
+#undef VPTE_BASE_CHEETAH
/* Setup interrupt globals, we are always SMP. */
- wrpr %o1, PSTATE_IG, %pstate
+ wrpr %o1, PSTATE_IG, %pstate
/* Get our UPA MID. */
- lduw [%o2 + AOFF_task_processor], %g1
- sethi %hi(cpu_data), %g5
- or %g5, %lo(cpu_data), %g5
+ lduw [%o2 + AOFF_task_processor], %g1
+ sethi %hi(cpu_data), %g5
+ or %g5, %lo(cpu_data), %g5
/* In theory this is: &(cpu_data[this_upamid].irq_worklists[0]) */
- sllx %g1, 7, %g1
- add %g5, %g1, %g1
- add %g1, 64, %g6
+ sllx %g1, 7, %g1
+ add %g5, %g1, %g1
+ add %g1, 64, %g6
- wrpr %g0, 0, %wstate
- or %o1, PSTATE_IE, %o1
- wrpr %o1, 0, %pstate
+ wrpr %g0, 0, %wstate
+ or %o1, PSTATE_IE, %o1
+ wrpr %o1, 0, %pstate
- call prom_set_trap_table
- sethi %hi(sparc64_ttable_tl0), %o0
+ call prom_set_trap_table
+ sethi %hi(sparc64_ttable_tl0), %o0
- call smp_callin
+ call smp_callin
nop
- call cpu_idle
- mov 0, %o0
- call cpu_panic
+ call cpu_idle
+ mov 0, %o0
+ call cpu_panic
nop
-1: b,a,pt %xcc, 1b
+1: b,a,pt %xcc, 1b
.align 8
sparc64_cpu_startup_end:
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index cc703d3bc..0a368bcee 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.70 2001/02/09 05:46:44 davem Exp $
+/* $Id: traps.c,v 1.73 2001/03/22 07:26:03 davem Exp $
* arch/sparc64/kernel/traps.c
*
* Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -26,6 +26,7 @@
#include <asm/uaccess.h>
#include <asm/fpumacro.h>
#include <asm/lsu.h>
+#include <asm/dcu.h>
#include <asm/psrcompat.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
@@ -263,6 +264,10 @@ void bad_trap (struct pt_regs *regs, long lvl)
}
if (regs->tstate & TSTATE_PRIV)
die_if_kernel ("Kernel bad trap", regs);
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_ILLTRP;
@@ -291,6 +296,10 @@ void instruction_access_exception (struct pt_regs *regs,
#endif
die_if_kernel("Iax", regs);
}
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
info.si_signo = SIGSEGV;
info.si_errno = 0;
info.si_code = SEGV_MAPERR;
@@ -342,32 +351,41 @@ void data_access_exception (struct pt_regs *regs,
#ifdef CONFIG_PCI
/* This is really pathetic... */
-/* #define DEBUG_PCI_POKES */
extern volatile int pci_poke_in_progress;
extern volatile int pci_poke_faulted;
#endif
/* When access exceptions happen, we must do this. */
-static __inline__ void clean_and_reenable_l1_caches(void)
+static void clean_and_reenable_l1_caches(void)
{
unsigned long va;
- /* Clean 'em. */
- for(va = 0; va < (PAGE_SIZE << 1); va += 32) {
- spitfire_put_icache_tag(va, 0x0);
- spitfire_put_dcache_tag(va, 0x0);
- }
+ if (tlb_type == spitfire) {
+ /* Clean 'em. */
+ for (va = 0; va < (PAGE_SIZE << 1); va += 32) {
+ spitfire_put_icache_tag(va, 0x0);
+ spitfire_put_dcache_tag(va, 0x0);
+ }
- /* Re-enable. */
- __asm__ __volatile__("flush %%g6\n\t"
- "membar #Sync\n\t"
- "stxa %0, [%%g0] %1\n\t"
- "membar #Sync"
- : /* no outputs */
- : "r" (LSU_CONTROL_IC | LSU_CONTROL_DC |
- LSU_CONTROL_IM | LSU_CONTROL_DM),
- "i" (ASI_LSU_CONTROL)
- : "memory");
+ /* Re-enable in LSU. */
+ __asm__ __volatile__("flush %%g6\n\t"
+ "membar #Sync\n\t"
+ "stxa %0, [%%g0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (LSU_CONTROL_IC | LSU_CONTROL_DC |
+ LSU_CONTROL_IM | LSU_CONTROL_DM),
+ "i" (ASI_LSU_CONTROL)
+ : "memory");
+ } else if (tlb_type == cheetah) {
+ /* Flush D-cache */
+ for (va = 0; va < (1 << 16); va += (1 << 5)) {
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (va), "i" (ASI_DCACHE_TAG));
+ }
+ }
}
void do_iae(struct pt_regs *regs)
@@ -387,20 +405,16 @@ void do_iae(struct pt_regs *regs)
void do_dae(struct pt_regs *regs)
{
#ifdef CONFIG_PCI
- if(pci_poke_in_progress) {
-#ifdef DEBUG_PCI_POKES
- prom_printf(" (POKE tpc[%016lx] tnpc[%016lx] ",
- regs->tpc, regs->tnpc);
-#endif
+ if (pci_poke_in_progress) {
+ clean_and_reenable_l1_caches();
+
pci_poke_faulted = 1;
- regs->tnpc = regs->tpc + 4;
+ /* Why the fuck did they have to change this? */
+ if (tlb_type == cheetah)
+ regs->tpc += 4;
-#ifdef DEBUG_PCI_POKES
- prom_printf("PCI) ");
- /* prom_halt(); */
-#endif
- clean_and_reenable_l1_caches();
+ regs->tnpc = regs->tpc + 4;
return;
}
#endif
@@ -534,6 +548,10 @@ void do_fpe_common(struct pt_regs *regs)
unsigned long fsr = current->thread.xfsr[0];
siginfo_t info;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_addr = (void *)regs->tpc;
@@ -589,6 +607,10 @@ void do_tof(struct pt_regs *regs)
if(regs->tstate & TSTATE_PRIV)
die_if_kernel("Penguin overflow trap from kernel mode", regs);
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
info.si_signo = SIGEMT;
info.si_errno = 0;
info.si_code = EMT_TAGOVF;
@@ -601,6 +623,10 @@ void do_div0(struct pt_regs *regs)
{
siginfo_t info;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_code = FPE_INTDIV;
@@ -700,8 +726,13 @@ void die_if_kernel(char *str, struct pt_regs *regs)
(rw->ins[6] + STACK_BIAS);
}
instruction_dump ((unsigned int *) regs->tpc);
- } else
+ } else {
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
user_instruction_dump ((unsigned int *) regs->tpc);
+ }
#ifdef CONFIG_SMP
smp_report_regs();
#endif
@@ -765,6 +796,10 @@ void do_privop(struct pt_regs *regs)
{
siginfo_t info;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_PRVOPC;
@@ -907,6 +942,10 @@ void do_getpsr(struct pt_regs *regs)
regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate);
regs->tpc = regs->tnpc;
regs->tnpc += 4;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
}
void trap_init(void)
diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S
index b1081b9fe..2f7e0e16c 100644
--- a/arch/sparc64/kernel/ttable.S
+++ b/arch/sparc64/kernel/ttable.S
@@ -1,4 +1,4 @@
-/* $Id: ttable.S,v 1.31 2000/05/09 17:40:14 davem Exp $
+/* $Id: ttable.S,v 1.32 2001/03/23 07:56:30 davem Exp $
* ttable.S: Sparc V9 Trap Table(s) with SpitFire extensions.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -22,7 +22,7 @@ tl0_resv018: BTRAP(0x18) BTRAP(0x19) BTRAP(0x1a) BTRAP(0x1b) BTRAP(0x1c) BTRAP(0
tl0_resv01e: BTRAP(0x1e) BTRAP(0x1f)
tl0_fpdis: TRAP_NOSAVE(do_fpdis)
tl0_fpieee: TRAP_SAVEFPU(do_fpieee)
-tl0_fpother: TRAP_SAVEFPU(do_fpother)
+tl0_fpother: TRAP_NOSAVE(do_fpother_check_fitos)
tl0_tof: TRAP(do_tof)
tl0_cwin: CLEAN_WINDOW
tl0_div0: TRAP(do_div0)
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index f43204c3b..7a21f0080 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -1,4 +1,4 @@
-/* $Id: unaligned.c,v 1.20 2000/04/29 08:05:21 anton Exp $
+/* $Id: unaligned.c,v 1.21 2001/03/21 11:46:20 davem Exp $
* unaligned.c: Unaligned load/store trap handling with special
* cases for the kernel to do them more quickly.
*
@@ -334,6 +334,10 @@ static inline void advance(struct pt_regs *regs)
{
regs->tpc = regs->tnpc;
regs->tnpc += 4;
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ regs->tnpc &= 0xffffffff;
+ }
}
static inline int floating_point_load_or_store_p(unsigned int insn)
diff --git a/arch/sparc64/lib/U3copy_in_user.S b/arch/sparc64/lib/U3copy_in_user.S
index 0fc169b9d..e28d34ac0 100644
--- a/arch/sparc64/lib/U3copy_in_user.S
+++ b/arch/sparc64/lib/U3copy_in_user.S
@@ -1,4 +1,4 @@
-/* $Id: U3copy_in_user.S,v 1.3 2000/11/01 09:29:19 davem Exp $
+/* $Id: U3copy_in_user.S,v 1.4 2001/03/21 05:58:47 davem Exp $
* U3memcpy.S: UltraSparc-III optimized copy within userspace.
*
* Copyright (C) 1999, 2000 David S. Miller (davem@redhat.com)
@@ -231,25 +231,25 @@ U3copy_in_user_enter:
.align 64
U3copy_in_user_begin:
- prefetch [%o1 + 0x000], #one_read ! MS Group1
- prefetch [%o1 + 0x040], #one_read ! MS Group2
+ prefetcha [%o1 + 0x000] %asi, #one_read ! MS Group1
+ prefetcha [%o1 + 0x040] %asi, #one_read ! MS Group2
andn %o2, (0x40 - 1), %o4 ! A0
- prefetch [%o1 + 0x080], #one_read ! MS Group3
+ prefetcha [%o1 + 0x080] %asi, #one_read ! MS Group3
cmp %o4, 0x140 ! A0
- prefetch [%o1 + 0x0c0], #one_read ! MS Group4
+ prefetcha [%o1 + 0x0c0] %asi, #one_read ! MS Group4
EX(ldda [%o1 + 0x000] %asi, %f0, add %o2, %g0) ! MS Group5 (%f0 results at G8)
bge,a,pt %icc, 1f ! BR
- prefetch [%o1 + 0x100], #one_read ! MS Group6
+ prefetcha [%o1 + 0x100] %asi, #one_read ! MS Group6
1: EX(ldda [%o1 + 0x008] %asi, %f2, add %o2, %g0) ! AX (%f2 results at G9)
cmp %o4, 0x180 ! A1
bge,a,pt %icc, 1f ! BR
- prefetch [%o1 + 0x140], #one_read ! MS Group7
+ prefetcha [%o1 + 0x140] %asi, #one_read ! MS Group7
1: EX(ldda [%o1 + 0x010] %asi, %f4, add %o2, %g0) ! AX (%f4 results at G10)
cmp %o4, 0x1c0 ! A1
bge,a,pt %icc, 1f ! BR
- prefetch [%o1 + 0x180], #one_read ! MS Group8
+ prefetcha [%o1 + 0x180] %asi, #one_read ! MS Group8
1: faligndata %f0, %f2, %f16 ! FGA Group9 (%f16 at G12)
EX(ldda [%o1 + 0x018] %asi, %f6, add %o2, %g0) ! AX (%f6 results at G12)
faligndata %f2, %f4, %f18 ! FGA Group10 (%f18 results at G13)
@@ -305,7 +305,7 @@ U3copy_in_user_loop1:
faligndata %f8, %f10, %f24 ! FGA Group16 (%f24 results at G19)
EXBLK1(ldda [%o1 + 0x040] %asi, %f0) ! AX (%f0 results at G19)
- prefetch [%o1 + 0x180], #one_read ! MS
+ prefetcha [%o1 + 0x180] %asi, #one_read ! MS
faligndata %f10, %f12, %f26 ! FGA Group17 (%f26 results at G20)
subcc %o4, 0x40, %o4 ! A0
add %o1, 0x40, %o1 ! A1
diff --git a/arch/sparc64/lib/VISbzero.S b/arch/sparc64/lib/VISbzero.S
index 610740d37..c8713995c 100644
--- a/arch/sparc64/lib/VISbzero.S
+++ b/arch/sparc64/lib/VISbzero.S
@@ -1,4 +1,4 @@
-/* $Id: VISbzero.S,v 1.10 1999/05/25 16:52:56 jj Exp $
+/* $Id: VISbzero.S,v 1.11 2001/03/15 08:51:24 anton Exp $
* VISbzero.S: High speed clear operations utilizing the UltraSparc
* Visual Instruction Set.
*
@@ -83,6 +83,8 @@
.text
.align 32
#ifdef __KERNEL__
+ .globl __bzero_begin
+__bzero_begin:
.globl __bzero, __bzero_noasi
__bzero_noasi:
rd %asi, %g5
@@ -272,3 +274,5 @@ VISbzerofixup_zb:
ba,pt %xcc, VISbzerofixup_ret0
sub %o1, %g2, %o0
#endif
+ .globl __bzero_end
+__bzero_end:
diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S
index 2254ba5c5..d1b257174 100644
--- a/arch/sparc64/lib/VISsave.S
+++ b/arch/sparc64/lib/VISsave.S
@@ -1,4 +1,4 @@
-/* $Id: VISsave.S,v 1.4 1999/07/30 09:35:37 davem Exp $
+/* $Id: VISsave.S,v 1.5 2001/03/08 22:08:51 davem Exp $
* VISsave.S: Code for saving FPU register state for
* VIS routines. One should not call this directly,
* but use macros provided in <asm/visasm.h>.
@@ -37,14 +37,15 @@ vis1: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3
clr %g1
ba,pt %xcc, 3f
- stb %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr]
+ stx %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr]
2: add %g6, %g1, %g3
cmp %o5, FPRS_DU
be,pn %icc, 6f
sll %g1, 3, %g1
stb %o5, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved]
rd %gsr, %g2
- stb %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr]
+ add %g6, %g1, %g3
+ stx %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr]
add %g6, %g1, %g2
stx %fsr, [%g2 + AOFF_task_thread + AOFF_thread_xfsr]
@@ -106,7 +107,8 @@ VISenterhalf:
stb %g2, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved]
rd %gsr, %g2
- stb %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr]
+ add %g6, %g1, %g3
+ stx %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr]
add %g6, %g1, %g2
stx %fsr, [%g2 + AOFF_task_thread + AOFF_thread_xfsr]
sll %g1, 5, %g1
diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S
index 8d2b749e1..006ab5228 100644
--- a/arch/sparc64/lib/blockops.S
+++ b/arch/sparc64/lib/blockops.S
@@ -1,4 +1,4 @@
-/* $Id: blockops.S,v 1.27 2000/07/14 01:12:49 davem Exp $
+/* $Id: blockops.S,v 1.30 2001/03/22 13:10:10 davem Exp $
* blockops.S: UltraSparc block zero optimized routines.
*
* Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com)
@@ -83,6 +83,8 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
or %g2, %g3, %g2
add %o0, %o3, %o0
add %o0, %o1, %o1
+#define FIX_INSN_1 0x96102068 /* mov (13 << 3), %o3 */
+cheetah_patch_1:
mov TLBTEMP_ENT1, %o3
rdpr %pstate, %g3
wrpr %g3, PSTATE_IE, %pstate
@@ -96,16 +98,14 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
/* Spitfire Errata #32 workaround */
mov 0x8, %o4
stxa %g0, [%o4] ASI_DMMU
- sethi %hi(empty_zero_page), %o4
- flush %o4
+ membar #Sync
ldxa [%o3] ASI_DTLB_TAG_READ, %o4
/* Spitfire Errata #32 workaround */
mov 0x8, %o5
stxa %g0, [%o5] ASI_DMMU
- sethi %hi(empty_zero_page), %o5
- flush %o5
+ membar #Sync
ldxa [%o3] ASI_DTLB_DATA_ACCESS, %o5
stxa %o0, [%o2] ASI_DMMU
@@ -116,16 +116,14 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
/* Spitfire Errata #32 workaround */
mov 0x8, %g5
stxa %g0, [%g5] ASI_DMMU
- sethi %hi(empty_zero_page), %g5
- flush %g5
+ membar #Sync
ldxa [%o3] ASI_DTLB_TAG_READ, %g5
/* Spitfire Errata #32 workaround */
mov 0x8, %g7
stxa %g0, [%g7] ASI_DMMU
- sethi %hi(empty_zero_page), %g7
- flush %g7
+ membar #Sync
ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g7
stxa %o1, [%o2] ASI_DMMU
@@ -136,6 +134,107 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
bne,pn %xcc, copy_page_using_blkcommit
nop
+ rdpr %ver, %g3
+ sllx %g3, 16, %g3
+ srlx %g3, 32 + 16, %g3
+ cmp %g3, 0x14
+ bne,pt %icc, spitfire_copy_user_page
+ nop
+
+cheetah_copy_user_page:
+ mov 121, %o2 ! A0 Group
+ prefetch [%o1 + 0x000], #one_read ! MS
+ prefetch [%o1 + 0x040], #one_read ! MS Group
+ prefetch [%o1 + 0x080], #one_read ! MS Group
+ prefetch [%o1 + 0x0c0], #one_read ! MS Group
+ ldd [%o1 + 0x000], %f0 ! MS Group
+ prefetch [%o1 + 0x100], #one_read ! MS Group
+ ldd [%o1 + 0x008], %f2 ! AX
+ prefetch [%o1 + 0x140], #one_read ! MS Group
+ ldd [%o1 + 0x010], %f4 ! AX
+ prefetch [%o1 + 0x180], #one_read ! MS Group
+ fmovd %f0, %f32 ! FGA Group
+ ldd [%o1 + 0x018], %f6 ! AX
+ fmovd %f2, %f34 ! FGA Group
+ ldd [%o1 + 0x020], %f8 ! MS
+ fmovd %f4, %f36 ! FGA Group
+ ldd [%o1 + 0x028], %f10 ! AX
+ membar #StoreStore ! MS
+ fmovd %f6, %f38 ! FGA Group
+ ldd [%o1 + 0x030], %f12 ! MS
+ fmovd %f8, %f40 ! FGA Group
+ ldd [%o1 + 0x038], %f14 ! AX
+ fmovd %f10, %f42 ! FGA Group
+ ldd [%o1 + 0x040], %f16 ! MS
+1: ldd [%o1 + 0x048], %f2 ! AX (Group)
+ fmovd %f12, %f44 ! FGA
+ ldd [%o1 + 0x050], %f4 ! MS
+ fmovd %f14, %f46 ! FGA Group
+ stda %f32, [%o0] ASI_BLK_P ! MS
+ ldd [%o1 + 0x058], %f6 ! AX
+ fmovd %f16, %f32 ! FGA Group (8-cycle stall)
+ ldd [%o1 + 0x060], %f8 ! MS
+ fmovd %f2, %f34 ! FGA Group
+ ldd [%o1 + 0x068], %f10 ! AX
+ fmovd %f4, %f36 ! FGA Group
+ ldd [%o1 + 0x070], %f12 ! MS
+ fmovd %f6, %f38 ! FGA Group
+ ldd [%o1 + 0x078], %f14 ! AX
+ fmovd %f8, %f40 ! FGA Group
+ ldd [%o1 + 0x080], %f16 ! AX
+ prefetch [%o1 + 0x180], #one_read ! MS
+ fmovd %f10, %f42 ! FGA Group
+ subcc %o2, 1, %o2 ! A0
+ add %o0, 0x40, %o0 ! A1
+ bne,pt %xcc, 1b ! BR
+ add %o1, 0x40, %o1 ! A0 Group
+
+ mov 5, %o2 ! A0 Group
+1: ldd [%o1 + 0x048], %f2 ! AX
+ fmovd %f12, %f44 ! FGA
+ ldd [%o1 + 0x050], %f4 ! MS
+ fmovd %f14, %f46 ! FGA Group
+ stda %f32, [%o0] ASI_BLK_P ! MS
+ ldd [%o1 + 0x058], %f6 ! AX
+ fmovd %f16, %f32 ! FGA Group (8-cycle stall)
+ ldd [%o1 + 0x060], %f8 ! MS
+ fmovd %f2, %f34 ! FGA Group
+ ldd [%o1 + 0x068], %f10 ! AX
+ fmovd %f4, %f36 ! FGA Group
+ ldd [%o1 + 0x070], %f12 ! MS
+ fmovd %f6, %f38 ! FGA Group
+ ldd [%o1 + 0x078], %f14 ! AX
+ fmovd %f8, %f40 ! FGA Group
+ ldd [%o1 + 0x080], %f16 ! MS
+ fmovd %f10, %f42 ! FGA Group
+ subcc %o2, 1, %o2 ! A0
+ add %o0, 0x40, %o0 ! A1
+ bne,pt %xcc, 1b ! BR
+ add %o1, 0x40, %o1 ! A0 Group
+
+ ldd [%o1 + 0x048], %f2 ! AX
+ fmovd %f12, %f44 ! FGA
+ ldd [%o1 + 0x050], %f4 ! MS
+ fmovd %f14, %f46 ! FGA Group
+ stda %f32, [%o0] ASI_BLK_P ! MS
+ ldd [%o1 + 0x058], %f6 ! AX
+ fmovd %f16, %f32 ! FGA Group (8-cycle stall)
+ ldd [%o1 + 0x060], %f8 ! MS
+ fmovd %f2, %f34 ! FGA Group
+ ldd [%o1 + 0x068], %f10 ! AX
+ fmovd %f4, %f36 ! FGA Group
+ ldd [%o1 + 0x070], %f12 ! MS
+ fmovd %f6, %f38 ! FGA Group
+ add %o0, 0x40, %o0 ! A0
+ ldd [%o1 + 0x078], %f14 ! AX
+ fmovd %f8, %f40 ! FGA Group
+ fmovd %f10, %f42 ! FGA Group
+ fmovd %f12, %f44 ! FGA Group
+ fmovd %f14, %f46 ! FGA Group
+ stda %f32, [%o0] ASI_BLK_P ! MS
+ ba,a,pt %xcc, copy_user_page_continue
+
+spitfire_copy_user_page:
ldda [%o1] ASI_BLK_P, %f0
add %o1, 0x40, %o1
ldda [%o1] ASI_BLK_P, %f16
@@ -237,6 +336,8 @@ clear_user_page: /* %o0=dest, %o1=vaddr */
or %g3, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), %g3
or %g1, %g3, %g1
add %o0, %o3, %o0
+#define FIX_INSN_2 0x96102070 /* mov (14 << 3), %o3 */
+cheetah_patch_2:
mov TLBTEMP_ENT2, %o3
rdpr %pstate, %g3
wrpr %g3, PSTATE_IE, %pstate
@@ -244,16 +345,14 @@ clear_user_page: /* %o0=dest, %o1=vaddr */
/* Spitfire Errata #32 workaround */
mov 0x8, %g5
stxa %g0, [%g5] ASI_DMMU
- sethi %hi(empty_zero_page), %g5
- flush %g5
+ membar #Sync
ldxa [%o3] ASI_DTLB_TAG_READ, %g5
/* Spitfire Errata #32 workaround */
mov 0x8, %g7
stxa %g0, [%g7] ASI_DMMU
- sethi %hi(empty_zero_page), %g7
- flush %g7
+ membar #Sync
ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g7
stxa %o0, [%o2] ASI_DMMU
@@ -299,3 +398,24 @@ clear_page_common:
membar #Sync
jmpl %o7 + 0x8, %g0
wrpr %g3, 0x0, %pstate
+
+ /* We will write cheetah optimized versions later. */
+ .globl cheetah_patch_pgcopyops
+cheetah_patch_pgcopyops:
+ sethi %hi(FIX_INSN_1), %g1
+ or %g1, %lo(FIX_INSN_1), %g1
+ sethi %hi(cheetah_patch_1), %g2
+ or %g2, %lo(cheetah_patch_1), %g2
+ stw %g1, [%g2]
+ flush %g2
+ sethi %hi(FIX_INSN_2), %g1
+ or %g1, %lo(FIX_INSN_2), %g1
+ sethi %hi(cheetah_patch_2), %g2
+ or %g2, %lo(cheetah_patch_2), %g2
+ stw %g1, [%g2]
+ flush %g2
+ retl
+ nop
+
+#undef FIX_INSN1
+#undef FIX_INSN2
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 12006b58a..f161898c0 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.51 2000/09/14 06:22:32 anton Exp $
+/* $Id: fault.c,v 1.54 2001/03/24 09:36:11 davem Exp $
* arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -142,7 +142,7 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
{
unsigned long g2;
unsigned char asi = ASI_P;
-
+
if (!insn) {
if (regs->tstate & TSTATE_PRIV) {
if (!regs->tpc || (regs->tpc & 0x3))
@@ -234,7 +234,12 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs)
if (in_interrupt() || !mm)
goto handle_kernel_fault;
- down(&mm->mmap_sem);
+ if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
+ regs->tpc &= 0xffffffff;
+ address &= 0xffffffff;
+ }
+
+ down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
@@ -286,7 +291,12 @@ good_area:
if (fault_code & FAULT_CODE_WRITE) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
- if ((vma->vm_flags & VM_EXEC) != 0 &&
+
+ /* Spitfire has an icache which does not snoop
+ * processor stores. Later processors do...
+ */
+ if (tlb_type == spitfire &&
+ (vma->vm_flags & VM_EXEC) != 0 &&
vma->vm_file != NULL)
current->thread.use_blkcommit = 1;
} else {
@@ -308,7 +318,7 @@ good_area:
goto out_of_memory;
}
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
goto fault_done;
/*
@@ -316,7 +326,7 @@ good_area:
* Fix it, but check if it's kernel or user first..
*/
bad_area:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
handle_kernel_fault:
do_kernel_fault(regs, si_code, fault_code, insn, address);
@@ -328,14 +338,14 @@ handle_kernel_fault:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", current->comm);
if (!(regs->tstate & TSTATE_PRIV))
do_exit(SIGKILL);
goto handle_kernel_fault;
do_sigbus:
- up(&mm->mmap_sem);
+ up_read(&mm->mmap_sem);
/*
* Send a sigbus, regardless of whether we were in kernel
diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c
index 68b77cfab..954c4b493 100644
--- a/arch/sparc64/mm/generic.c
+++ b/arch/sparc64/mm/generic.c
@@ -1,4 +1,4 @@
-/* $Id: generic.c,v 1.14 2000/08/09 00:00:15 davem Exp $
+/* $Id: generic.c,v 1.16 2001/03/25 04:40:05 davem Exp $
* generic.c: Generic Sparc mm routines that are not dependent upon
* MMU type but are Sparc specific.
*
@@ -104,12 +104,10 @@ static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigne
end = PGDIR_SIZE;
offset -= address;
do {
- pte_t * pte = pte_alloc(pmd, address);
+ pte_t * pte = pte_alloc(current->mm, pmd, address);
if (!pte)
return -ENOMEM;
- spin_lock(&current->mm->page_table_lock);
io_remap_pte_range(pte, address, end - address, address + offset, prot, space);
- spin_unlock(&current->mm->page_table_lock);
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
} while (address < end);
@@ -122,13 +120,16 @@ int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long
pgd_t * dir;
unsigned long beg = from;
unsigned long end = from + size;
+ struct mm_struct *mm = current->mm;
prot = __pgprot(pg_iobits);
offset -= from;
- dir = pgd_offset(current->mm, from);
- flush_cache_range(current->mm, beg, end);
+ dir = pgd_offset(mm, from);
+ flush_cache_range(mm, beg, end);
+
+ spin_lock(&mm->page_table_lock);
while (from < end) {
- pmd_t *pmd = pmd_alloc(dir, from);
+ pmd_t *pmd = pmd_alloc(current->mm, dir, from);
error = -ENOMEM;
if (!pmd)
break;
@@ -138,6 +139,8 @@ int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long
from = (from + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
+ spin_unlock(&mm->page_table_lock);
+
flush_tlb_range(current->mm, beg, end);
return error;
}
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 15407f4f4..a4cc8ad81 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.162 2001/02/13 01:16:44 davem Exp $
+/* $Id: init.c,v 1.172 2001/03/24 09:36:01 davem Exp $
* arch/sparc64/mm/init.c
*
* Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -40,6 +40,8 @@ unsigned long *sparc64_valid_addr_bitmap;
/* Ugly, but necessary... -DaveM */
unsigned long phys_base;
+enum ultra_tlb_layout tlb_type = spitfire;
+
/* get_new_mmu_context() uses "cache + 1". */
spinlock_t ctx_alloc_lock = SPIN_LOCK_UNLOCKED;
unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1;
@@ -57,17 +59,17 @@ int do_check_pgt_cache(int low, int high)
{
int freed = 0;
- if(pgtable_cache_size > high) {
+ if (pgtable_cache_size > high) {
do {
#ifdef CONFIG_SMP
- if(pgd_quicklist)
+ if (pgd_quicklist)
free_pgd_slow(get_pgd_fast()), freed++;
#endif
- if(pte_quicklist[0])
- free_pte_slow(get_pte_fast(0)), freed++;
- if(pte_quicklist[1])
- free_pte_slow(get_pte_fast(1)), freed++;
- } while(pgtable_cache_size > low);
+ if (pte_quicklist[0])
+ free_pte_slow(pte_alloc_one_fast(NULL, 0)), freed++;
+ if (pte_quicklist[1])
+ free_pte_slow(pte_alloc_one_fast(NULL, 1 << (PAGE_SHIFT + 10))), freed++;
+ } while (pgtable_cache_size > low);
}
#ifndef CONFIG_SMP
if (pgd_cache_size > high / 4) {
@@ -107,7 +109,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
if (VALID_PAGE(page) && page->mapping &&
test_bit(PG_dcache_dirty, &page->flags)) {
- __flush_dcache_page(page->virtual, 1);
+ __flush_dcache_page(page->virtual,
+ (tlb_type == spitfire));
clear_bit(PG_dcache_dirty, &page->flags);
}
__update_mmu_cache(vma, address, pte);
@@ -118,10 +121,13 @@ extern void __flush_icache_page(unsigned long);
void flush_icache_range(unsigned long start, unsigned long end)
{
- unsigned long kaddr;
+ /* Cheetah has coherent I-cache. */
+ if (tlb_type == spitfire) {
+ unsigned long kaddr;
- for (kaddr = start; kaddr < end; kaddr += PAGE_SIZE)
- __flush_icache_page(__get_phys(kaddr));
+ for (kaddr = start; kaddr < end; kaddr += PAGE_SIZE)
+ __flush_icache_page(__get_phys(kaddr));
+ }
}
/*
@@ -163,13 +169,12 @@ void show_mem(void)
int mmu_info(char *buf)
{
- /* We'll do the rest later to make it nice... -DaveM */
-#if 0
- if (this_is_cheetah)
- sprintf(buf, "MMU Type\t: One bad ass cpu\n");
+ if (tlb_type == cheetah)
+ return sprintf(buf, "MMU Type\t: Cheetah\n");
+ else if (tlb_type == spitfire)
+ return sprintf(buf, "MMU Type\t: Spitfire\n");
else
-#endif
- return sprintf(buf, "MMU Type\t: Spitfire\n");
+ return sprintf(buf, "MMU Type\t: ???\n");
}
struct linux_prom_translation {
@@ -231,6 +236,8 @@ static void inherit_prom_mappings(void)
for (vaddr = trans[i].virt;
vaddr < trans[i].virt + trans[i].size;
vaddr += PAGE_SIZE) {
+ unsigned long val;
+
pgdp = pgd_offset(&init_mm, vaddr);
if (pgd_none(*pgdp)) {
pmdp = __alloc_bootmem(PMD_TABLE_SIZE,
@@ -252,7 +259,14 @@ static void inherit_prom_mappings(void)
pmd_set(pmdp, ptep);
}
ptep = pte_offset(pmdp, vaddr);
- set_pte (ptep, __pte(trans[i].data | _PAGE_MODIFIED));
+
+ val = trans[i].data;
+
+ /* Clear diag TTE bits. */
+ if (tlb_type == spitfire)
+ val &= ~0x0003fe0000000000UL;
+
+ set_pte (ptep, __pte(val | _PAGE_MODIFIED));
trans[i].data += PAGE_SIZE;
}
}
@@ -268,26 +282,59 @@ static void inherit_prom_mappings(void)
: "r" (0),
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
- phys_page = spitfire_get_dtlb_data(63) & _PAGE_PADDR;
+ switch (tlb_type) {
+ default:
+ case spitfire:
+ phys_page = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent());
+ break;
+
+ case cheetah:
+ phys_page = cheetah_get_litlb_data(sparc64_highest_locked_tlbent());
+ break;
+ };
+
+ phys_page &= _PAGE_PADDR;
phys_page += ((unsigned long)&prom_boot_page -
(unsigned long)&empty_zero_page);
- /* Lock this into i/d tlb entry 59 */
- __asm__ __volatile__(
- "stxa %%g0, [%2] %3\n\t"
- "stxa %0, [%1] %4\n\t"
- "membar #Sync\n\t"
- "flush %%g6\n\t"
- "stxa %%g0, [%2] %5\n\t"
- "stxa %0, [%1] %6\n\t"
- "membar #Sync\n\t"
- "flush %%g6"
- : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP |
- _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W),
- "r" (59 << 3), "r" (TLB_TAG_ACCESS),
- "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS),
- "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS)
- : "memory");
+ if (tlb_type == spitfire) {
+ /* Lock this into i/d tlb entry 59 */
+ __asm__ __volatile__(
+ "stxa %%g0, [%2] %3\n\t"
+ "stxa %0, [%1] %4\n\t"
+ "membar #Sync\n\t"
+ "flush %%g6\n\t"
+ "stxa %%g0, [%2] %5\n\t"
+ "stxa %0, [%1] %6\n\t"
+ "membar #Sync\n\t"
+ "flush %%g6"
+ : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP |
+ _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W),
+ "r" (59 << 3), "r" (TLB_TAG_ACCESS),
+ "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS),
+ "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS)
+ : "memory");
+ } else if (tlb_type == cheetah) {
+ /* Lock this into i/d tlb-0 entry 11 */
+ __asm__ __volatile__(
+ "stxa %%g0, [%2] %3\n\t"
+ "stxa %0, [%1] %4\n\t"
+ "membar #Sync\n\t"
+ "flush %%g6\n\t"
+ "stxa %%g0, [%2] %5\n\t"
+ "stxa %0, [%1] %6\n\t"
+ "membar #Sync\n\t"
+ "flush %%g6"
+ : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP |
+ _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W),
+ "r" ((0 << 16) | (11 << 3)), "r" (TLB_TAG_ACCESS),
+ "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS),
+ "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS)
+ : "memory");
+ } else {
+ /* Implement me :-) */
+ BUG();
+ }
tte_vaddr = (unsigned long) &empty_zero_page;
@@ -298,7 +345,12 @@ static void inherit_prom_mappings(void)
: "r" (0),
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
- kern_locked_tte_data = tte_data = spitfire_get_dtlb_data(63);
+ if (tlb_type == spitfire)
+ tte_data = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent());
+ else
+ tte_data = cheetah_get_ldtlb_data(sparc64_highest_locked_tlbent());
+
+ kern_locked_tte_data = tte_data;
remap_func = (void *) ((unsigned long) &prom_remap -
(unsigned long) &prom_boot_page);
@@ -311,7 +363,9 @@ static void inherit_prom_mappings(void)
: "r" (0),
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
- remap_func(spitfire_get_dtlb_data(63) & _PAGE_PADDR,
+ remap_func((tlb_type == spitfire ?
+ (spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR) :
+ (cheetah_get_litlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR)),
(unsigned long) &empty_zero_page,
prom_get_mmu_ihandle());
@@ -320,8 +374,8 @@ static void inherit_prom_mappings(void)
spitfire_flush_itlb_nucleus_page(0x0);
/* Now lock us back into the TLBs via OBP. */
- prom_dtlb_load(63, tte_data, tte_vaddr);
- prom_itlb_load(63, tte_data, tte_vaddr);
+ prom_dtlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr);
+ prom_itlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr);
/* Re-read translations property. */
if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) {
@@ -372,26 +426,43 @@ static void __flush_nucleus_vptes(void)
int i;
/* Only DTLB must be checked for VPTE entries. */
- for(i = 0; i < 63; i++) {
- unsigned long tag;
-
- /* Spitfire Errata #32 workaround */
- __asm__ __volatile__("stxa %0, [%1] %2\n\t"
- "flush %%g6"
- : /* No outputs */
- : "r" (0),
- "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
-
- tag = spitfire_get_dtlb_tag(i);
- if(((tag & ~(PAGE_MASK)) == 0) &&
- ((tag & (PAGE_MASK)) >= prom_reserved_base)) {
- __asm__ __volatile__("stxa %%g0, [%0] %1"
- : /* no outputs */
- : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
- membar("#Sync");
- spitfire_put_dtlb_data(i, 0x0UL);
- membar("#Sync");
+ if (tlb_type == spitfire) {
+ for (i = 0; i < 63; i++) {
+ unsigned long tag;
+
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
+ tag = spitfire_get_dtlb_tag(i);
+ if (((tag & ~(PAGE_MASK)) == 0) &&
+ ((tag & (PAGE_MASK)) >= prom_reserved_base)) {
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
+ spitfire_put_dtlb_data(i, 0x0UL);
+ }
}
+ } else if (tlb_type == cheetah) {
+ for (i = 0; i < 512; i++) {
+ unsigned long tag = cheetah_get_dtlb_tag(i);
+
+ if ((tag & ~PAGE_MASK) == 0 &&
+ (tag & PAGE_MASK) >= prom_reserved_base) {
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
+ cheetah_put_dtlb_data(i, 0x0UL);
+ }
+ }
+ } else {
+ /* Implement me :-) */
+ BUG();
}
}
@@ -401,7 +472,7 @@ struct prom_tlb_entry {
unsigned long tlb_tag;
unsigned long tlb_data;
};
-struct prom_tlb_entry prom_itlb[8], prom_dtlb[8];
+struct prom_tlb_entry prom_itlb[16], prom_dtlb[16];
void prom_world(int enter)
{
@@ -426,42 +497,53 @@ void prom_world(int enter)
__flush_nucleus_vptes();
/* Install PROM world. */
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 16; i++) {
if (prom_dtlb[i].tlb_ent != -1) {
- __asm__ __volatile__("stxa %0, [%1] %2"
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "membar #Sync"
: : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),
"i" (ASI_DMMU));
- membar("#Sync");
- spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent,
- prom_dtlb[i].tlb_data);
- membar("#Sync");
+ if (tlb_type == spitfire)
+ spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent,
+ prom_dtlb[i].tlb_data);
+ else if (tlb_type == cheetah)
+ cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent,
+ prom_dtlb[i].tlb_data);
}
-
if (prom_itlb[i].tlb_ent != -1) {
- __asm__ __volatile__("stxa %0, [%1] %2"
- : : "r" (prom_itlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),
- "i" (ASI_IMMU));
- membar("#Sync");
- spitfire_put_itlb_data(prom_itlb[i].tlb_ent,
- prom_itlb[i].tlb_data);
- membar("#Sync");
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "membar #Sync"
+ : : "r" (prom_itlb[i].tlb_tag),
+ "r" (TLB_TAG_ACCESS),
+ "i" (ASI_IMMU));
+ if (tlb_type == spitfire)
+ spitfire_put_itlb_data(prom_itlb[i].tlb_ent,
+ prom_itlb[i].tlb_data);
+ else if (tlb_type == cheetah)
+ cheetah_put_litlb_data(prom_itlb[i].tlb_ent,
+ prom_itlb[i].tlb_data);
}
}
} else {
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 16; i++) {
if (prom_dtlb[i].tlb_ent != -1) {
- __asm__ __volatile__("stxa %%g0, [%0] %1"
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
: : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
- membar("#Sync");
- spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, 0x0UL);
- membar("#Sync");
+ if (tlb_type == spitfire)
+ spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, 0x0UL);
+ else
+ cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent, 0x0UL);
}
if (prom_itlb[i].tlb_ent != -1) {
- __asm__ __volatile__("stxa %%g0, [%0] %1"
- : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
- membar("#Sync");
- spitfire_put_itlb_data(prom_itlb[i].tlb_ent, 0x0UL);
- membar("#Sync");
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : : "r" (TLB_TAG_ACCESS),
+ "i" (ASI_IMMU));
+ if (tlb_type == spitfire)
+ spitfire_put_itlb_data(prom_itlb[i].tlb_ent, 0x0UL);
+ else
+ cheetah_put_litlb_data(prom_itlb[i].tlb_ent, 0x0UL);
}
}
}
@@ -490,25 +572,14 @@ void inherit_locked_prom_mappings(int save_p)
* UNDOCUMENTED!!!!!! Thanks S(t)un!
*/
if (save_p) {
- for(i = 0; i < 8; i++) {
- prom_dtlb[i].tlb_ent = -1;
+ for (i = 0; i < 16; i++) {
prom_itlb[i].tlb_ent = -1;
+ prom_dtlb[i].tlb_ent = -1;
}
}
- for(i = 0; i < 63; i++) {
- unsigned long data;
-
-
- /* Spitfire Errata #32 workaround */
- __asm__ __volatile__("stxa %0, [%1] %2\n\t"
- "flush %%g6"
- : /* No outputs */
- : "r" (0),
- "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
-
- data = spitfire_get_dtlb_data(i);
- if((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
- unsigned long tag;
+ if (tlb_type == spitfire) {
+ for (i = 0; i < SPITFIRE_HIGHEST_LOCKED_TLBENT; i++) {
+ unsigned long data;
/* Spitfire Errata #32 workaround */
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
@@ -517,36 +588,36 @@ void inherit_locked_prom_mappings(int save_p)
: "r" (0),
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
- tag = spitfire_get_dtlb_tag(i);
- if(save_p) {
- prom_dtlb[dtlb_seen].tlb_ent = i;
- prom_dtlb[dtlb_seen].tlb_tag = tag;
- prom_dtlb[dtlb_seen].tlb_data = data;
+ data = spitfire_get_dtlb_data(i);
+ if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
+ unsigned long tag;
+
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
+ tag = spitfire_get_dtlb_tag(i);
+ if (save_p) {
+ prom_dtlb[dtlb_seen].tlb_ent = i;
+ prom_dtlb[dtlb_seen].tlb_tag = tag;
+ prom_dtlb[dtlb_seen].tlb_data = data;
+ }
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
+ spitfire_put_dtlb_data(i, 0x0UL);
+
+ dtlb_seen++;
+ if (dtlb_seen > 15)
+ break;
}
- __asm__ __volatile__("stxa %%g0, [%0] %1"
- : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
- membar("#Sync");
- spitfire_put_dtlb_data(i, 0x0UL);
- membar("#Sync");
-
- dtlb_seen++;
- if(dtlb_seen > 7)
- break;
}
- }
- for(i = 0; i < 63; i++) {
- unsigned long data;
-
- /* Spitfire Errata #32 workaround */
- __asm__ __volatile__("stxa %0, [%1] %2\n\t"
- "flush %%g6"
- : /* No outputs */
- : "r" (0),
- "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
-
- data = spitfire_get_itlb_data(i);
- if((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
- unsigned long tag;
+
+ for (i = 0; i < SPITFIRE_HIGHEST_LOCKED_TLBENT; i++) {
+ unsigned long data;
/* Spitfire Errata #32 workaround */
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
@@ -555,22 +626,84 @@ void inherit_locked_prom_mappings(int save_p)
: "r" (0),
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
- tag = spitfire_get_itlb_tag(i);
- if(save_p) {
- prom_itlb[itlb_seen].tlb_ent = i;
- prom_itlb[itlb_seen].tlb_tag = tag;
- prom_itlb[itlb_seen].tlb_data = data;
+ data = spitfire_get_itlb_data(i);
+ if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
+ unsigned long tag;
+
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
+ tag = spitfire_get_itlb_tag(i);
+ if (save_p) {
+ prom_itlb[itlb_seen].tlb_ent = i;
+ prom_itlb[itlb_seen].tlb_tag = tag;
+ prom_itlb[itlb_seen].tlb_data = data;
+ }
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
+ spitfire_put_itlb_data(i, 0x0UL);
+
+ itlb_seen++;
+ if (itlb_seen > 15)
+ break;
+ }
+ }
+ } else if (tlb_type == cheetah) {
+ for (i = 0; i < CHEETAH_HIGHEST_LOCKED_TLBENT; i++) {
+ unsigned long data;
+
+ data = cheetah_get_ldtlb_data(i);
+ if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
+ unsigned long tag;
+
+ tag = cheetah_get_ldtlb_tag(i);
+ if (save_p) {
+ prom_dtlb[dtlb_seen].tlb_ent = i;
+ prom_dtlb[dtlb_seen].tlb_tag = tag;
+ prom_dtlb[dtlb_seen].tlb_data = data;
+ }
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
+ cheetah_put_ldtlb_data(i, 0x0UL);
+
+ dtlb_seen++;
+ if (dtlb_seen > 15)
+ break;
}
- __asm__ __volatile__("stxa %%g0, [%0] %1"
- : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
- membar("#Sync");
- spitfire_put_itlb_data(i, 0x0UL);
- membar("#Sync");
-
- itlb_seen++;
- if(itlb_seen > 7)
- break;
}
+
+ for (i = 0; i < CHEETAH_HIGHEST_LOCKED_TLBENT; i++) {
+ unsigned long data;
+
+ data = cheetah_get_litlb_data(i);
+ if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
+ unsigned long tag;
+
+ tag = cheetah_get_litlb_tag(i);
+ if (save_p) {
+ prom_itlb[itlb_seen].tlb_ent = i;
+ prom_itlb[itlb_seen].tlb_tag = tag;
+ prom_itlb[itlb_seen].tlb_data = data;
+ }
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
+ cheetah_put_litlb_data(i, 0x0UL);
+
+ itlb_seen++;
+ if (itlb_seen > 15)
+ break;
+ }
+ }
+ } else {
+ /* Implement me :-) */
+ BUG();
}
if (save_p)
prom_ditlb_set = 1;
@@ -581,25 +714,32 @@ void prom_reload_locked(void)
{
int i;
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 16; i++) {
if (prom_dtlb[i].tlb_ent != -1) {
- __asm__ __volatile__("stxa %0, [%1] %2"
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "membar #Sync"
: : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),
"i" (ASI_DMMU));
- membar("#Sync");
- spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent,
- prom_dtlb[i].tlb_data);
- membar("#Sync");
+ if (tlb_type == spitfire)
+ spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent,
+ prom_dtlb[i].tlb_data);
+ else if (tlb_type == cheetah)
+ cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent,
+ prom_dtlb[i].tlb_data);
}
if (prom_itlb[i].tlb_ent != -1) {
- __asm__ __volatile__("stxa %0, [%1] %2"
- : : "r" (prom_itlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),
- "i" (ASI_IMMU));
- membar("#Sync");
- spitfire_put_itlb_data(prom_itlb[i].tlb_ent,
- prom_itlb[i].tlb_data);
- membar("#Sync");
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "membar #Sync"
+ : : "r" (prom_itlb[i].tlb_tag),
+ "r" (TLB_TAG_ACCESS),
+ "i" (ASI_IMMU));
+ if (tlb_type == spitfire)
+ spitfire_put_itlb_data(prom_itlb[i].tlb_ent,
+ prom_itlb[i].tlb_data);
+ else
+ cheetah_put_litlb_data(prom_itlb[i].tlb_ent,
+ prom_itlb[i].tlb_data);
}
}
}
@@ -607,22 +747,38 @@ void prom_reload_locked(void)
void __flush_dcache_range(unsigned long start, unsigned long end)
{
unsigned long va;
- int n = 0;
- for (va = start; va < end; va += 32) {
- spitfire_put_dcache_tag(va & 0x3fe0, 0x0);
- if (++n >= 512)
- break;
+ if (tlb_type == spitfire) {
+ int n = 0;
+
+ for (va = start; va < end; va += 32) {
+ spitfire_put_dcache_tag(va & 0x3fe0, 0x0);
+ if (++n >= 512)
+ break;
+ }
+ } else {
+ start = __pa(start);
+ end = __pa(end);
+ for (va = start; va < end; va += 32)
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (va),
+ "i" (ASI_DCACHE_INVALIDATE));
}
}
void __flush_cache_all(void)
{
- unsigned long va;
-
- flushw_all();
- for(va = 0; va < (PAGE_SIZE << 1); va += 32)
- spitfire_put_icache_tag(va, 0x0);
+ /* Cheetah should be fine here too. */
+ if (tlb_type == spitfire) {
+ unsigned long va;
+
+ flushw_all();
+ for (va = 0; va < (PAGE_SIZE << 1); va += 32)
+ spitfire_put_icache_tag(va, 0x0);
+ __asm__ __volatile__("flush %g6");
+ }
}
/* If not locked, zap it. */
@@ -636,38 +792,41 @@ void __flush_tlb_all(void)
"wrpr %0, %1, %%pstate"
: "=r" (pstate)
: "i" (PSTATE_IE));
- for(i = 0; i < 64; i++) {
- /* Spitfire Errata #32 workaround */
- __asm__ __volatile__("stxa %0, [%1] %2\n\t"
- "flush %%g6"
- : /* No outputs */
- : "r" (0),
- "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
-
- if(!(spitfire_get_dtlb_data(i) & _PAGE_L)) {
- __asm__ __volatile__("stxa %%g0, [%0] %1"
- : /* no outputs */
- : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
- membar("#Sync");
- spitfire_put_dtlb_data(i, 0x0UL);
- membar("#Sync");
- }
+ if (tlb_type == spitfire) {
+ for (i = 0; i < 64; i++) {
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
- /* Spitfire Errata #32 workaround */
- __asm__ __volatile__("stxa %0, [%1] %2\n\t"
- "flush %%g6"
- : /* No outputs */
- : "r" (0),
- "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+ if (!(spitfire_get_dtlb_data(i) & _PAGE_L)) {
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
+ spitfire_put_dtlb_data(i, 0x0UL);
+ }
- if(!(spitfire_get_itlb_data(i) & _PAGE_L)) {
- __asm__ __volatile__("stxa %%g0, [%0] %1"
- : /* no outputs */
- : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
- membar("#Sync");
- spitfire_put_itlb_data(i, 0x0UL);
- membar("#Sync");
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
+ if (!(spitfire_get_itlb_data(i) & _PAGE_L)) {
+ __asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
+ spitfire_put_itlb_data(i, 0x0UL);
+ }
}
+ } else if (tlb_type == cheetah) {
+ cheetah_flush_dtlb_all();
+ cheetah_flush_itlb_all();
}
__asm__ __volatile__("wrpr %0, 0, %%pstate"
: : "r" (pstate));
@@ -709,7 +868,7 @@ void get_new_mmu_context(struct mm_struct *mm)
mmu_context_bmap[1] = 0;
mmu_context_bmap[2] = 0;
mmu_context_bmap[3] = 0;
- for(i = 4; i < CTX_BMAP_SLOTS; i += 4) {
+ for (i = 4; i < CTX_BMAP_SLOTS; i += 4) {
mmu_context_bmap[i + 0] = 0;
mmu_context_bmap[i + 1] = 0;
mmu_context_bmap[i + 2] = 0;
@@ -731,23 +890,6 @@ out:
struct pgtable_cache_struct pgt_quicklists;
#endif
-/* For PMDs we don't care about the color, writes are
- * only done via Dcache which is write-thru, so non-Dcache
- * reads will always see correct data.
- */
-pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
-{
- pmd_t *pmd;
-
- pmd = (pmd_t *) __get_free_page(GFP_KERNEL);
- if(pmd) {
- memset(pmd, 0, PAGE_SIZE);
- pgd_set(pgd, pmd);
- return pmd + offset;
- }
- return NULL;
-}
-
/* OK, we have to color these pages because during DTLB
* protection faults we set the dirty bit via a non-Dcache
* enabled mapping in the VPTE area. The kernel can end
@@ -762,9 +904,10 @@ pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
* 3) Process faults back in the page, the old pre-dirtied copy
* is provided and here is the corruption.
*/
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset, unsigned long color)
+pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
struct page *page = alloc_pages(GFP_KERNEL, 1);
+ unsigned long color = ((address >> (PAGE_SHIFT + 10)) & 1UL);
if (page) {
unsigned long *to_free;
@@ -788,8 +931,7 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset, unsigned long color)
pte_quicklist[color ^ 0x1] = to_free;
pgtable_cache_size++;
- pmd_set(pmd, pte);
- return pte + offset;
+ return pte;
}
return NULL;
}
@@ -798,31 +940,77 @@ void sparc_ultra_dump_itlb(void)
{
int slot;
- printk ("Contents of itlb: ");
- for (slot = 0; slot < 14; slot++) printk (" ");
- printk ("%2x:%016lx,%016lx\n", 0, spitfire_get_itlb_tag(0), spitfire_get_itlb_data(0));
- for (slot = 1; slot < 64; slot+=3) {
- printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx %2x:%016lx,%016lx\n",
- slot, spitfire_get_itlb_tag(slot), spitfire_get_itlb_data(slot),
- slot+1, spitfire_get_itlb_tag(slot+1), spitfire_get_itlb_data(slot+1),
- slot+2, spitfire_get_itlb_tag(slot+2), spitfire_get_itlb_data(slot+2));
- }
+ if (tlb_type == spitfire) {
+ printk ("Contents of itlb: ");
+ for (slot = 0; slot < 14; slot++) printk (" ");
+ printk ("%2x:%016lx,%016lx\n",
+ 0,
+ spitfire_get_itlb_tag(0), spitfire_get_itlb_data(0));
+ for (slot = 1; slot < 64; slot+=3) {
+ printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx %2x:%016lx,%016lx\n",
+ slot,
+ spitfire_get_itlb_tag(slot), spitfire_get_itlb_data(slot),
+ slot+1,
+ spitfire_get_itlb_tag(slot+1), spitfire_get_itlb_data(slot+1),
+ slot+2,
+ spitfire_get_itlb_tag(slot+2), spitfire_get_itlb_data(slot+2));
+ }
+ } else if (tlb_type == cheetah) {
+ printk ("Contents of itlb0:\n");
+ for (slot = 0; slot < 16; slot+=2) {
+ printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n",
+ slot,
+ cheetah_get_litlb_tag(slot), cheetah_get_litlb_data(slot),
+ slot+1,
+ cheetah_get_litlb_tag(slot+1), cheetah_get_litlb_data(slot+1));
+ }
+ printk ("Contents of itlb2:\n");
+ for (slot = 0; slot < 128; slot+=2) {
+ printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n",
+ slot,
+ cheetah_get_itlb_tag(slot), cheetah_get_itlb_data(slot),
+ slot+1,
+ cheetah_get_itlb_tag(slot+1), cheetah_get_itlb_data(slot+1));
+ }
+ }
}
void sparc_ultra_dump_dtlb(void)
{
int slot;
- printk ("Contents of dtlb: ");
- for (slot = 0; slot < 14; slot++) printk (" ");
- printk ("%2x:%016lx,%016lx\n", 0, spitfire_get_dtlb_tag(0),
- spitfire_get_dtlb_data(0));
- for (slot = 1; slot < 64; slot+=3) {
- printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx %2x:%016lx,%016lx\n",
- slot, spitfire_get_dtlb_tag(slot), spitfire_get_dtlb_data(slot),
- slot+1, spitfire_get_dtlb_tag(slot+1), spitfire_get_dtlb_data(slot+1),
- slot+2, spitfire_get_dtlb_tag(slot+2), spitfire_get_dtlb_data(slot+2));
- }
+ if (tlb_type == spitfire) {
+ printk ("Contents of dtlb: ");
+ for (slot = 0; slot < 14; slot++) printk (" ");
+ printk ("%2x:%016lx,%016lx\n", 0,
+ spitfire_get_dtlb_tag(0), spitfire_get_dtlb_data(0));
+ for (slot = 1; slot < 64; slot+=3) {
+ printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx %2x:%016lx,%016lx\n",
+ slot,
+ spitfire_get_dtlb_tag(slot), spitfire_get_dtlb_data(slot),
+ slot+1,
+ spitfire_get_dtlb_tag(slot+1), spitfire_get_dtlb_data(slot+1),
+ slot+2,
+ spitfire_get_dtlb_tag(slot+2), spitfire_get_dtlb_data(slot+2));
+ }
+ } else if (tlb_type == cheetah) {
+ printk ("Contents of dtlb0:\n");
+ for (slot = 0; slot < 16; slot+=2) {
+ printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n",
+ slot,
+ cheetah_get_ldtlb_tag(slot), cheetah_get_ldtlb_data(slot),
+ slot+1,
+ cheetah_get_ldtlb_tag(slot+1), cheetah_get_ldtlb_data(slot+1));
+ }
+ printk ("Contents of dtlb2:\n");
+ for (slot = 0; slot < 512; slot+=2) {
+ printk ("%2x:%016lx,%016lx %2x:%016lx,%016lx\n",
+ slot,
+ cheetah_get_dtlb_tag(slot), cheetah_get_dtlb_data(slot),
+ slot+1,
+ cheetah_get_dtlb_tag(slot+1), cheetah_get_dtlb_data(slot+1));
+ }
+ }
}
extern unsigned long cmdline_memory_size;
@@ -959,20 +1147,35 @@ void __init paging_init(void)
pt = phys_base | _PAGE_VALID | _PAGE_SZ4MB;
pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W;
__save_and_cli(flags);
- __asm__ __volatile__("
- stxa %1, [%0] %3
- stxa %2, [%5] %4
- membar #Sync
- flush %%g6
- nop
- nop
- nop"
- : /* No outputs */
- : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt),
- "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3)
- : "memory");
- if (((unsigned long)&_end) >= KERNBASE + 0x340000) {
- second_alias_page = alias_base + 0x400000;
+ if (tlb_type == spitfire) {
+ __asm__ __volatile__("
+ stxa %1, [%0] %3
+ stxa %2, [%5] %4
+ membar #Sync
+ flush %%g6
+ nop
+ nop
+ nop"
+ : /* No outputs */
+ : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt),
+ "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3)
+ : "memory");
+ if (((unsigned long)&_end) >= KERNBASE + 0x340000) {
+ second_alias_page = alias_base + 0x400000;
+ __asm__ __volatile__("
+ stxa %1, [%0] %3
+ stxa %2, [%5] %4
+ membar #Sync
+ flush %%g6
+ nop
+ nop
+ nop"
+ : /* No outputs */
+ : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000),
+ "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (60 << 3)
+ : "memory");
+ }
+ } else if (tlb_type == cheetah) {
__asm__ __volatile__("
stxa %1, [%0] %3
stxa %2, [%5] %4
@@ -982,9 +1185,24 @@ void __init paging_init(void)
nop
nop"
: /* No outputs */
- : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000),
- "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (60 << 3)
+ : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt),
+ "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (13<<3))
: "memory");
+ if (((unsigned long)&_end) >= KERNBASE + 0x340000) {
+ second_alias_page = alias_base + 0x400000;
+ __asm__ __volatile__("
+ stxa %1, [%0] %3
+ stxa %2, [%5] %4
+ membar #Sync
+ flush %%g6
+ nop
+ nop
+ nop"
+ : /* No outputs */
+ : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000),
+ "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (12<<3))
+ : "memory");
+ }
}
__restore_flags(flags);
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
index daaf580a0..b9b25bb84 100644
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.48 2000/11/06 06:59:04 davem Exp $
+/* $Id: ultra.S,v 1.54 2001/03/22 07:26:04 davem Exp $
* ultra.S: Don't expand these all over the place...
*
* Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
@@ -10,6 +10,22 @@
#include <asm/page.h>
#include <asm/spitfire.h>
+ /* Basically, all this madness has to do with the
+ * fact that Cheetah does not support IMMU flushes
+ * out of the secondary context. Someone needs to
+ * throw a south lake birthday party for the folks
+ * in Microelectronics who refused to fix this shit.
+ */
+#define BRANCH_IF_CHEETAH(tmp1, tmp2, label) \
+ rdpr %ver, %tmp1; \
+ sethi %hi(0x003e0014), %tmp2; \
+ srlx %tmp1, 32, %tmp1; \
+ or %tmp2, %lo(0x003e0014), %tmp2; \
+ cmp %tmp1, %tmp2; \
+ be,pn %icc, label; \
+ nop; \
+ nop;
+
/* This file is meant to be read efficiently by the CPU, not humans.
* Staraj sie tego nikomu nie pierdolnac...
*/
@@ -17,37 +33,77 @@
.align 32
.globl __flush_tlb_page, __flush_tlb_mm, __flush_tlb_range
__flush_tlb_page: /* %o0=(ctx & 0x3ff), %o1=page&PAGE_MASK, %o2=SECONDARY_CONTEXT */
-/*IC1*/ ldxa [%o2] ASI_DMMU, %g2
+/*IC1*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_page)
+__spitfire_flush_tlb_page:
+/*IC2*/ ldxa [%o2] ASI_DMMU, %g2
cmp %g2, %o0
- bne,pn %icc, __flush_tlb_page_slow
+ bne,pn %icc, __spitfire_flush_tlb_page_slow
or %o1, 0x10, %g3
stxa %g0, [%g3] ASI_DMMU_DEMAP
stxa %g0, [%g3] ASI_IMMU_DEMAP
retl
flush %g6
+__cheetah_flush_tlb_page:
+/*IC3*/ rdpr %pstate, %g5
+ andn %g5, PSTATE_IE, %g2
+ wrpr %g2, 0x0, %pstate
+ wrpr %g0, 1, %tl
+ mov PRIMARY_CONTEXT, %o2
+ ldxa [%o2] ASI_DMMU, %g2
+ stxa %o0, [%o2] ASI_DMMU
+ stxa %g0, [%o1] ASI_DMMU_DEMAP
+/*IC4*/ stxa %g0, [%o1] ASI_IMMU_DEMAP
+ stxa %g2, [%o2] ASI_DMMU
+ flush %g6
+ wrpr %g0, 0, %tl
+ retl
+ wrpr %g5, 0x0, %pstate
+ nop
+ nop
__flush_tlb_mm: /* %o0=(ctx & 0x3ff), %o1=SECONDARY_CONTEXT */
-/*IC2*/ ldxa [%o1] ASI_DMMU, %g2
+/*IC5*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_mm)
+__spitfire_flush_tlb_mm:
+/*IC6*/ ldxa [%o1] ASI_DMMU, %g2
cmp %g2, %o0
- bne,pn %icc, __flush_tlb_mm_slow
+ bne,pn %icc, __spitfire_flush_tlb_mm_slow
mov 0x50, %g3
stxa %g0, [%g3] ASI_DMMU_DEMAP
stxa %g0, [%g3] ASI_IMMU_DEMAP
retl
flush %g6
+__cheetah_flush_tlb_mm:
+/*IC7*/ rdpr %pstate, %g5
+ andn %g5, PSTATE_IE, %g2
+ wrpr %g2, 0x0, %pstate
+ wrpr %g0, 1, %tl
+ mov PRIMARY_CONTEXT, %o2
+ mov 0x40, %g3
+ ldxa [%o2] ASI_DMMU, %g2
+ stxa %o0, [%o2] ASI_DMMU
+/*IC8*/ stxa %g0, [%g3] ASI_DMMU_DEMAP
+ stxa %g0, [%g3] ASI_IMMU_DEMAP
+ stxa %g2, [%o2] ASI_DMMU
+ flush %g6
+ wrpr %g0, 0, %tl
+ retl
+ wrpr %g5, 0x0, %pstate
+ nop
__flush_tlb_range: /* %o0=(ctx&0x3ff), %o1=start&PAGE_MASK, %o2=SECONDARY_CONTEXT,
* %o3=end&PAGE_MASK, %o4=PAGE_SIZE, %o5=(end - start)
*/
+/*IC9*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_range)
+__spitfire_flush_tlb_range:
#define TLB_MAGIC 207 /* Students, do you know how I calculated this? -DaveM */
-/*IC3*/ cmp %o5, %o4
+/*IC10*/cmp %o5, %o4
bleu,pt %xcc, __flush_tlb_page
srlx %o5, 13, %g5
cmp %g5, TLB_MAGIC
- bgeu,pn %icc, __flush_tlb_range_constant_time
+ bgeu,pn %icc, __spitfire_flush_tlb_range_constant_time
or %o1, 0x10, %g5
ldxa [%o2] ASI_DMMU, %g2
cmp %g2, %o0
-__flush_tlb_range_page_by_page:
-/*IC4*/ bne,pn %icc, __flush_tlb_range_pbp_slow
+__spitfire_flush_tlb_range_page_by_page:
+/*IC11*/bne,pn %icc, __spitfire_flush_tlb_range_pbp_slow
sub %o5, %o4, %o5
1: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP
stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP
@@ -55,10 +111,11 @@ __flush_tlb_range_page_by_page:
sub %o5, %o4, %o5
retl
flush %g6
-__flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
-/*IC5*/ rdpr %pstate, %g1
+__spitfire_flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
+/*IC12*/rdpr %pstate, %g1
wrpr %g1, PSTATE_IE, %pstate
mov TLB_TAG_ACCESS, %g3
+ /* XXX Spitfire dependency... */
mov (62 << 3), %g2
/* Spitfire Errata #32 workaround. */
@@ -70,7 +127,7 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
and %o4, 0x3ff, %o5
cmp %o5, %o0
bne,pt %icc, 2f
-/*IC6*/ andn %o4, 0x3ff, %o4
+/*IC13*/ andn %o4, 0x3ff, %o4
cmp %o4, %o1
blu,pt %xcc, 2f
cmp %o4, %o3
@@ -78,7 +135,7 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
2: ldxa [%g2] ASI_DTLB_TAG_READ, %o4
and %o4, 0x3ff, %o5
cmp %o5, %o0
-/*IC7*/ andn %o4, 0x3ff, %o4
+/*IC14*/andn %o4, 0x3ff, %o4
bne,pt %icc, 3f
cmp %o4, %o1
blu,pt %xcc, 3f
@@ -86,7 +143,7 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
blu,pn %xcc, 5f
nop
3: brnz,pt %g2, 1b
-/*IC8*/ sub %g2, (1 << 3), %g2
+/*IC15*/ sub %g2, (1 << 3), %g2
retl
wrpr %g1, 0x0, %pstate
4: stxa %g0, [%g3] ASI_IMMU
@@ -102,7 +159,7 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
nop
5: stxa %g0, [%g3] ASI_DMMU
-/*IC9*/ stxa %g0, [%g2] ASI_DTLB_DATA_ACCESS
+/*IC16*/stxa %g0, [%g2] ASI_DTLB_DATA_ACCESS
flush %g6
/* Spitfire Errata #32 workaround. */
@@ -114,45 +171,70 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
nop
.align 32
-__flush_tlb_mm_slow:
-/*IC10*/rdpr %pstate, %g1
+__cheetah_flush_tlb_range:
+ cmp %o5, %o4
+ bleu,pt %xcc, __cheetah_flush_tlb_page
+ nop
+/*IC17*/rdpr %pstate, %g5
+ andn %g5, PSTATE_IE, %g2
+ wrpr %g2, 0x0, %pstate
+ wrpr %g0, 1, %tl
+ mov PRIMARY_CONTEXT, %o2
+ sub %o5, %o4, %o5
+ ldxa [%o2] ASI_DMMU, %g2
+ stxa %o0, [%o2] ASI_DMMU
+
+/*IC18*/
+1: stxa %g0, [%o1 + %o5] ASI_DMMU_DEMAP
+ stxa %g0, [%o1 + %o5] ASI_IMMU_DEMAP
+ membar #Sync
+ brnz,pt %o5, 1b
+ sub %o5, %o4, %o5
+
+ stxa %g2, [%o2] ASI_DMMU
+ flush %g6
+ wrpr %g0, 0, %tl
+ retl
+/*IC19*/ wrpr %g5, 0x0, %pstate
+
+__spitfire_flush_tlb_mm_slow:
+ rdpr %pstate, %g1
wrpr %g1, PSTATE_IE, %pstate
stxa %o0, [%o1] ASI_DMMU
stxa %g0, [%g3] ASI_DMMU_DEMAP
stxa %g0, [%g3] ASI_IMMU_DEMAP
flush %g6
stxa %g2, [%o1] ASI_DMMU
- flush %g6
-/*IC11*/retl
+/*IC18*/flush %g6
+ retl
wrpr %g1, 0, %pstate
- .align 32
-__flush_tlb_page_slow:
-/*IC12*/rdpr %pstate, %g1
+__spitfire_flush_tlb_page_slow:
+ rdpr %pstate, %g1
wrpr %g1, PSTATE_IE, %pstate
stxa %o0, [%o2] ASI_DMMU
stxa %g0, [%g3] ASI_DMMU_DEMAP
stxa %g0, [%g3] ASI_IMMU_DEMAP
- flush %g6
+/*IC20*/flush %g6
stxa %g2, [%o2] ASI_DMMU
flush %g6
-/*IC13*/retl
+ retl
wrpr %g1, 0, %pstate
- .align 32
-__flush_tlb_range_pbp_slow:
-/*IC13*/rdpr %pstate, %g1
+__spitfire_flush_tlb_range_pbp_slow:
+ rdpr %pstate, %g1
wrpr %g1, PSTATE_IE, %pstate
stxa %o0, [%o2] ASI_DMMU
+/*IC21*/
2: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP
stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP
brnz,pt %o5, 2b
sub %o5, %o4, %o5
flush %g6
-/*IC14*/stxa %g2, [%o2] ASI_DMMU
+ stxa %g2, [%o2] ASI_DMMU
flush %g6
retl
- wrpr %g1, 0x0, %pstate
+/*IC22*/ wrpr %g1, 0x0, %pstate
.align 32
.globl __flush_icache_page
@@ -210,6 +292,27 @@ iflush2:sub %o1, 0x20, %g3
.globl __flush_dcache_page
__flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
sub %o0, %g4, %o0
+
+ rdpr %ver, %g1
+ sethi %hi(0x003e0014), %g2
+ srlx %g1, 32, %g1
+ or %g2, %lo(0x003e0014), %g2
+ cmp %g1, %g2
+ bne,pt %icc, flush_dcpage_spitfire
+ nop
+
+flush_dcpage_cheetah:
+ sethi %hi(8192), %o4
+1: subcc %o4, (1 << 5), %o4
+ stxa %g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
+ membar #Sync
+ bne,pt %icc, 1b
+ nop
+ /* I-cache flush never needed on Cheetah, see callers. */
+ retl
+ nop
+
+flush_dcpage_spitfire:
clr %o4
srlx %o0, 11, %o0
sethi %hi(1 << 14), %o2
@@ -317,18 +420,18 @@ __update_mmu_cache: /* %o0=vma, %o1=address, %o2=pte */
.align 32
.globl xcall_flush_tlb_page, xcall_flush_tlb_mm, xcall_flush_tlb_range
xcall_flush_tlb_page:
- mov SECONDARY_CONTEXT, %g2
- or %g1, 0x10, %g4
+ mov PRIMARY_CONTEXT, %g2
ldxa [%g2] ASI_DMMU, %g3
stxa %g5, [%g2] ASI_DMMU
- stxa %g0, [%g4] ASI_DMMU_DEMAP
- stxa %g0, [%g4] ASI_IMMU_DEMAP
+ stxa %g0, [%g1] ASI_DMMU_DEMAP
+ stxa %g0, [%g1] ASI_IMMU_DEMAP
stxa %g3, [%g2] ASI_DMMU
retry
+ nop
xcall_flush_tlb_mm:
- mov SECONDARY_CONTEXT, %g2
- mov 0x50, %g4
+ mov PRIMARY_CONTEXT, %g2
+ mov 0x40, %g4
ldxa [%g2] ASI_DMMU, %g3
stxa %g5, [%g2] ASI_DMMU
stxa %g0, [%g4] ASI_DMMU_DEMAP
@@ -343,20 +446,21 @@ xcall_flush_tlb_range:
andn %g7, %g2, %g7
sub %g7, %g1, %g3
add %g2, 1, %g2
- orcc %g1, 0x10, %g1
srlx %g3, 13, %g4
-
cmp %g4, 96
+
bgu,pn %icc, xcall_flush_tlb_mm
- mov SECONDARY_CONTEXT, %g4
+ mov PRIMARY_CONTEXT, %g4
ldxa [%g4] ASI_DMMU, %g7
sub %g3, %g2, %g3
stxa %g5, [%g4] ASI_DMMU
nop
nop
+ nop
1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP
+ membar #Sync
brnz,pt %g3, 1b
sub %g3, %g2, %g3
stxa %g7, [%g4] ASI_DMMU
@@ -433,7 +537,8 @@ errata32_hwbug:
/* These two are not performance critical... */
.globl xcall_flush_tlb_all
xcall_flush_tlb_all:
-
+ BRANCH_IF_CHEETAH(g2, g3, __cheetah_xcall_flush_tlb_all)
+__spitfire_xcall_flush_tlb_all:
/* Spitfire Errata #32 workaround. */
sethi %hi(errata32_hwbug), %g4
stx %g0, [%g4 + %lo(errata32_hwbug)]
@@ -475,12 +580,21 @@ xcall_flush_tlb_all:
flush %g6
retry
+__cheetah_xcall_flush_tlb_all:
+ mov 0x80, %g2
+ stxa %g0, [%g2] ASI_DMMU_DEMAP
+ stxa %g0, [%g2] ASI_IMMU_DEMAP
+ retry
+
.globl xcall_flush_cache_all
xcall_flush_cache_all:
+ BRANCH_IF_CHEETAH(g2, g3, __cheetah_xcall_flush_cache_all)
+__spitfire_xcall_flush_cache_all:
sethi %hi(16383), %g2
or %g2, %lo(16383), %g2
clr %g3
1: stxa %g0, [%g3] ASI_IC_TAG
+ membar #Sync
add %g3, 32, %g3
cmp %g3, %g2
bleu,pt %xcc, 1b
@@ -488,6 +602,13 @@ xcall_flush_cache_all:
flush %g6
retry
+ /* Cheetah's caches are fully coherent in the sense that
+ * caches are flushed here. We need to verify this and
+ * really just not even send out the xcall at the top level.
+ */
+__cheetah_xcall_flush_cache_all:
+ retry
+
.globl xcall_call_function
xcall_call_function:
mov TLB_TAG_ACCESS, %g5 ! wheee...
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 15c8736ef..8d56b895a 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.31 2000/12/14 22:57:25 davem Exp $
+/* $Id: misc.c,v 1.32 2001/03/24 09:36:11 davem Exp $
* misc.c: Miscelaneous syscall emulation for Solaris
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -92,12 +92,12 @@ static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 o
ret_type = flags & _MAP_NEW;
flags &= ~_MAP_NEW;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
retval = do_mmap(file,
(unsigned long) addr, (unsigned long) len,
(unsigned long) prot, (unsigned long) flags, off);
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
if(!ret_type)
retval = ((retval < 0xf0000000) ? 0 : retval);