2020-12-18 20:46:03

by Sam Ravnborg

[permalink] [raw]
Subject: [RFC PATCH 0/13] sparc32: sunset sun4m and sun4d

The sun4m and sun4d based SPARC machines was very popular in the
90'ties and was then replaced by the more powerful sparc64
class of machines.
Today there is only Gentoo that to my best knowledge supports
sparc32 and people have moved on to more capable HW.

Cobham Gaisler have variants of the LEON processer that
runs sparc32 - and they are in production today.

With this patchset I propose to sunset sun4m and sun4d and move
focus to a more streamlined support for LEON.

One downside is that qemu supports sun4m - and we may loose
some testing possibilities when sun4m is dropped. qemu supports
LEON to some degree - I have not yet tried it out.

Andreas from Gaisler have indicated that they may be more active
upstream on sparc32 - and this will only be easier with a kernel
where the legacy stuff is dropped.

I decided to divide up the patches to make it possible to review
the set as some of the patches touches assembler and these parts
could use some extra eyes if we move forward with this.

For now it builds with the configurations I have tried.

Looking forward for feedback if sunsetting is a good idea or not.

Sam

Sam Ravnborg (13):
sparc32: Drop sun4m/sun4d support from head_32.S
sparc32: Drop floppy support
sparc32: Drop sun4m specific led driver
sparc32: Drop auxio support
sparc32: Drop run-time patching of ipi trap
sparc32: Drop patching of interrupt vector
sparc32: Drop sun4m/sun4d specific irq handling
sparc32: Drop sun4d/sun4m smp support
sparc32: Drop pcic support
sparc32: Drop mbus support
sparc32: Drop unused mmu models
sparc32: drop check for sparc_model
sparc32: drop use of sparc_config

Note: I dunno why git does not see floppy_64.h=>floppy.h as a rename??

arch/sparc/Kconfig | 16 +-
arch/sparc/include/asm/auxio_32.h | 73 +---
arch/sparc/include/asm/cpu_type.h | 18 -
arch/sparc/include/asm/elf_32.h | 2 -
arch/sparc/include/asm/floppy.h | 786 ++++++++++++++++++++++++++++++++-
arch/sparc/include/asm/floppy_32.h | 393 -----------------
arch/sparc/include/asm/floppy_64.h | 779 ---------------------------------
arch/sparc/include/asm/io_32.h | 4 +-
arch/sparc/include/asm/irq_32.h | 1 -
arch/sparc/include/asm/mbus.h | 97 -----
arch/sparc/include/asm/mxcc.h | 138 ------
arch/sparc/include/asm/pcic.h | 130 ------
arch/sparc/include/asm/pgtable_32.h | 24 -
arch/sparc/include/asm/ross.h | 192 --------
arch/sparc/include/asm/swift.h | 107 -----
arch/sparc/include/asm/timer_32.h | 1 +
arch/sparc/include/asm/tsunami.h | 65 ---
arch/sparc/include/asm/viking.h | 255 -----------
arch/sparc/kernel/Makefile | 8 +-
arch/sparc/kernel/apc.c | 14 -
arch/sparc/kernel/auxio_32.c | 140 ------
arch/sparc/kernel/cpu.c | 1 -
arch/sparc/kernel/devices.c | 10 +-
arch/sparc/kernel/entry.S | 354 +--------------
arch/sparc/kernel/head_32.S | 190 +-------
arch/sparc/kernel/ioport.c | 6 +-
arch/sparc/kernel/irq.h | 35 +-
arch/sparc/kernel/irq_32.c | 127 +-----
arch/sparc/kernel/kernel.h | 28 --
arch/sparc/kernel/led.c | 146 -------
arch/sparc/kernel/leon_kernel.c | 43 +-
arch/sparc/kernel/leon_pmc.c | 14 +-
arch/sparc/kernel/leon_smp.c | 3 -
arch/sparc/kernel/of_device_32.c | 4 +-
arch/sparc/kernel/pcic.c | 841 ------------------------------------
arch/sparc/kernel/pmc.c | 10 -
arch/sparc/kernel/process_32.c | 10 -
arch/sparc/kernel/setup_32.c | 80 +---
arch/sparc/kernel/smp_32.c | 102 +----
arch/sparc/kernel/sun4d_irq.c | 519 ----------------------
arch/sparc/kernel/sun4d_smp.c | 413 ------------------
arch/sparc/kernel/sun4m_irq.c | 240 ----------
arch/sparc/kernel/sun4m_smp.c | 273 ------------
arch/sparc/kernel/time_32.c | 114 +++--
arch/sparc/kernel/ttable_32.S | 9 +-
arch/sparc/mm/Makefile | 1 -
arch/sparc/mm/hypersparc.S | 414 ------------------
arch/sparc/mm/io-unit.c | 3 -
arch/sparc/mm/iommu.c | 49 +--
arch/sparc/mm/mm_32.h | 1 -
arch/sparc/mm/srmmu.c | 834 +----------------------------------
arch/sparc/mm/swift.S | 256 -----------
arch/sparc/mm/tsunami.S | 132 ------
arch/sparc/mm/viking.S | 284 ------------
arch/sparc/prom/misc_32.c | 2 -
55 files changed, 905 insertions(+), 7886 deletions(-)



2020-12-18 20:46:08

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 04/13] sparc32: Drop auxio support

auxio is not supported by LEON - so drop it.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Christian Brauner <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Dmitry Safonov <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/include/asm/auxio_32.h | 73 +---------------
arch/sparc/kernel/Makefile | 2 +-
arch/sparc/kernel/apc.c | 14 ---
arch/sparc/kernel/auxio_32.c | 140 ------------------------------
arch/sparc/kernel/devices.c | 3 -
arch/sparc/kernel/kernel.h | 4 -
arch/sparc/kernel/pmc.c | 10 ---
arch/sparc/kernel/process_32.c | 10 ---
arch/sparc/prom/misc_32.c | 2 -
9 files changed, 3 insertions(+), 255 deletions(-)
delete mode 100644 arch/sparc/kernel/auxio_32.c

diff --git a/arch/sparc/include/asm/auxio_32.h b/arch/sparc/include/asm/auxio_32.h
index 852457c7a265..e2335ddd359d 100644
--- a/arch/sparc/include/asm/auxio_32.h
+++ b/arch/sparc/include/asm/auxio_32.h
@@ -1,43 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * auxio.h: Definitions and code for the Auxiliary I/O register.
+ * Dummy definitions for the Auxiliary I/O register.
*
* Copyright (C) 1995 David S. Miller ([email protected])
*/
#ifndef _SPARC_AUXIO_H
#define _SPARC_AUXIO_H

-#include <asm/vaddrs.h>
-
-/* This register is an unsigned char in IO space. It does two things.
- * First, it is used to control the front panel LED light on machines
- * that have it (good for testing entry points to trap handlers and irq's)
- * Secondly, it controls various floppy drive parameters.
- */
-#define AUXIO_ORMEIN 0xf0 /* All writes must set these bits. */
-#define AUXIO_ORMEIN4M 0xc0 /* sun4m - All writes must set these bits. */
-#define AUXIO_FLPY_DENS 0x20 /* Floppy density, high if set. Read only. */
-#define AUXIO_FLPY_DCHG 0x10 /* A disk change occurred. Read only. */
-#define AUXIO_EDGE_ON 0x10 /* sun4m - On means Jumper block is in. */
-#define AUXIO_FLPY_DSEL 0x08 /* Drive select/start-motor. Write only. */
-#define AUXIO_LINK_TEST 0x08 /* sun4m - On means TPE Carrier detect. */
-
-/* Set the following to one, then zero, after doing a pseudo DMA transfer. */
-#define AUXIO_FLPY_TCNT 0x04 /* Floppy terminal count. Write only. */
-
-/* Set the following to zero to eject the floppy. */
-#define AUXIO_FLPY_EJCT 0x02 /* Eject floppy disk. Write only. */
-#define AUXIO_LED 0x01 /* On if set, off if unset. Read/Write */
-
-#ifndef __ASSEMBLY__
-
-/*
- * NOTE: these routines are implementation dependent--
- * understand the hardware you are querying!
- */
-void set_auxio(unsigned char bits_on, unsigned char bits_off);
-unsigned char get_auxio(void); /* .../asm/floppy.h */
-
/*
* The following routines are provided for driver-compatibility
* with sparc64 (primarily sunlance.c)
@@ -46,44 +15,6 @@ unsigned char get_auxio(void); /* .../asm/floppy.h */
#define AUXIO_LTE_ON 1
#define AUXIO_LTE_OFF 0

-/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
- *
- * on - AUXIO_LTE_ON or AUXIO_LTE_OFF
- */
-#define auxio_set_lte(on) \
-do { \
- if(on) { \
- set_auxio(AUXIO_LINK_TEST, 0); \
- } else { \
- set_auxio(0, AUXIO_LINK_TEST); \
- } \
-} while (0)
-
-#define AUXIO_LED_ON 1
-#define AUXIO_LED_OFF 0
-
-/* auxio_set_led - Set system front panel LED
- *
- * on - AUXIO_LED_ON or AUXIO_LED_OFF
- */
-#define auxio_set_led(on) \
-do { \
- if(on) { \
- set_auxio(AUXIO_LED, 0); \
- } else { \
- set_auxio(0, AUXIO_LED); \
- } \
-} while (0)
-
-#endif /* !(__ASSEMBLY__) */
-
-
-/* AUXIO2 (Power Off Control) */
-extern volatile u8 __iomem *auxio_power_register;
-
-#define AUXIO_POWER_DETECT_FAILURE 32
-#define AUXIO_POWER_CLEAR_FAILURE 2
-#define AUXIO_POWER_OFF 1
-
+#define auxio_set_lte(on)

#endif /* !(_SPARC_AUXIO_H) */
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index b6c9ca1d6c66..b2735fb29c89 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -84,7 +84,7 @@ obj-$(CONFIG_SMP) += trampoline_$(BITS).o smp_$(BITS).o
obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o leon_smp.o
obj-$(CONFIG_SPARC64_SMP) += hvtramp.o

-obj-y += auxio_$(BITS).o
+obj-$(CONFIG_SPARC64) += auxio_64.o
obj-$(CONFIG_SUN_PM) += apc.o pmc.o

obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c
index ecd05bc0a104..93f5934bbbe1 100644
--- a/arch/sparc/kernel/apc.c
+++ b/arch/sparc/kernel/apc.c
@@ -19,15 +19,9 @@
#include <asm/io.h>
#include <asm/oplib.h>
#include <linux/uaccess.h>
-#include <asm/auxio.h>
#include <asm/apc.h>
#include <asm/processor.h>

-/* Debugging
- *
- * #define APC_DEBUG_LED
- */
-
#define APC_MINOR MISC_DYNAMIC_MINOR
#define APC_OBPNAME "power-management"
#define APC_DEVNAME "apc"
@@ -60,15 +54,7 @@ __setup("apc=", apc_setup);
*/
static void apc_swift_idle(void)
{
-#ifdef APC_DEBUG_LED
- set_auxio(0x00, AUXIO_LED);
-#endif
-
apc_writeb(apc_readb(APC_IDLE_REG) | APC_IDLE_ON, APC_IDLE_REG);
-
-#ifdef APC_DEBUG_LED
- set_auxio(AUXIO_LED, 0x00);
-#endif
}

static inline void apc_free(struct platform_device *op)
diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c
deleted file mode 100644
index a32d588174f2..000000000000
--- a/arch/sparc/kernel/auxio_32.c
+++ /dev/null
@@ -1,140 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* auxio.c: Probing for the Sparc AUXIO register at boot time.
- *
- * Copyright (C) 1996 David S. Miller ([email protected])
- */
-
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/export.h>
-
-#include <asm/oplib.h>
-#include <asm/io.h>
-#include <asm/auxio.h>
-#include <asm/string.h> /* memset(), Linux has no bzero() */
-#include <asm/cpu_type.h>
-
-#include "kernel.h"
-
-/* Probe and map in the Auxiliary I/O register */
-
-/* auxio_register is not static because it is referenced
- * in entry.S::floppy_tdone
- */
-void __iomem *auxio_register = NULL;
-static DEFINE_SPINLOCK(auxio_lock);
-
-void __init auxio_probe(void)
-{
- phandle node, auxio_nd;
- struct linux_prom_registers auxregs[1];
- struct resource r;
-
- switch (sparc_cpu_model) {
- case sparc_leon:
- case sun4d:
- return;
- default:
- break;
- }
- node = prom_getchild(prom_root_node);
- auxio_nd = prom_searchsiblings(node, "auxiliary-io");
- if(!auxio_nd) {
- node = prom_searchsiblings(node, "obio");
- node = prom_getchild(node);
- auxio_nd = prom_searchsiblings(node, "auxio");
- if(!auxio_nd) {
-#ifdef CONFIG_PCI
- /* There may be auxio on Ebus */
- return;
-#else
- if(prom_searchsiblings(node, "leds")) {
- /* VME chassis sun4m machine, no auxio exists. */
- return;
- }
- prom_printf("Cannot find auxio node, cannot continue...\n");
- prom_halt();
-#endif
- }
- }
- if(prom_getproperty(auxio_nd, "reg", (char *) auxregs, sizeof(auxregs)) <= 0)
- return;
- prom_apply_obio_ranges(auxregs, 0x1);
- /* Map the register both read and write */
- r.flags = auxregs[0].which_io & 0xF;
- r.start = auxregs[0].phys_addr;
- r.end = auxregs[0].phys_addr + auxregs[0].reg_size - 1;
- auxio_register = of_ioremap(&r, 0, auxregs[0].reg_size, "auxio");
- /* Fix the address on sun4m. */
- if ((((unsigned long) auxregs[0].phys_addr) & 3) == 3)
- auxio_register += (3 - ((unsigned long)auxio_register & 3));
-
- set_auxio(AUXIO_LED, 0);
-}
-
-unsigned char get_auxio(void)
-{
- if(auxio_register)
- return sbus_readb(auxio_register);
- return 0;
-}
-EXPORT_SYMBOL(get_auxio);
-
-void set_auxio(unsigned char bits_on, unsigned char bits_off)
-{
- unsigned char regval;
- unsigned long flags;
- spin_lock_irqsave(&auxio_lock, flags);
- switch (sparc_cpu_model) {
- case sun4m:
- if(!auxio_register)
- break; /* VME chassis sun4m, no auxio. */
- regval = sbus_readb(auxio_register);
- sbus_writeb(((regval | bits_on) & ~bits_off) | AUXIO_ORMEIN4M,
- auxio_register);
- break;
- case sun4d:
- break;
- default:
- panic("Can't set AUXIO register on this machine.");
- }
- spin_unlock_irqrestore(&auxio_lock, flags);
-}
-EXPORT_SYMBOL(set_auxio);
-
-/* sun4m power control register (AUXIO2) */
-
-volatile u8 __iomem *auxio_power_register = NULL;
-
-void __init auxio_power_probe(void)
-{
- struct linux_prom_registers regs;
- phandle node;
- struct resource r;
-
- /* Attempt to find the sun4m power control node. */
- node = prom_getchild(prom_root_node);
- node = prom_searchsiblings(node, "obio");
- node = prom_getchild(node);
- node = prom_searchsiblings(node, "power");
- if (node == 0 || (s32)node == -1)
- return;
-
- /* Map the power control register. */
- if (prom_getproperty(node, "reg", (char *)&regs, sizeof(regs)) <= 0)
- return;
- prom_apply_obio_ranges(&regs, 1);
- memset(&r, 0, sizeof(r));
- r.flags = regs.which_io & 0xF;
- r.start = regs.phys_addr;
- r.end = regs.phys_addr + regs.reg_size - 1;
- auxio_power_register =
- (u8 __iomem *)of_ioremap(&r, 0, regs.reg_size, "auxpower");
-
- /* Display a quick message on the console. */
- if (auxio_power_register)
- printk(KERN_INFO "Power off control detected.\n");
-}
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c
index 23b6e50d4ada..b3c2d51b22c4 100644
--- a/arch/sparc/kernel/devices.c
+++ b/arch/sparc/kernel/devices.c
@@ -132,7 +132,4 @@ void __init device_scan(void)
0);
}
#endif /* !CONFIG_SMP */
-
- auxio_probe();
- auxio_power_probe();
}
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index c76e49032273..7328d13875e4 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -175,10 +175,6 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn);
/* windows.c */
void try_to_clear_window_buffer(struct pt_regs *regs, int who);

-/* auxio_32.c */
-void __init auxio_probe(void);
-void __init auxio_power_probe(void);
-
/* pcic.c */
extern void __iomem *pcic_regs;
void pcic_nmi(unsigned int pend, struct pt_regs *regs);
diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c
index b5c1eb33b951..441b9fbc27f1 100644
--- a/arch/sparc/kernel/pmc.c
+++ b/arch/sparc/kernel/pmc.c
@@ -17,12 +17,10 @@
#include <asm/io.h>
#include <asm/oplib.h>
#include <linux/uaccess.h>
-#include <asm/auxio.h>
#include <asm/processor.h>

/* Debug
*
- * #define PMC_DEBUG_LED
* #define PMC_NO_IDLE
*/

@@ -43,15 +41,7 @@ static u8 __iomem *regs;
*/
static void pmc_swift_idle(void)
{
-#ifdef PMC_DEBUG_LED
- set_auxio(0x00, AUXIO_LED);
-#endif
-
pmc_writeb(pmc_readb(PMC_IDLE_REG) | PMC_IDLE_ON, PMC_IDLE_REG);
-
-#ifdef PMC_DEBUG_LED
- set_auxio(AUXIO_LED, 0x00);
-#endif
}

static int pmc_probe(struct platform_device *op)
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index a02363735915..cf9ef387c6d5 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -30,7 +30,6 @@
#include <linux/slab.h>
#include <linux/cpu.h>

-#include <asm/auxio.h>
#include <asm/oplib.h>
#include <linux/uaccess.h>
#include <asm/page.h>
@@ -52,8 +51,6 @@ void (*sparc_idle)(void);

/*
* Power-off handler instantiation for pm.h compliance
- * This is done via auxio, but could be used as a fallback
- * handler when auxio is not present-- unused for now...
*/
void (*pm_power_off)(void) = machine_power_off;
EXPORT_SYMBOL(pm_power_off);
@@ -107,13 +104,6 @@ void machine_restart(char * cmd)

void machine_power_off(void)
{
- if (auxio_power_register &&
- (!of_node_is_type(of_console_device, "serial") || scons_pwroff)) {
- u8 power_register = sbus_readb(auxio_power_register);
- power_register |= AUXIO_POWER_OFF;
- sbus_writeb(power_register, auxio_power_register);
- }
-
machine_halt();
}

diff --git a/arch/sparc/prom/misc_32.c b/arch/sparc/prom/misc_32.c
index 625750924860..78dde6bfbf0f 100644
--- a/arch/sparc/prom/misc_32.c
+++ b/arch/sparc/prom/misc_32.c
@@ -13,7 +13,6 @@

#include <asm/openprom.h>
#include <asm/oplib.h>
-#include <asm/auxio.h>

extern void restore_current(void);

@@ -60,7 +59,6 @@ prom_cmdline(void)
(*(romvec->pv_abort))();
restore_current();
spin_unlock_irqrestore(&prom_lock, flags);
- set_auxio(AUXIO_LED, 0);
}

/* Drop into the prom, but completely terminate the program.
--
2.27.0

2020-12-18 20:46:10

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 03/13] sparc32: Drop sun4m specific led driver

The led driver is only relevant for the sun4m machines.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Christian Brauner <[email protected]>
Cc: Stephen Rothwell <[email protected]>
Cc: Alexey Dobriyan <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: [email protected]
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/Kconfig | 9 ---
arch/sparc/kernel/Makefile | 1 -
arch/sparc/kernel/led.c | 146 -------------------------------------
3 files changed, 156 deletions(-)
delete mode 100644 arch/sparc/kernel/led.c

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 2c6d8d834f9a..8447f5b7bb90 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -337,15 +337,6 @@ config SUN_PM
Enable power management and CPU standby features on supported
SPARC platforms.

-config SPARC_LED
- tristate "Sun4m LED driver"
- depends on SPARC32
- help
- This driver toggles the front-panel LED on sun4m systems
- in a user-specifiable manner. Its state can be probed
- by reading /proc/led and its blinking mode can be changed
- via writes to /proc/led
-
config SERIAL_CONSOLE
bool
depends on SPARC32
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index d3a0e072ebe8..b6c9ca1d6c66 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -89,7 +89,6 @@ obj-$(CONFIG_SUN_PM) += apc.o pmc.o

obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_MODULES) += sparc_ksyms.o
-obj-$(CONFIG_SPARC_LED) += led.o
obj-$(CONFIG_KGDB) += kgdb_$(BITS).o


diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c
deleted file mode 100644
index bd48575172c3..000000000000
--- a/arch/sparc/kernel/led.c
+++ /dev/null
@@ -1,146 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/uaccess.h>
-#include <linux/sched/loadavg.h>
-
-#include <asm/auxio.h>
-
-#define LED_MAX_LENGTH 8 /* maximum chars written to proc file */
-
-static inline void led_toggle(void)
-{
- unsigned char val = get_auxio();
- unsigned char on, off;
-
- if (val & AUXIO_LED) {
- on = 0;
- off = AUXIO_LED;
- } else {
- on = AUXIO_LED;
- off = 0;
- }
-
- set_auxio(on, off);
-}
-
-static struct timer_list led_blink_timer;
-static unsigned long led_blink_timer_timeout;
-
-static void led_blink(struct timer_list *unused)
-{
- unsigned long timeout = led_blink_timer_timeout;
-
- led_toggle();
-
- /* reschedule */
- if (!timeout) { /* blink according to load */
- led_blink_timer.expires = jiffies +
- ((1 + (avenrun[0] >> FSHIFT)) * HZ);
- } else { /* blink at user specified interval */
- led_blink_timer.expires = jiffies + (timeout * HZ);
- }
- add_timer(&led_blink_timer);
-}
-
-static int led_proc_show(struct seq_file *m, void *v)
-{
- if (get_auxio() & AUXIO_LED)
- seq_puts(m, "on\n");
- else
- seq_puts(m, "off\n");
- return 0;
-}
-
-static int led_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, led_proc_show, NULL);
-}
-
-static ssize_t led_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- char *buf = NULL;
-
- if (count > LED_MAX_LENGTH)
- count = LED_MAX_LENGTH;
-
- buf = memdup_user_nul(buffer, count);
- if (IS_ERR(buf))
- return PTR_ERR(buf);
-
- /* work around \n when echo'ing into proc */
- if (buf[count - 1] == '\n')
- buf[count - 1] = '\0';
-
- /* before we change anything we want to stop any running timers,
- * otherwise calls such as on will have no persistent effect
- */
- del_timer_sync(&led_blink_timer);
-
- if (!strcmp(buf, "on")) {
- auxio_set_led(AUXIO_LED_ON);
- } else if (!strcmp(buf, "toggle")) {
- led_toggle();
- } else if ((*buf > '0') && (*buf <= '9')) {
- led_blink_timer_timeout = simple_strtoul(buf, NULL, 10);
- led_blink(&led_blink_timer);
- } else if (!strcmp(buf, "load")) {
- led_blink_timer_timeout = 0;
- led_blink(&led_blink_timer);
- } else {
- auxio_set_led(AUXIO_LED_OFF);
- }
-
- kfree(buf);
-
- return count;
-}
-
-static const struct proc_ops led_proc_ops = {
- .proc_open = led_proc_open,
- .proc_read = seq_read,
- .proc_lseek = seq_lseek,
- .proc_release = single_release,
- .proc_write = led_proc_write,
-};
-
-static struct proc_dir_entry *led;
-
-#define LED_VERSION "0.1"
-
-static int __init led_init(void)
-{
- timer_setup(&led_blink_timer, led_blink, 0);
-
- led = proc_create("led", 0, NULL, &led_proc_ops);
- if (!led)
- return -ENOMEM;
-
- printk(KERN_INFO
- "led: version %s, Lars Kotthoff <[email protected]>\n",
- LED_VERSION);
-
- return 0;
-}
-
-static void __exit led_exit(void)
-{
- remove_proc_entry("led", NULL);
- del_timer_sync(&led_blink_timer);
-}
-
-module_init(led_init);
-module_exit(led_exit);
-
-MODULE_AUTHOR("Lars Kotthoff <[email protected]>");
-MODULE_DESCRIPTION("Provides control of the front LED on SPARC systems.");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(LED_VERSION);
--
2.27.0

2020-12-18 20:46:18

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 02/13] sparc32: Drop floppy support

LEON do not have floppy support so we can drop it

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Denis Efremov <[email protected]>
Cc: Willy Tarreau <[email protected]>
Cc: Christian Brauner <[email protected]>
Cc: [email protected]
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/Kconfig | 2 +-
arch/sparc/include/asm/floppy.h | 786 ++++++++++++++++++++++++++++-
arch/sparc/include/asm/floppy_32.h | 393 ---------------
arch/sparc/include/asm/floppy_64.h | 779 ----------------------------
arch/sparc/kernel/entry.S | 137 -----
arch/sparc/kernel/irq.h | 3 -
arch/sparc/kernel/irq_32.c | 93 ----
arch/sparc/kernel/kernel.h | 2 -
8 files changed, 779 insertions(+), 1416 deletions(-)
delete mode 100644 arch/sparc/include/asm/floppy_32.h
delete mode 100644 arch/sparc/include/asm/floppy_64.h

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index c9c34dc52b7d..2c6d8d834f9a 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -200,7 +200,7 @@ config GENERIC_CALIBRATE_DELAY

config ARCH_MAY_HAVE_PC_FDC
bool
- default y
+ default y if SPARC64

config EMULATED_CMPXCHG
bool
diff --git a/arch/sparc/include/asm/floppy.h b/arch/sparc/include/asm/floppy.h
index 4b315802e635..070c8c1f5c8f 100644
--- a/arch/sparc/include/asm/floppy.h
+++ b/arch/sparc/include/asm/floppy.h
@@ -1,9 +1,779 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef ___ASM_SPARC_FLOPPY_H
-#define ___ASM_SPARC_FLOPPY_H
-#if defined(__sparc__) && defined(__arch64__)
-#include <asm/floppy_64.h>
-#else
-#include <asm/floppy_32.h>
-#endif
-#endif
+/* floppy.h: Sparc specific parts of the Floppy driver.
+ *
+ * Copyright (C) 1996, 2007, 2008 David S. Miller ([email protected])
+ * Copyright (C) 1997 Jakub Jelinek ([email protected])
+ *
+ * Ultra/PCI support added: Sep 1997 Eddie C. Dost ([email protected])
+ */
+
+#ifndef __ASM_SPARC64_FLOPPY_H
+#define __ASM_SPARC64_FLOPPY_H
+
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/auxio.h>
+
+/*
+ * Define this to enable exchanging drive 0 and 1 if only drive 1 is
+ * probed on PCI machines.
+ */
+#undef PCI_FDC_SWAP_DRIVES
+
+
+/* References:
+ * 1) Netbsd Sun floppy driver.
+ * 2) NCR 82077 controller manual
+ * 3) Intel 82077 controller manual
+ */
+struct sun_flpy_controller {
+ volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
+ volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
+ volatile unsigned char dor_82077; /* Digital Output reg. */
+ volatile unsigned char tapectl_82077; /* Tape Control reg */
+ volatile unsigned char status_82077; /* Main Status Register. */
+#define drs_82077 status_82077 /* Digital Rate Select reg. */
+ volatile unsigned char data_82077; /* Data fifo. */
+ volatile unsigned char ___unused;
+ volatile unsigned char dir_82077; /* Digital Input reg. */
+#define dcr_82077 dir_82077 /* Config Control reg. */
+};
+
+/* You'll only ever find one controller on an Ultra anyways. */
+static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
+unsigned long fdc_status;
+static struct platform_device *floppy_op = NULL;
+
+struct sun_floppy_ops {
+ unsigned char (*fd_inb) (unsigned long port, unsigned int reg);
+ void (*fd_outb) (unsigned char value, unsigned long base,
+ unsigned int reg);
+ void (*fd_enable_dma) (void);
+ void (*fd_disable_dma) (void);
+ void (*fd_set_dma_mode) (int);
+ void (*fd_set_dma_addr) (char *);
+ void (*fd_set_dma_count) (int);
+ unsigned int (*get_dma_residue) (void);
+ int (*fd_request_irq) (void);
+ void (*fd_free_irq) (void);
+ int (*fd_eject) (int);
+};
+
+static struct sun_floppy_ops sun_fdops;
+
+#define fd_inb(base, reg) sun_fdops.fd_inb(base, reg)
+#define fd_outb(value, base, reg) sun_fdops.fd_outb(value, base, reg)
+#define fd_enable_dma() sun_fdops.fd_enable_dma()
+#define fd_disable_dma() sun_fdops.fd_disable_dma()
+#define fd_request_dma() (0) /* nothing... */
+#define fd_free_dma() /* nothing... */
+#define fd_clear_dma_ff() /* nothing... */
+#define fd_set_dma_mode(mode) sun_fdops.fd_set_dma_mode(mode)
+#define fd_set_dma_addr(addr) sun_fdops.fd_set_dma_addr(addr)
+#define fd_set_dma_count(count) sun_fdops.fd_set_dma_count(count)
+#define get_dma_residue(x) sun_fdops.get_dma_residue()
+#define fd_request_irq() sun_fdops.fd_request_irq()
+#define fd_free_irq() sun_fdops.fd_free_irq()
+#define fd_eject(drive) sun_fdops.fd_eject(drive)
+
+/* Super paranoid... */
+#undef HAVE_DISABLE_HLT
+
+static int sun_floppy_types[2] = { 0, 0 };
+
+/* Here is where we catch the floppy driver trying to initialize,
+ * therefore this is where we call the PROM device tree probing
+ * routine etc. on the Sparc.
+ */
+#define FLOPPY0_TYPE sun_floppy_init()
+#define FLOPPY1_TYPE sun_floppy_types[1]
+
+#define FDC1 ((unsigned long)sun_fdc)
+
+#define N_FDC 1
+#define N_DRIVE 8
+
+/* No 64k boundary crossing problems on the Sparc. */
+#define CROSS_64KB(a,s) (0)
+
+static unsigned char sun_82077_fd_inb(unsigned long base, unsigned int reg)
+{
+ udelay(5);
+ switch (reg) {
+ default:
+ printk("floppy: Asked to read unknown port %x\n", reg);
+ panic("floppy: Port bolixed.");
+ case FD_STATUS:
+ return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
+ case FD_DATA:
+ return sbus_readb(&sun_fdc->data_82077);
+ case FD_DIR:
+ /* XXX: Is DCL on 0x80 in sun4m? */
+ return sbus_readb(&sun_fdc->dir_82077);
+ }
+ panic("sun_82072_fd_inb: How did I get here?");
+}
+
+static void sun_82077_fd_outb(unsigned char value, unsigned long base,
+ unsigned int reg)
+{
+ udelay(5);
+ switch (reg) {
+ default:
+ printk("floppy: Asked to write to unknown port %x\n", reg);
+ panic("floppy: Port bolixed.");
+ case FD_DOR:
+ /* Happily, the 82077 has a real DOR register. */
+ sbus_writeb(value, &sun_fdc->dor_82077);
+ break;
+ case FD_DATA:
+ sbus_writeb(value, &sun_fdc->data_82077);
+ break;
+ case FD_DCR:
+ sbus_writeb(value, &sun_fdc->dcr_82077);
+ break;
+ case FD_DSR:
+ sbus_writeb(value, &sun_fdc->status_82077);
+ break;
+ }
+ return;
+}
+
+/* For pseudo-dma (Sun floppy drives have no real DMA available to
+ * them so we must eat the data fifo bytes directly ourselves) we have
+ * three state variables. doing_pdma tells our inline low-level
+ * assembly floppy interrupt entry point whether it should sit and eat
+ * bytes from the fifo or just transfer control up to the higher level
+ * floppy interrupt c-code. I tried very hard but I could not get the
+ * pseudo-dma to work in c-code without getting many overruns and
+ * underruns. If non-zero, doing_pdma encodes the direction of
+ * the transfer for debugging. 1=read 2=write
+ */
+unsigned char *pdma_vaddr;
+unsigned long pdma_size;
+volatile int doing_pdma = 0;
+
+/* This is software state */
+char *pdma_base = NULL;
+unsigned long pdma_areasize;
+
+/* Common routines to all controller types on the Sparc. */
+static void sun_fd_disable_dma(void)
+{
+ doing_pdma = 0;
+ pdma_base = NULL;
+}
+
+static void sun_fd_set_dma_mode(int mode)
+{
+ switch(mode) {
+ case DMA_MODE_READ:
+ doing_pdma = 1;
+ break;
+ case DMA_MODE_WRITE:
+ doing_pdma = 2;
+ break;
+ default:
+ printk("Unknown dma mode %d\n", mode);
+ panic("floppy: Giving up...");
+ }
+}
+
+static void sun_fd_set_dma_addr(char *buffer)
+{
+ pdma_vaddr = buffer;
+}
+
+static void sun_fd_set_dma_count(int length)
+{
+ pdma_size = length;
+}
+
+static void sun_fd_enable_dma(void)
+{
+ pdma_base = pdma_vaddr;
+ pdma_areasize = pdma_size;
+}
+
+irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
+{
+ if (likely(doing_pdma)) {
+ void __iomem *stat = (void __iomem *) fdc_status;
+ unsigned char *vaddr = pdma_vaddr;
+ unsigned long size = pdma_size;
+ u8 val;
+
+ while (size) {
+ val = readb(stat);
+ if (unlikely(!(val & 0x80))) {
+ pdma_vaddr = vaddr;
+ pdma_size = size;
+ return IRQ_HANDLED;
+ }
+ if (unlikely(!(val & 0x20))) {
+ pdma_vaddr = vaddr;
+ pdma_size = size;
+ doing_pdma = 0;
+ goto main_interrupt;
+ }
+ if (val & 0x40) {
+ /* read */
+ *vaddr++ = readb(stat + 1);
+ } else {
+ unsigned char data = *vaddr++;
+
+ /* write */
+ writeb(data, stat + 1);
+ }
+ size--;
+ }
+
+ pdma_vaddr = vaddr;
+ pdma_size = size;
+
+ /* Send Terminal Count pulse to floppy controller. */
+ val = readb(auxio_register);
+ val |= AUXIO_AUX1_FTCNT;
+ writeb(val, auxio_register);
+ val &= ~AUXIO_AUX1_FTCNT;
+ writeb(val, auxio_register);
+
+ doing_pdma = 0;
+ }
+
+main_interrupt:
+ return floppy_interrupt(irq, dev_cookie);
+}
+
+static int sun_fd_request_irq(void)
+{
+ static int once = 0;
+ int error;
+
+ if(!once) {
+ once = 1;
+
+ error = request_irq(FLOPPY_IRQ, sparc_floppy_irq,
+ 0, "floppy", NULL);
+
+ return ((error == 0) ? 0 : -1);
+ }
+ return 0;
+}
+
+static void sun_fd_free_irq(void)
+{
+}
+
+static unsigned int sun_get_dma_residue(void)
+{
+ /* XXX This isn't really correct. XXX */
+ return 0;
+}
+
+static int sun_fd_eject(int drive)
+{
+ set_dor(0x00, 0xff, 0x90);
+ udelay(500);
+ set_dor(0x00, 0x6f, 0x00);
+ udelay(500);
+ return 0;
+}
+
+#include <asm/ebus_dma.h>
+#include <asm/ns87303.h>
+
+static struct ebus_dma_info sun_pci_fd_ebus_dma;
+static struct device *sun_floppy_dev;
+static int sun_pci_broken_drive = -1;
+
+struct sun_pci_dma_op {
+ unsigned int addr;
+ int len;
+ int direction;
+ char *buf;
+};
+static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
+static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
+
+irqreturn_t floppy_interrupt(int irq, void *dev_id);
+
+static unsigned char sun_pci_fd_inb(unsigned long base, unsigned int reg)
+{
+ udelay(5);
+ return inb(base + reg);
+}
+
+static void sun_pci_fd_outb(unsigned char val, unsigned long base,
+ unsigned int reg)
+{
+ udelay(5);
+ outb(val, base + reg);
+}
+
+static void sun_pci_fd_broken_outb(unsigned char val, unsigned long base,
+ unsigned int reg)
+{
+ udelay(5);
+ /*
+ * XXX: Due to SUN's broken floppy connector on AX and AXi
+ * we need to turn on MOTOR_0 also, if the floppy is
+ * jumpered to DS1 (like most PC floppies are). I hope
+ * this does not hurt correct hardware like the AXmp.
+ * (Eddie, Sep 12 1998).
+ */
+ if (reg == FD_DOR) {
+ if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
+ val |= 0x10;
+ }
+ }
+ outb(val, base + reg);
+}
+
+#ifdef PCI_FDC_SWAP_DRIVES
+static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long base,
+ unsigned int reg)
+{
+ udelay(5);
+ /*
+ * XXX: Due to SUN's broken floppy connector on AX and AXi
+ * we need to turn on MOTOR_0 also, if the floppy is
+ * jumpered to DS1 (like most PC floppies are). I hope
+ * this does not hurt correct hardware like the AXmp.
+ * (Eddie, Sep 12 1998).
+ */
+ if (reg == FD_DOR) {
+ if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
+ val &= ~(0x03);
+ val |= 0x21;
+ }
+ }
+ outb(val, base + reg);
+}
+#endif /* PCI_FDC_SWAP_DRIVES */
+
+static void sun_pci_fd_enable_dma(void)
+{
+ BUG_ON((NULL == sun_pci_dma_pending.buf) ||
+ (0 == sun_pci_dma_pending.len) ||
+ (0 == sun_pci_dma_pending.direction));
+
+ sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
+ sun_pci_dma_current.len = sun_pci_dma_pending.len;
+ sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
+
+ sun_pci_dma_pending.buf = NULL;
+ sun_pci_dma_pending.len = 0;
+ sun_pci_dma_pending.direction = 0;
+ sun_pci_dma_pending.addr = -1U;
+
+ sun_pci_dma_current.addr =
+ dma_map_single(sun_floppy_dev,
+ sun_pci_dma_current.buf,
+ sun_pci_dma_current.len,
+ sun_pci_dma_current.direction);
+
+ ebus_dma_enable(&sun_pci_fd_ebus_dma, 1);
+
+ if (ebus_dma_request(&sun_pci_fd_ebus_dma,
+ sun_pci_dma_current.addr,
+ sun_pci_dma_current.len))
+ BUG();
+}
+
+static void sun_pci_fd_disable_dma(void)
+{
+ ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
+ if (sun_pci_dma_current.addr != -1U)
+ dma_unmap_single(sun_floppy_dev,
+ sun_pci_dma_current.addr,
+ sun_pci_dma_current.len,
+ sun_pci_dma_current.direction);
+ sun_pci_dma_current.addr = -1U;
+}
+
+static void sun_pci_fd_set_dma_mode(int mode)
+{
+ if (mode == DMA_MODE_WRITE)
+ sun_pci_dma_pending.direction = DMA_TO_DEVICE;
+ else
+ sun_pci_dma_pending.direction = DMA_FROM_DEVICE;
+
+ ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
+}
+
+static void sun_pci_fd_set_dma_count(int length)
+{
+ sun_pci_dma_pending.len = length;
+}
+
+static void sun_pci_fd_set_dma_addr(char *buffer)
+{
+ sun_pci_dma_pending.buf = buffer;
+}
+
+static unsigned int sun_pci_get_dma_residue(void)
+{
+ return ebus_dma_residue(&sun_pci_fd_ebus_dma);
+}
+
+static int sun_pci_fd_request_irq(void)
+{
+ return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
+}
+
+static void sun_pci_fd_free_irq(void)
+{
+ ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
+}
+
+static int sun_pci_fd_eject(int drive)
+{
+ return -EINVAL;
+}
+
+void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
+{
+ floppy_interrupt(0, NULL);
+}
+
+/*
+ * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
+ * even if this is configured using DS1, thus looks like /dev/fd1 with
+ * the cabling used in Ultras.
+ */
+#define DOR (port + 2)
+#define MSR (port + 4)
+#define FIFO (port + 5)
+
+static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
+ unsigned long reg)
+{
+ unsigned char status;
+ int timeout = 1000;
+
+ while (!((status = inb(MSR)) & 0x80) && --timeout)
+ udelay(100);
+ outb(val, reg);
+}
+
+static unsigned char sun_pci_fd_sensei(unsigned long port)
+{
+ unsigned char result[2] = { 0x70, 0x00 };
+ unsigned char status;
+ int i = 0;
+
+ sun_pci_fd_out_byte(port, 0x08, FIFO);
+ do {
+ int timeout = 1000;
+
+ while (!((status = inb(MSR)) & 0x80) && --timeout)
+ udelay(100);
+
+ if (!timeout)
+ break;
+
+ if ((status & 0xf0) == 0xd0)
+ result[i++] = inb(FIFO);
+ else
+ break;
+ } while (i < 2);
+
+ return result[0];
+}
+
+static void sun_pci_fd_reset(unsigned long port)
+{
+ unsigned char mask = 0x00;
+ unsigned char status;
+ int timeout = 10000;
+
+ outb(0x80, MSR);
+ do {
+ status = sun_pci_fd_sensei(port);
+ if ((status & 0xc0) == 0xc0)
+ mask |= 1 << (status & 0x03);
+ else
+ udelay(100);
+ } while ((mask != 0x0f) && --timeout);
+}
+
+static int sun_pci_fd_test_drive(unsigned long port, int drive)
+{
+ unsigned char status, data;
+ int timeout = 1000;
+ int ready;
+
+ sun_pci_fd_reset(port);
+
+ data = (0x10 << drive) | 0x0c | drive;
+ sun_pci_fd_out_byte(port, data, DOR);
+
+ sun_pci_fd_out_byte(port, 0x07, FIFO);
+ sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
+
+ do {
+ udelay(100);
+ status = sun_pci_fd_sensei(port);
+ } while (((status & 0xc0) == 0x80) && --timeout);
+
+ if (!timeout)
+ ready = 0;
+ else
+ ready = (status & 0x10) ? 0 : 1;
+
+ sun_pci_fd_reset(port);
+ return ready;
+}
+#undef FIFO
+#undef MSR
+#undef DOR
+
+static int __init ebus_fdthree_p(struct device_node *dp)
+{
+ if (of_node_name_eq(dp, "fdthree"))
+ return 1;
+ if (of_node_name_eq(dp, "floppy")) {
+ const char *compat;
+
+ compat = of_get_property(dp, "compatible", NULL);
+ if (compat && !strcmp(compat, "fdthree"))
+ return 1;
+ }
+ return 0;
+}
+
+static unsigned long __init sun_floppy_init(void)
+{
+ static int initialized = 0;
+ struct device_node *dp;
+ struct platform_device *op;
+ const char *prop;
+ char state[128];
+
+ if (initialized)
+ return sun_floppy_types[0];
+ initialized = 1;
+
+ op = NULL;
+
+ for_each_node_by_name(dp, "SUNW,fdtwo") {
+ if (!of_node_name_eq(dp->parent, "sbus"))
+ continue;
+ op = of_find_device_by_node(dp);
+ if (op)
+ break;
+ }
+ if (op) {
+ floppy_op = op;
+ FLOPPY_IRQ = op->archdata.irqs[0];
+ } else {
+ struct device_node *ebus_dp;
+ void __iomem *auxio_reg;
+ const char *state_prop;
+ unsigned long config;
+
+ dp = NULL;
+ for_each_node_by_name(ebus_dp, "ebus") {
+ for (dp = ebus_dp->child; dp; dp = dp->sibling) {
+ if (ebus_fdthree_p(dp))
+ goto found_fdthree;
+ }
+ }
+ found_fdthree:
+ if (!dp)
+ return 0;
+
+ op = of_find_device_by_node(dp);
+ if (!op)
+ return 0;
+
+ state_prop = of_get_property(op->dev.of_node, "status", NULL);
+ if (state_prop && !strncmp(state_prop, "disabled", 8))
+ return 0;
+
+ FLOPPY_IRQ = op->archdata.irqs[0];
+
+ /* Make sure the high density bit is set, some systems
+ * (most notably Ultra5/Ultra10) come up with it clear.
+ */
+ auxio_reg = (void __iomem *) op->resource[2].start;
+ writel(readl(auxio_reg)|0x2, auxio_reg);
+
+ sun_floppy_dev = &op->dev;
+
+ spin_lock_init(&sun_pci_fd_ebus_dma.lock);
+
+ /* XXX ioremap */
+ sun_pci_fd_ebus_dma.regs = (void __iomem *)
+ op->resource[1].start;
+ if (!sun_pci_fd_ebus_dma.regs)
+ return 0;
+
+ sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
+ EBUS_DMA_FLAG_TCI_DISABLE);
+ sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback;
+ sun_pci_fd_ebus_dma.client_cookie = NULL;
+ sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ;
+ strcpy(sun_pci_fd_ebus_dma.name, "floppy");
+ if (ebus_dma_register(&sun_pci_fd_ebus_dma))
+ return 0;
+
+ /* XXX ioremap */
+ sun_fdc = (struct sun_flpy_controller *) op->resource[0].start;
+
+ sun_fdops.fd_inb = sun_pci_fd_inb;
+ sun_fdops.fd_outb = sun_pci_fd_outb;
+
+ can_use_virtual_dma = use_virtual_dma = 0;
+ sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
+ sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
+ sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
+ sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
+ sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
+ sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
+
+ sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
+ sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
+
+ sun_fdops.fd_eject = sun_pci_fd_eject;
+
+ fdc_status = (unsigned long) &sun_fdc->status_82077;
+
+ /*
+ * XXX: Find out on which machines this is really needed.
+ */
+ if (1) {
+ sun_pci_broken_drive = 1;
+ sun_fdops.fd_outb = sun_pci_fd_broken_outb;
+ }
+
+ allowed_drive_mask = 0;
+ if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
+ sun_floppy_types[0] = 4;
+ if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
+ sun_floppy_types[1] = 4;
+
+ /*
+ * Find NS87303 SuperIO config registers (through ecpp).
+ */
+ config = 0;
+ for (dp = ebus_dp->child; dp; dp = dp->sibling) {
+ if (of_node_name_eq(dp, "ecpp")) {
+ struct platform_device *ecpp_op;
+
+ ecpp_op = of_find_device_by_node(dp);
+ if (ecpp_op)
+ config = ecpp_op->resource[1].start;
+ goto config_done;
+ }
+ }
+ config_done:
+
+ /*
+ * Sanity check, is this really the NS87303?
+ */
+ switch (config & 0x3ff) {
+ case 0x02e:
+ case 0x15c:
+ case 0x26e:
+ case 0x398:
+ break;
+ default:
+ config = 0;
+ }
+
+ if (!config)
+ return sun_floppy_types[0];
+
+ /* Enable PC-AT mode. */
+ ns87303_modify(config, ASC, 0, 0xc0);
+
+#ifdef PCI_FDC_SWAP_DRIVES
+ /*
+ * If only Floppy 1 is present, swap drives.
+ */
+ if (!sun_floppy_types[0] && sun_floppy_types[1]) {
+ /*
+ * Set the drive exchange bit in FCR on NS87303,
+ * make sure other bits are sane before doing so.
+ */
+ ns87303_modify(config, FER, FER_EDM, 0);
+ ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
+ ns87303_modify(config, FCR, 0, FCR_LDE);
+
+ config = sun_floppy_types[0];
+ sun_floppy_types[0] = sun_floppy_types[1];
+ sun_floppy_types[1] = config;
+
+ if (sun_pci_broken_drive != -1) {
+ sun_pci_broken_drive = 1 - sun_pci_broken_drive;
+ sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
+ }
+ }
+#endif /* PCI_FDC_SWAP_DRIVES */
+
+ return sun_floppy_types[0];
+ }
+ prop = of_get_property(op->dev.of_node, "status", NULL);
+ if (prop && !strncmp(state, "disabled", 8))
+ return 0;
+
+ /*
+ * We cannot do of_ioremap here: it does request_region,
+ * which the generic floppy driver tries to do once again.
+ * But we must use the sdev resource values as they have
+ * had parent ranges applied.
+ */
+ sun_fdc = (struct sun_flpy_controller *)
+ (op->resource[0].start +
+ ((op->resource[0].flags & 0x1ffUL) << 32UL));
+
+ /* Last minute sanity check... */
+ if (sbus_readb(&sun_fdc->status1_82077) == 0xff) {
+ sun_fdc = (struct sun_flpy_controller *)-1;
+ return 0;
+ }
+
+ sun_fdops.fd_inb = sun_82077_fd_inb;
+ sun_fdops.fd_outb = sun_82077_fd_outb;
+
+ can_use_virtual_dma = use_virtual_dma = 1;
+ sun_fdops.fd_enable_dma = sun_fd_enable_dma;
+ sun_fdops.fd_disable_dma = sun_fd_disable_dma;
+ sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
+ sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
+ sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
+ sun_fdops.get_dma_residue = sun_get_dma_residue;
+
+ sun_fdops.fd_request_irq = sun_fd_request_irq;
+ sun_fdops.fd_free_irq = sun_fd_free_irq;
+
+ sun_fdops.fd_eject = sun_fd_eject;
+
+ fdc_status = (unsigned long) &sun_fdc->status_82077;
+
+ /* Success... */
+ allowed_drive_mask = 0x01;
+ sun_floppy_types[0] = 4;
+ sun_floppy_types[1] = 0;
+
+ return sun_floppy_types[0];
+}
+
+#define EXTRA_FLOPPY_PARAMS
+
+static DEFINE_SPINLOCK(dma_spin_lock);
+
+#define claim_dma_lock() \
+({ unsigned long flags; \
+ spin_lock_irqsave(&dma_spin_lock, flags); \
+ flags; \
+})
+
+#define release_dma_lock(__flags) \
+ spin_unlock_irqrestore(&dma_spin_lock, __flags);
+
+#endif /* !(__ASM_SPARC64_FLOPPY_H) */
diff --git a/arch/sparc/include/asm/floppy_32.h b/arch/sparc/include/asm/floppy_32.h
deleted file mode 100644
index e10ab9ad3097..000000000000
--- a/arch/sparc/include/asm/floppy_32.h
+++ /dev/null
@@ -1,393 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* asm/floppy.h: Sparc specific parts of the Floppy driver.
- *
- * Copyright (C) 1995 David S. Miller ([email protected])
- */
-
-#ifndef __ASM_SPARC_FLOPPY_H
-#define __ASM_SPARC_FLOPPY_H
-
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/pgtable.h>
-
-#include <asm/idprom.h>
-#include <asm/oplib.h>
-#include <asm/auxio.h>
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/irq.h>
-
-/* We don't need no stinkin' I/O port allocation crap. */
-#undef release_region
-#undef request_region
-#define release_region(X, Y) do { } while(0)
-#define request_region(X, Y, Z) (1)
-
-/* References:
- * 1) Netbsd Sun floppy driver.
- * 2) NCR 82077 controller manual
- * 3) Intel 82077 controller manual
- */
-struct sun_flpy_controller {
- volatile unsigned char status_82072; /* Main Status reg. */
-#define dcr_82072 status_82072 /* Digital Control reg. */
-#define status1_82077 status_82072 /* Auxiliary Status reg. 1 */
-
- volatile unsigned char data_82072; /* Data fifo. */
-#define status2_82077 data_82072 /* Auxiliary Status reg. 2 */
-
- volatile unsigned char dor_82077; /* Digital Output reg. */
- volatile unsigned char tapectl_82077; /* What the? Tape control reg? */
-
- volatile unsigned char status_82077; /* Main Status Register. */
-#define drs_82077 status_82077 /* Digital Rate Select reg. */
-
- volatile unsigned char data_82077; /* Data fifo. */
- volatile unsigned char ___unused;
- volatile unsigned char dir_82077; /* Digital Input reg. */
-#define dcr_82077 dir_82077 /* Config Control reg. */
-};
-
-/* You'll only ever find one controller on a SparcStation anyways. */
-static struct sun_flpy_controller *sun_fdc = NULL;
-
-struct sun_floppy_ops {
- unsigned char (*fd_inb)(int port);
- void (*fd_outb)(unsigned char value, int port);
-};
-
-static struct sun_floppy_ops sun_fdops;
-
-#define fd_inb(base, reg) sun_fdops.fd_inb(reg)
-#define fd_outb(value, base, reg) sun_fdops.fd_outb(value, reg)
-#define fd_enable_dma() sun_fd_enable_dma()
-#define fd_disable_dma() sun_fd_disable_dma()
-#define fd_request_dma() (0) /* nothing... */
-#define fd_free_dma() /* nothing... */
-#define fd_clear_dma_ff() /* nothing... */
-#define fd_set_dma_mode(mode) sun_fd_set_dma_mode(mode)
-#define fd_set_dma_addr(addr) sun_fd_set_dma_addr(addr)
-#define fd_set_dma_count(count) sun_fd_set_dma_count(count)
-#define fd_enable_irq() /* nothing... */
-#define fd_disable_irq() /* nothing... */
-#define fd_request_irq() sun_fd_request_irq()
-#define fd_free_irq() /* nothing... */
-#if 0 /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */
-#define fd_dma_mem_alloc(size) ((unsigned long) vmalloc(size))
-#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
-#endif
-
-/* XXX This isn't really correct. XXX */
-#define get_dma_residue(x) (0)
-
-#define FLOPPY0_TYPE 4
-#define FLOPPY1_TYPE 0
-
-/* Super paranoid... */
-#undef HAVE_DISABLE_HLT
-
-/* Here is where we catch the floppy driver trying to initialize,
- * therefore this is where we call the PROM device tree probing
- * routine etc. on the Sparc.
- */
-#define FDC1 sun_floppy_init()
-
-#define N_FDC 1
-#define N_DRIVE 8
-
-/* No 64k boundary crossing problems on the Sparc. */
-#define CROSS_64KB(a,s) (0)
-
-/* Routines unique to each controller type on a Sun. */
-static void sun_set_dor(unsigned char value, int fdc_82077)
-{
- if (fdc_82077)
- sun_fdc->dor_82077 = value;
-}
-
-static unsigned char sun_read_dir(void)
-{
- return sun_fdc->dir_82077;
-}
-
-static unsigned char sun_82072_fd_inb(int port)
-{
- udelay(5);
- switch (port) {
- default:
- printk("floppy: Asked to read unknown port %d\n", port);
- panic("floppy: Port bolixed.");
- case FD_STATUS:
- return sun_fdc->status_82072 & ~STATUS_DMA;
- case FD_DATA:
- return sun_fdc->data_82072;
- case FD_DIR:
- return sun_read_dir();
- }
- panic("sun_82072_fd_inb: How did I get here?");
-}
-
-static void sun_82072_fd_outb(unsigned char value, int port)
-{
- udelay(5);
- switch (port) {
- default:
- printk("floppy: Asked to write to unknown port %d\n", port);
- panic("floppy: Port bolixed.");
- case FD_DOR:
- sun_set_dor(value, 0);
- break;
- case FD_DATA:
- sun_fdc->data_82072 = value;
- break;
- case FD_DCR:
- sun_fdc->dcr_82072 = value;
- break;
- case FD_DSR:
- sun_fdc->status_82072 = value;
- break;
- }
- return;
-}
-
-static unsigned char sun_82077_fd_inb(int port)
-{
- udelay(5);
- switch (port) {
- default:
- printk("floppy: Asked to read unknown port %d\n", port);
- panic("floppy: Port bolixed.");
- case FD_SRA:
- return sun_fdc->status1_82077;
- case FD_SRB:
- return sun_fdc->status2_82077;
- case FD_DOR:
- return sun_fdc->dor_82077;
- case FD_TDR:
- return sun_fdc->tapectl_82077;
- case FD_STATUS:
- return sun_fdc->status_82077 & ~STATUS_DMA;
- case FD_DATA:
- return sun_fdc->data_82077;
- case FD_DIR:
- return sun_read_dir();
- }
- panic("sun_82077_fd_inb: How did I get here?");
-}
-
-static void sun_82077_fd_outb(unsigned char value, int port)
-{
- udelay(5);
- switch (port) {
- default:
- printk("floppy: Asked to write to unknown port %d\n", port);
- panic("floppy: Port bolixed.");
- case FD_DOR:
- sun_set_dor(value, 1);
- break;
- case FD_DATA:
- sun_fdc->data_82077 = value;
- break;
- case FD_DCR:
- sun_fdc->dcr_82077 = value;
- break;
- case FD_DSR:
- sun_fdc->status_82077 = value;
- break;
- case FD_TDR:
- sun_fdc->tapectl_82077 = value;
- break;
- }
- return;
-}
-
-/* For pseudo-dma (Sun floppy drives have no real DMA available to
- * them so we must eat the data fifo bytes directly ourselves) we have
- * three state variables. doing_pdma tells our inline low-level
- * assembly floppy interrupt entry point whether it should sit and eat
- * bytes from the fifo or just transfer control up to the higher level
- * floppy interrupt c-code. I tried very hard but I could not get the
- * pseudo-dma to work in c-code without getting many overruns and
- * underruns. If non-zero, doing_pdma encodes the direction of
- * the transfer for debugging. 1=read 2=write
- */
-
-/* Common routines to all controller types on the Sparc. */
-static inline void virtual_dma_init(void)
-{
- /* nothing... */
-}
-
-static inline void sun_fd_disable_dma(void)
-{
- doing_pdma = 0;
- pdma_base = NULL;
-}
-
-static inline void sun_fd_set_dma_mode(int mode)
-{
- switch(mode) {
- case DMA_MODE_READ:
- doing_pdma = 1;
- break;
- case DMA_MODE_WRITE:
- doing_pdma = 2;
- break;
- default:
- printk("Unknown dma mode %d\n", mode);
- panic("floppy: Giving up...");
- }
-}
-
-static inline void sun_fd_set_dma_addr(char *buffer)
-{
- pdma_vaddr = buffer;
-}
-
-static inline void sun_fd_set_dma_count(int length)
-{
- pdma_size = length;
-}
-
-static inline void sun_fd_enable_dma(void)
-{
- pdma_base = pdma_vaddr;
- pdma_areasize = pdma_size;
-}
-
-int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler);
-
-static int sun_fd_request_irq(void)
-{
- static int once = 0;
-
- if (!once) {
- once = 1;
- return sparc_floppy_request_irq(FLOPPY_IRQ, floppy_interrupt);
- } else {
- return 0;
- }
-}
-
-static struct linux_prom_registers fd_regs[2];
-
-static int sun_floppy_init(void)
-{
- struct platform_device *op;
- struct device_node *dp;
- struct resource r;
- char state[128];
- phandle fd_node;
- phandle tnode;
- int num_regs;
-
- use_virtual_dma = 1;
-
- /* Forget it if we aren't on a machine that could possibly
- * ever have a floppy drive.
- */
- if (sparc_cpu_model != sun4m) {
- /* We certainly don't have a floppy controller. */
- goto no_sun_fdc;
- }
- /* Well, try to find one. */
- tnode = prom_getchild(prom_root_node);
- fd_node = prom_searchsiblings(tnode, "obio");
- if (fd_node != 0) {
- tnode = prom_getchild(fd_node);
- fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo");
- } else {
- fd_node = prom_searchsiblings(tnode, "fd");
- }
- if (fd_node == 0) {
- goto no_sun_fdc;
- }
-
- /* The sun4m lets us know if the controller is actually usable. */
- if (prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) {
- if(!strcmp(state, "disabled")) {
- goto no_sun_fdc;
- }
- }
- num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs));
- num_regs = (num_regs / sizeof(fd_regs[0]));
- prom_apply_obio_ranges(fd_regs, num_regs);
- memset(&r, 0, sizeof(r));
- r.flags = fd_regs[0].which_io;
- r.start = fd_regs[0].phys_addr;
- sun_fdc = of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
-
- /* Look up irq in platform_device.
- * We try "SUNW,fdtwo" and "fd"
- */
- op = NULL;
- for_each_node_by_name(dp, "SUNW,fdtwo") {
- op = of_find_device_by_node(dp);
- if (op)
- break;
- }
- if (!op) {
- for_each_node_by_name(dp, "fd") {
- op = of_find_device_by_node(dp);
- if (op)
- break;
- }
- }
- if (!op)
- goto no_sun_fdc;
-
- FLOPPY_IRQ = op->archdata.irqs[0];
-
- /* Last minute sanity check... */
- if (sun_fdc->status_82072 == 0xff) {
- sun_fdc = NULL;
- goto no_sun_fdc;
- }
-
- sun_fdops.fd_inb = sun_82077_fd_inb;
- sun_fdops.fd_outb = sun_82077_fd_outb;
- fdc_status = &sun_fdc->status_82077;
-
- if (sun_fdc->dor_82077 == 0x80) {
- sun_fdc->dor_82077 = 0x02;
- if (sun_fdc->dor_82077 == 0x80) {
- sun_fdops.fd_inb = sun_82072_fd_inb;
- sun_fdops.fd_outb = sun_82072_fd_outb;
- fdc_status = &sun_fdc->status_82072;
- }
- }
-
- /* Success... */
- allowed_drive_mask = 0x01;
- return (int) sun_fdc;
-
-no_sun_fdc:
- return -1;
-}
-
-static int sparc_eject(void)
-{
- set_dor(0x00, 0xff, 0x90);
- udelay(500);
- set_dor(0x00, 0x6f, 0x00);
- udelay(500);
- return 0;
-}
-
-#define fd_eject(drive) sparc_eject()
-
-#define EXTRA_FLOPPY_PARAMS
-
-static DEFINE_SPINLOCK(dma_spin_lock);
-
-#define claim_dma_lock() \
-({ unsigned long flags; \
- spin_lock_irqsave(&dma_spin_lock, flags); \
- flags; \
-})
-
-#define release_dma_lock(__flags) \
- spin_unlock_irqrestore(&dma_spin_lock, __flags);
-
-#endif /* !(__ASM_SPARC_FLOPPY_H) */
diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h
deleted file mode 100644
index 070c8c1f5c8f..000000000000
--- a/arch/sparc/include/asm/floppy_64.h
+++ /dev/null
@@ -1,779 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* floppy.h: Sparc specific parts of the Floppy driver.
- *
- * Copyright (C) 1996, 2007, 2008 David S. Miller ([email protected])
- * Copyright (C) 1997 Jakub Jelinek ([email protected])
- *
- * Ultra/PCI support added: Sep 1997 Eddie C. Dost ([email protected])
- */
-
-#ifndef __ASM_SPARC64_FLOPPY_H
-#define __ASM_SPARC64_FLOPPY_H
-
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/auxio.h>
-
-/*
- * Define this to enable exchanging drive 0 and 1 if only drive 1 is
- * probed on PCI machines.
- */
-#undef PCI_FDC_SWAP_DRIVES
-
-
-/* References:
- * 1) Netbsd Sun floppy driver.
- * 2) NCR 82077 controller manual
- * 3) Intel 82077 controller manual
- */
-struct sun_flpy_controller {
- volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
- volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
- volatile unsigned char dor_82077; /* Digital Output reg. */
- volatile unsigned char tapectl_82077; /* Tape Control reg */
- volatile unsigned char status_82077; /* Main Status Register. */
-#define drs_82077 status_82077 /* Digital Rate Select reg. */
- volatile unsigned char data_82077; /* Data fifo. */
- volatile unsigned char ___unused;
- volatile unsigned char dir_82077; /* Digital Input reg. */
-#define dcr_82077 dir_82077 /* Config Control reg. */
-};
-
-/* You'll only ever find one controller on an Ultra anyways. */
-static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
-unsigned long fdc_status;
-static struct platform_device *floppy_op = NULL;
-
-struct sun_floppy_ops {
- unsigned char (*fd_inb) (unsigned long port, unsigned int reg);
- void (*fd_outb) (unsigned char value, unsigned long base,
- unsigned int reg);
- void (*fd_enable_dma) (void);
- void (*fd_disable_dma) (void);
- void (*fd_set_dma_mode) (int);
- void (*fd_set_dma_addr) (char *);
- void (*fd_set_dma_count) (int);
- unsigned int (*get_dma_residue) (void);
- int (*fd_request_irq) (void);
- void (*fd_free_irq) (void);
- int (*fd_eject) (int);
-};
-
-static struct sun_floppy_ops sun_fdops;
-
-#define fd_inb(base, reg) sun_fdops.fd_inb(base, reg)
-#define fd_outb(value, base, reg) sun_fdops.fd_outb(value, base, reg)
-#define fd_enable_dma() sun_fdops.fd_enable_dma()
-#define fd_disable_dma() sun_fdops.fd_disable_dma()
-#define fd_request_dma() (0) /* nothing... */
-#define fd_free_dma() /* nothing... */
-#define fd_clear_dma_ff() /* nothing... */
-#define fd_set_dma_mode(mode) sun_fdops.fd_set_dma_mode(mode)
-#define fd_set_dma_addr(addr) sun_fdops.fd_set_dma_addr(addr)
-#define fd_set_dma_count(count) sun_fdops.fd_set_dma_count(count)
-#define get_dma_residue(x) sun_fdops.get_dma_residue()
-#define fd_request_irq() sun_fdops.fd_request_irq()
-#define fd_free_irq() sun_fdops.fd_free_irq()
-#define fd_eject(drive) sun_fdops.fd_eject(drive)
-
-/* Super paranoid... */
-#undef HAVE_DISABLE_HLT
-
-static int sun_floppy_types[2] = { 0, 0 };
-
-/* Here is where we catch the floppy driver trying to initialize,
- * therefore this is where we call the PROM device tree probing
- * routine etc. on the Sparc.
- */
-#define FLOPPY0_TYPE sun_floppy_init()
-#define FLOPPY1_TYPE sun_floppy_types[1]
-
-#define FDC1 ((unsigned long)sun_fdc)
-
-#define N_FDC 1
-#define N_DRIVE 8
-
-/* No 64k boundary crossing problems on the Sparc. */
-#define CROSS_64KB(a,s) (0)
-
-static unsigned char sun_82077_fd_inb(unsigned long base, unsigned int reg)
-{
- udelay(5);
- switch (reg) {
- default:
- printk("floppy: Asked to read unknown port %x\n", reg);
- panic("floppy: Port bolixed.");
- case FD_STATUS:
- return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
- case FD_DATA:
- return sbus_readb(&sun_fdc->data_82077);
- case FD_DIR:
- /* XXX: Is DCL on 0x80 in sun4m? */
- return sbus_readb(&sun_fdc->dir_82077);
- }
- panic("sun_82072_fd_inb: How did I get here?");
-}
-
-static void sun_82077_fd_outb(unsigned char value, unsigned long base,
- unsigned int reg)
-{
- udelay(5);
- switch (reg) {
- default:
- printk("floppy: Asked to write to unknown port %x\n", reg);
- panic("floppy: Port bolixed.");
- case FD_DOR:
- /* Happily, the 82077 has a real DOR register. */
- sbus_writeb(value, &sun_fdc->dor_82077);
- break;
- case FD_DATA:
- sbus_writeb(value, &sun_fdc->data_82077);
- break;
- case FD_DCR:
- sbus_writeb(value, &sun_fdc->dcr_82077);
- break;
- case FD_DSR:
- sbus_writeb(value, &sun_fdc->status_82077);
- break;
- }
- return;
-}
-
-/* For pseudo-dma (Sun floppy drives have no real DMA available to
- * them so we must eat the data fifo bytes directly ourselves) we have
- * three state variables. doing_pdma tells our inline low-level
- * assembly floppy interrupt entry point whether it should sit and eat
- * bytes from the fifo or just transfer control up to the higher level
- * floppy interrupt c-code. I tried very hard but I could not get the
- * pseudo-dma to work in c-code without getting many overruns and
- * underruns. If non-zero, doing_pdma encodes the direction of
- * the transfer for debugging. 1=read 2=write
- */
-unsigned char *pdma_vaddr;
-unsigned long pdma_size;
-volatile int doing_pdma = 0;
-
-/* This is software state */
-char *pdma_base = NULL;
-unsigned long pdma_areasize;
-
-/* Common routines to all controller types on the Sparc. */
-static void sun_fd_disable_dma(void)
-{
- doing_pdma = 0;
- pdma_base = NULL;
-}
-
-static void sun_fd_set_dma_mode(int mode)
-{
- switch(mode) {
- case DMA_MODE_READ:
- doing_pdma = 1;
- break;
- case DMA_MODE_WRITE:
- doing_pdma = 2;
- break;
- default:
- printk("Unknown dma mode %d\n", mode);
- panic("floppy: Giving up...");
- }
-}
-
-static void sun_fd_set_dma_addr(char *buffer)
-{
- pdma_vaddr = buffer;
-}
-
-static void sun_fd_set_dma_count(int length)
-{
- pdma_size = length;
-}
-
-static void sun_fd_enable_dma(void)
-{
- pdma_base = pdma_vaddr;
- pdma_areasize = pdma_size;
-}
-
-irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
-{
- if (likely(doing_pdma)) {
- void __iomem *stat = (void __iomem *) fdc_status;
- unsigned char *vaddr = pdma_vaddr;
- unsigned long size = pdma_size;
- u8 val;
-
- while (size) {
- val = readb(stat);
- if (unlikely(!(val & 0x80))) {
- pdma_vaddr = vaddr;
- pdma_size = size;
- return IRQ_HANDLED;
- }
- if (unlikely(!(val & 0x20))) {
- pdma_vaddr = vaddr;
- pdma_size = size;
- doing_pdma = 0;
- goto main_interrupt;
- }
- if (val & 0x40) {
- /* read */
- *vaddr++ = readb(stat + 1);
- } else {
- unsigned char data = *vaddr++;
-
- /* write */
- writeb(data, stat + 1);
- }
- size--;
- }
-
- pdma_vaddr = vaddr;
- pdma_size = size;
-
- /* Send Terminal Count pulse to floppy controller. */
- val = readb(auxio_register);
- val |= AUXIO_AUX1_FTCNT;
- writeb(val, auxio_register);
- val &= ~AUXIO_AUX1_FTCNT;
- writeb(val, auxio_register);
-
- doing_pdma = 0;
- }
-
-main_interrupt:
- return floppy_interrupt(irq, dev_cookie);
-}
-
-static int sun_fd_request_irq(void)
-{
- static int once = 0;
- int error;
-
- if(!once) {
- once = 1;
-
- error = request_irq(FLOPPY_IRQ, sparc_floppy_irq,
- 0, "floppy", NULL);
-
- return ((error == 0) ? 0 : -1);
- }
- return 0;
-}
-
-static void sun_fd_free_irq(void)
-{
-}
-
-static unsigned int sun_get_dma_residue(void)
-{
- /* XXX This isn't really correct. XXX */
- return 0;
-}
-
-static int sun_fd_eject(int drive)
-{
- set_dor(0x00, 0xff, 0x90);
- udelay(500);
- set_dor(0x00, 0x6f, 0x00);
- udelay(500);
- return 0;
-}
-
-#include <asm/ebus_dma.h>
-#include <asm/ns87303.h>
-
-static struct ebus_dma_info sun_pci_fd_ebus_dma;
-static struct device *sun_floppy_dev;
-static int sun_pci_broken_drive = -1;
-
-struct sun_pci_dma_op {
- unsigned int addr;
- int len;
- int direction;
- char *buf;
-};
-static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
-static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
-
-irqreturn_t floppy_interrupt(int irq, void *dev_id);
-
-static unsigned char sun_pci_fd_inb(unsigned long base, unsigned int reg)
-{
- udelay(5);
- return inb(base + reg);
-}
-
-static void sun_pci_fd_outb(unsigned char val, unsigned long base,
- unsigned int reg)
-{
- udelay(5);
- outb(val, base + reg);
-}
-
-static void sun_pci_fd_broken_outb(unsigned char val, unsigned long base,
- unsigned int reg)
-{
- udelay(5);
- /*
- * XXX: Due to SUN's broken floppy connector on AX and AXi
- * we need to turn on MOTOR_0 also, if the floppy is
- * jumpered to DS1 (like most PC floppies are). I hope
- * this does not hurt correct hardware like the AXmp.
- * (Eddie, Sep 12 1998).
- */
- if (reg == FD_DOR) {
- if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
- val |= 0x10;
- }
- }
- outb(val, base + reg);
-}
-
-#ifdef PCI_FDC_SWAP_DRIVES
-static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long base,
- unsigned int reg)
-{
- udelay(5);
- /*
- * XXX: Due to SUN's broken floppy connector on AX and AXi
- * we need to turn on MOTOR_0 also, if the floppy is
- * jumpered to DS1 (like most PC floppies are). I hope
- * this does not hurt correct hardware like the AXmp.
- * (Eddie, Sep 12 1998).
- */
- if (reg == FD_DOR) {
- if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
- val &= ~(0x03);
- val |= 0x21;
- }
- }
- outb(val, base + reg);
-}
-#endif /* PCI_FDC_SWAP_DRIVES */
-
-static void sun_pci_fd_enable_dma(void)
-{
- BUG_ON((NULL == sun_pci_dma_pending.buf) ||
- (0 == sun_pci_dma_pending.len) ||
- (0 == sun_pci_dma_pending.direction));
-
- sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
- sun_pci_dma_current.len = sun_pci_dma_pending.len;
- sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
-
- sun_pci_dma_pending.buf = NULL;
- sun_pci_dma_pending.len = 0;
- sun_pci_dma_pending.direction = 0;
- sun_pci_dma_pending.addr = -1U;
-
- sun_pci_dma_current.addr =
- dma_map_single(sun_floppy_dev,
- sun_pci_dma_current.buf,
- sun_pci_dma_current.len,
- sun_pci_dma_current.direction);
-
- ebus_dma_enable(&sun_pci_fd_ebus_dma, 1);
-
- if (ebus_dma_request(&sun_pci_fd_ebus_dma,
- sun_pci_dma_current.addr,
- sun_pci_dma_current.len))
- BUG();
-}
-
-static void sun_pci_fd_disable_dma(void)
-{
- ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
- if (sun_pci_dma_current.addr != -1U)
- dma_unmap_single(sun_floppy_dev,
- sun_pci_dma_current.addr,
- sun_pci_dma_current.len,
- sun_pci_dma_current.direction);
- sun_pci_dma_current.addr = -1U;
-}
-
-static void sun_pci_fd_set_dma_mode(int mode)
-{
- if (mode == DMA_MODE_WRITE)
- sun_pci_dma_pending.direction = DMA_TO_DEVICE;
- else
- sun_pci_dma_pending.direction = DMA_FROM_DEVICE;
-
- ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
-}
-
-static void sun_pci_fd_set_dma_count(int length)
-{
- sun_pci_dma_pending.len = length;
-}
-
-static void sun_pci_fd_set_dma_addr(char *buffer)
-{
- sun_pci_dma_pending.buf = buffer;
-}
-
-static unsigned int sun_pci_get_dma_residue(void)
-{
- return ebus_dma_residue(&sun_pci_fd_ebus_dma);
-}
-
-static int sun_pci_fd_request_irq(void)
-{
- return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
-}
-
-static void sun_pci_fd_free_irq(void)
-{
- ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
-}
-
-static int sun_pci_fd_eject(int drive)
-{
- return -EINVAL;
-}
-
-void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
-{
- floppy_interrupt(0, NULL);
-}
-
-/*
- * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
- * even if this is configured using DS1, thus looks like /dev/fd1 with
- * the cabling used in Ultras.
- */
-#define DOR (port + 2)
-#define MSR (port + 4)
-#define FIFO (port + 5)
-
-static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
- unsigned long reg)
-{
- unsigned char status;
- int timeout = 1000;
-
- while (!((status = inb(MSR)) & 0x80) && --timeout)
- udelay(100);
- outb(val, reg);
-}
-
-static unsigned char sun_pci_fd_sensei(unsigned long port)
-{
- unsigned char result[2] = { 0x70, 0x00 };
- unsigned char status;
- int i = 0;
-
- sun_pci_fd_out_byte(port, 0x08, FIFO);
- do {
- int timeout = 1000;
-
- while (!((status = inb(MSR)) & 0x80) && --timeout)
- udelay(100);
-
- if (!timeout)
- break;
-
- if ((status & 0xf0) == 0xd0)
- result[i++] = inb(FIFO);
- else
- break;
- } while (i < 2);
-
- return result[0];
-}
-
-static void sun_pci_fd_reset(unsigned long port)
-{
- unsigned char mask = 0x00;
- unsigned char status;
- int timeout = 10000;
-
- outb(0x80, MSR);
- do {
- status = sun_pci_fd_sensei(port);
- if ((status & 0xc0) == 0xc0)
- mask |= 1 << (status & 0x03);
- else
- udelay(100);
- } while ((mask != 0x0f) && --timeout);
-}
-
-static int sun_pci_fd_test_drive(unsigned long port, int drive)
-{
- unsigned char status, data;
- int timeout = 1000;
- int ready;
-
- sun_pci_fd_reset(port);
-
- data = (0x10 << drive) | 0x0c | drive;
- sun_pci_fd_out_byte(port, data, DOR);
-
- sun_pci_fd_out_byte(port, 0x07, FIFO);
- sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
-
- do {
- udelay(100);
- status = sun_pci_fd_sensei(port);
- } while (((status & 0xc0) == 0x80) && --timeout);
-
- if (!timeout)
- ready = 0;
- else
- ready = (status & 0x10) ? 0 : 1;
-
- sun_pci_fd_reset(port);
- return ready;
-}
-#undef FIFO
-#undef MSR
-#undef DOR
-
-static int __init ebus_fdthree_p(struct device_node *dp)
-{
- if (of_node_name_eq(dp, "fdthree"))
- return 1;
- if (of_node_name_eq(dp, "floppy")) {
- const char *compat;
-
- compat = of_get_property(dp, "compatible", NULL);
- if (compat && !strcmp(compat, "fdthree"))
- return 1;
- }
- return 0;
-}
-
-static unsigned long __init sun_floppy_init(void)
-{
- static int initialized = 0;
- struct device_node *dp;
- struct platform_device *op;
- const char *prop;
- char state[128];
-
- if (initialized)
- return sun_floppy_types[0];
- initialized = 1;
-
- op = NULL;
-
- for_each_node_by_name(dp, "SUNW,fdtwo") {
- if (!of_node_name_eq(dp->parent, "sbus"))
- continue;
- op = of_find_device_by_node(dp);
- if (op)
- break;
- }
- if (op) {
- floppy_op = op;
- FLOPPY_IRQ = op->archdata.irqs[0];
- } else {
- struct device_node *ebus_dp;
- void __iomem *auxio_reg;
- const char *state_prop;
- unsigned long config;
-
- dp = NULL;
- for_each_node_by_name(ebus_dp, "ebus") {
- for (dp = ebus_dp->child; dp; dp = dp->sibling) {
- if (ebus_fdthree_p(dp))
- goto found_fdthree;
- }
- }
- found_fdthree:
- if (!dp)
- return 0;
-
- op = of_find_device_by_node(dp);
- if (!op)
- return 0;
-
- state_prop = of_get_property(op->dev.of_node, "status", NULL);
- if (state_prop && !strncmp(state_prop, "disabled", 8))
- return 0;
-
- FLOPPY_IRQ = op->archdata.irqs[0];
-
- /* Make sure the high density bit is set, some systems
- * (most notably Ultra5/Ultra10) come up with it clear.
- */
- auxio_reg = (void __iomem *) op->resource[2].start;
- writel(readl(auxio_reg)|0x2, auxio_reg);
-
- sun_floppy_dev = &op->dev;
-
- spin_lock_init(&sun_pci_fd_ebus_dma.lock);
-
- /* XXX ioremap */
- sun_pci_fd_ebus_dma.regs = (void __iomem *)
- op->resource[1].start;
- if (!sun_pci_fd_ebus_dma.regs)
- return 0;
-
- sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
- EBUS_DMA_FLAG_TCI_DISABLE);
- sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback;
- sun_pci_fd_ebus_dma.client_cookie = NULL;
- sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ;
- strcpy(sun_pci_fd_ebus_dma.name, "floppy");
- if (ebus_dma_register(&sun_pci_fd_ebus_dma))
- return 0;
-
- /* XXX ioremap */
- sun_fdc = (struct sun_flpy_controller *) op->resource[0].start;
-
- sun_fdops.fd_inb = sun_pci_fd_inb;
- sun_fdops.fd_outb = sun_pci_fd_outb;
-
- can_use_virtual_dma = use_virtual_dma = 0;
- sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
- sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
- sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
- sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
- sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
- sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
-
- sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
- sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
-
- sun_fdops.fd_eject = sun_pci_fd_eject;
-
- fdc_status = (unsigned long) &sun_fdc->status_82077;
-
- /*
- * XXX: Find out on which machines this is really needed.
- */
- if (1) {
- sun_pci_broken_drive = 1;
- sun_fdops.fd_outb = sun_pci_fd_broken_outb;
- }
-
- allowed_drive_mask = 0;
- if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
- sun_floppy_types[0] = 4;
- if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
- sun_floppy_types[1] = 4;
-
- /*
- * Find NS87303 SuperIO config registers (through ecpp).
- */
- config = 0;
- for (dp = ebus_dp->child; dp; dp = dp->sibling) {
- if (of_node_name_eq(dp, "ecpp")) {
- struct platform_device *ecpp_op;
-
- ecpp_op = of_find_device_by_node(dp);
- if (ecpp_op)
- config = ecpp_op->resource[1].start;
- goto config_done;
- }
- }
- config_done:
-
- /*
- * Sanity check, is this really the NS87303?
- */
- switch (config & 0x3ff) {
- case 0x02e:
- case 0x15c:
- case 0x26e:
- case 0x398:
- break;
- default:
- config = 0;
- }
-
- if (!config)
- return sun_floppy_types[0];
-
- /* Enable PC-AT mode. */
- ns87303_modify(config, ASC, 0, 0xc0);
-
-#ifdef PCI_FDC_SWAP_DRIVES
- /*
- * If only Floppy 1 is present, swap drives.
- */
- if (!sun_floppy_types[0] && sun_floppy_types[1]) {
- /*
- * Set the drive exchange bit in FCR on NS87303,
- * make sure other bits are sane before doing so.
- */
- ns87303_modify(config, FER, FER_EDM, 0);
- ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
- ns87303_modify(config, FCR, 0, FCR_LDE);
-
- config = sun_floppy_types[0];
- sun_floppy_types[0] = sun_floppy_types[1];
- sun_floppy_types[1] = config;
-
- if (sun_pci_broken_drive != -1) {
- sun_pci_broken_drive = 1 - sun_pci_broken_drive;
- sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
- }
- }
-#endif /* PCI_FDC_SWAP_DRIVES */
-
- return sun_floppy_types[0];
- }
- prop = of_get_property(op->dev.of_node, "status", NULL);
- if (prop && !strncmp(state, "disabled", 8))
- return 0;
-
- /*
- * We cannot do of_ioremap here: it does request_region,
- * which the generic floppy driver tries to do once again.
- * But we must use the sdev resource values as they have
- * had parent ranges applied.
- */
- sun_fdc = (struct sun_flpy_controller *)
- (op->resource[0].start +
- ((op->resource[0].flags & 0x1ffUL) << 32UL));
-
- /* Last minute sanity check... */
- if (sbus_readb(&sun_fdc->status1_82077) == 0xff) {
- sun_fdc = (struct sun_flpy_controller *)-1;
- return 0;
- }
-
- sun_fdops.fd_inb = sun_82077_fd_inb;
- sun_fdops.fd_outb = sun_82077_fd_outb;
-
- can_use_virtual_dma = use_virtual_dma = 1;
- sun_fdops.fd_enable_dma = sun_fd_enable_dma;
- sun_fdops.fd_disable_dma = sun_fd_disable_dma;
- sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
- sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
- sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
- sun_fdops.get_dma_residue = sun_get_dma_residue;
-
- sun_fdops.fd_request_irq = sun_fd_request_irq;
- sun_fdops.fd_free_irq = sun_fd_free_irq;
-
- sun_fdops.fd_eject = sun_fd_eject;
-
- fdc_status = (unsigned long) &sun_fdc->status_82077;
-
- /* Success... */
- allowed_drive_mask = 0x01;
- sun_floppy_types[0] = 4;
- sun_floppy_types[1] = 0;
-
- return sun_floppy_types[0];
-}
-
-#define EXTRA_FLOPPY_PARAMS
-
-static DEFINE_SPINLOCK(dma_spin_lock);
-
-#define claim_dma_lock() \
-({ unsigned long flags; \
- spin_lock_irqsave(&dma_spin_lock, flags); \
- flags; \
-})
-
-#define release_dma_lock(__flags) \
- spin_unlock_irqrestore(&dma_spin_lock, __flags);
-
-#endif /* !(__ASM_SPARC64_FLOPPY_H) */
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index d58940280f8d..9985b08a3467 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -55,143 +55,6 @@ arch_kgdb_breakpoint:
.size arch_kgdb_breakpoint,.-arch_kgdb_breakpoint
#endif

-#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
- .align 4
- .globl floppy_hardint
-floppy_hardint:
- /*
- * This code cannot touch registers %l0 %l1 and %l2
- * because SAVE_ALL depends on their values. It depends
- * on %l3 also, but we regenerate it before a call.
- * Other registers are:
- * %l3 -- base address of fdc registers
- * %l4 -- pdma_vaddr
- * %l5 -- scratch for ld/st address
- * %l6 -- pdma_size
- * %l7 -- scratch [floppy byte, ld/st address, aux. data]
- */
-
- /* Do we have work to do? */
- sethi %hi(doing_pdma), %l7
- ld [%l7 + %lo(doing_pdma)], %l7
- cmp %l7, 0
- be floppy_dosoftint
- nop
-
- /* Load fdc register base */
- sethi %hi(fdc_status), %l3
- ld [%l3 + %lo(fdc_status)], %l3
-
- /* Setup register addresses */
- sethi %hi(pdma_vaddr), %l5 ! transfer buffer
- ld [%l5 + %lo(pdma_vaddr)], %l4
- sethi %hi(pdma_size), %l5 ! bytes to go
- ld [%l5 + %lo(pdma_size)], %l6
-next_byte:
- ldub [%l3], %l7
-
- andcc %l7, 0x80, %g0 ! Does fifo still have data
- bz floppy_fifo_emptied ! fifo has been emptied...
- andcc %l7, 0x20, %g0 ! in non-dma mode still?
- bz floppy_overrun ! nope, overrun
- andcc %l7, 0x40, %g0 ! 0=write 1=read
- bz floppy_write
- sub %l6, 0x1, %l6
-
- /* Ok, actually read this byte */
- ldub [%l3 + 1], %l7
- orcc %g0, %l6, %g0
- stb %l7, [%l4]
- bne next_byte
- add %l4, 0x1, %l4
-
- b floppy_tdone
- nop
-
-floppy_write:
- /* Ok, actually write this byte */
- ldub [%l4], %l7
- orcc %g0, %l6, %g0
- stb %l7, [%l3 + 1]
- bne next_byte
- add %l4, 0x1, %l4
-
- /* fall through... */
-floppy_tdone:
- sethi %hi(pdma_vaddr), %l5
- st %l4, [%l5 + %lo(pdma_vaddr)]
- sethi %hi(pdma_size), %l5
- st %l6, [%l5 + %lo(pdma_size)]
- /* Flip terminal count pin */
- set auxio_register, %l7
- ld [%l7], %l7
-
- ldub [%l7], %l5
-
- or %l5, 0xc2, %l5
- stb %l5, [%l7]
- andn %l5, 0x02, %l5
-
-2:
- /* Kill some time so the bits set */
- WRITE_PAUSE
- WRITE_PAUSE
-
- stb %l5, [%l7]
-
- /* Prevent recursion */
- sethi %hi(doing_pdma), %l7
- b floppy_dosoftint
- st %g0, [%l7 + %lo(doing_pdma)]
-
- /* We emptied the FIFO, but we haven't read everything
- * as of yet. Store the current transfer address and
- * bytes left to read so we can continue when the next
- * fast IRQ comes in.
- */
-floppy_fifo_emptied:
- sethi %hi(pdma_vaddr), %l5
- st %l4, [%l5 + %lo(pdma_vaddr)]
- sethi %hi(pdma_size), %l7
- st %l6, [%l7 + %lo(pdma_size)]
-
- /* Restore condition codes */
- wr %l0, 0x0, %psr
- WRITE_PAUSE
-
- jmp %l1
- rett %l2
-
-floppy_overrun:
- sethi %hi(pdma_vaddr), %l5
- st %l4, [%l5 + %lo(pdma_vaddr)]
- sethi %hi(pdma_size), %l5
- st %l6, [%l5 + %lo(pdma_size)]
- /* Prevent recursion */
- sethi %hi(doing_pdma), %l7
- st %g0, [%l7 + %lo(doing_pdma)]
-
- /* fall through... */
-floppy_dosoftint:
- rd %wim, %l3
- SAVE_ALL
-
- /* Set all IRQs off. */
- or %l0, PSR_PIL, %l4
- wr %l4, 0x0, %psr
- WRITE_PAUSE
- wr %l4, PSR_ET, %psr
- WRITE_PAUSE
-
- mov 11, %o0 ! floppy irq level (unused anyway)
- mov %g0, %o1 ! devid is not used in fast interrupts
- call sparc_floppy_irq
- add %sp, STACKFRAME_SZ, %o2 ! struct pt_regs *regs
-
- RESTORE_ALL
-
-#endif /* (CONFIG_BLK_DEV_FD) */
-
/* Bad trap handler */
.globl bad_trap_handler
bad_trap_handler:
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h
index b02026ad6e34..0d9b740725b4 100644
--- a/arch/sparc/kernel/irq.h
+++ b/arch/sparc/kernel/irq.h
@@ -83,9 +83,6 @@ void handler_irq(unsigned int pil, struct pt_regs *regs);

unsigned long leon_get_irqmask(unsigned int irq);

-/* irq_32.c */
-void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs);
-
/* sun4m_irq.c */
void sun4m_nmi(struct pt_regs *regs);

diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index e8452be5123b..510184c3aa17 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -235,99 +235,6 @@ void handler_irq(unsigned int pil, struct pt_regs *regs)
set_irq_regs(old_regs);
}

-#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
-static unsigned int floppy_irq;
-
-int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler)
-{
- unsigned int cpu_irq;
- int err;
-
-
- err = request_irq(irq, irq_handler, 0, "floppy", NULL);
- if (err)
- return -1;
-
- /* Save for later use in floppy interrupt handler */
- floppy_irq = irq;
-
- cpu_irq = (irq & (NR_IRQS - 1));
-
- /* Dork with trap table if we get this far. */
-#define INSTANTIATE(table) \
- table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_one = SPARC_RD_PSR_L0; \
- table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two = \
- SPARC_BRANCH((unsigned long) floppy_hardint, \
- (unsigned long) &table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two);\
- table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_three = SPARC_RD_WIM_L3; \
- table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
-
- INSTANTIATE(sparc_ttable)
-
-#if defined CONFIG_SMP
- if (sparc_cpu_model != sparc_leon) {
- struct tt_entry *trap_table;
-
- trap_table = &trapbase_cpu1;
- INSTANTIATE(trap_table)
- trap_table = &trapbase_cpu2;
- INSTANTIATE(trap_table)
- trap_table = &trapbase_cpu3;
- INSTANTIATE(trap_table)
- }
-#endif
-#undef INSTANTIATE
- /*
- * XXX Correct thing whould be to flush only I- and D-cache lines
- * which contain the handler in question. But as of time of the
- * writing we have no CPU-neutral interface to fine-grained flushes.
- */
- flush_cache_all();
- return 0;
-}
-EXPORT_SYMBOL(sparc_floppy_request_irq);
-
-/*
- * These variables are used to access state from the assembler
- * interrupt handler, floppy_hardint, so we cannot put these in
- * the floppy driver image because that would not work in the
- * modular case.
- */
-volatile unsigned char *fdc_status;
-EXPORT_SYMBOL(fdc_status);
-
-char *pdma_vaddr;
-EXPORT_SYMBOL(pdma_vaddr);
-
-unsigned long pdma_size;
-EXPORT_SYMBOL(pdma_size);
-
-volatile int doing_pdma;
-EXPORT_SYMBOL(doing_pdma);
-
-char *pdma_base;
-EXPORT_SYMBOL(pdma_base);
-
-unsigned long pdma_areasize;
-EXPORT_SYMBOL(pdma_areasize);
-
-/* Use the generic irq support to call floppy_interrupt
- * which was setup using request_irq() in sparc_floppy_request_irq().
- * We only have one floppy interrupt so we do not need to check
- * for additional handlers being wired up by irq_link()
- */
-void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct pt_regs *old_regs;
-
- old_regs = set_irq_regs(regs);
- irq_enter();
- generic_handle_irq(floppy_irq);
- irq_exit();
- set_irq_regs(old_regs);
-}
-#endif
-
/* djhr
* This could probably be made indirect too and assigned in the CPU
* bits of the code. That would be much nicer I think and would also
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 9cd09a3ef35f..c76e49032273 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -152,8 +152,6 @@ extern unsigned int real_irq_entry[];
extern unsigned int smp4d_ticker[];
extern unsigned int patchme_maybe_smp_msg[];

-void floppy_hardint(void);
-
/* trampoline_32.S */
extern unsigned long sun4m_cpu_startup;
extern unsigned long sun4d_cpu_startup;
--
2.27.0

2020-12-18 20:46:21

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 01/13] sparc32: Drop sun4m/sun4d support from head_32.S

Remove the most obvious parts of sun4* support from head_32.S.
Use a single print if a sun4* machine is detected thus restricting
boots to LEON machines.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/kernel/head_32.S | 190 ++----------------------------------
1 file changed, 9 insertions(+), 181 deletions(-)

diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index be30c8d4cc73..b7b14250cbe0 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -45,11 +45,7 @@ cputypvar:
.align 4

notsup:
- .asciz "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n"
- .align 4
-
-sun4e_notsup:
- .asciz "Sparc-Linux sun4e support does not exist\n\n"
+ .asciz "Sparc-Linux sun4* or MMU-less not supported\n\n"
.align 4

/* The trap-table - located in the __HEAD section */
@@ -215,114 +211,10 @@ not_a_sun4:
be leon_remap /* It is a LEON - jump */
nop

- /* Sanity-check, is MMU enabled */
- lda [%g0] ASI_M_MMUREGS, %g1
- andcc %g1, 1, %g0
- be halt_notsup
- nop
-
- /* Check for a viking (TI) module. */
- cmp %g3, PSR_IMPL_TI
- bne srmmu_not_viking
- nop
-
- /* Figure out what kind of viking we are on.
- * We need to know if we have to play with the
- * AC bit and disable traps or not.
- */
-
- /* I've only seen MicroSparc's on SparcClassics with this
- * bit set.
- */
- set 0x800, %g2
- lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg
- and %g2, %g3, %g3
- subcc %g3, 0x0, %g0
- bnz srmmu_not_viking ! is in mbus mode
- nop
-
- rd %psr, %g3 ! DO NOT TOUCH %g3
- andn %g3, PSR_ET, %g2
- wr %g2, 0x0, %psr
- WRITE_PAUSE
-
- /* Get context table pointer, then convert to
- * a physical address, which is 36 bits.
- */
- set AC_M_CTPR, %g4
- lda [%g4] ASI_M_MMUREGS, %g4
- sll %g4, 0x4, %g4 ! We use this below
- ! DO NOT TOUCH %g4
-
- /* Set the AC bit in the Viking's MMU control reg. */
- lda [%g0] ASI_M_MMUREGS, %g5 ! DO NOT TOUCH %g5
- set 0x8000, %g6 ! AC bit mask
- or %g5, %g6, %g6 ! Or it in...
- sta %g6, [%g0] ASI_M_MMUREGS ! Close your eyes...
-
- /* Grrr, why does it seem like every other load/store
- * on the sun4m is in some ASI space...
- * Fine with me, let's get the pointer to the level 1
- * page table directory and fetch its entry.
- */
- lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr
- srl %o1, 0x4, %o1 ! Clear low 4 bits
- sll %o1, 0x8, %o1 ! Make physical
-
- /* Ok, pull in the PTD. */
- lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd
-
- /* Calculate to KERNBASE entry. */
- add %o1, KERNBASE >> (PGDIR_SHIFT - 2), %o3
-
- /* Poke the entry into the calculated address. */
- sta %o2, [%o3] ASI_M_BYPASS
-
- /* I don't get it Sun, if you engineered all these
- * boot loaders and the PROM (thank you for the debugging
- * features btw) why did you not have them load kernel
- * images up in high address space, since this is necessary
- * for ABI compliance anyways? Does this low-mapping provide
- * enhanced interoperability?
- *
- * "The PROM is the computer."
- */
-
- /* Ok, restore the MMU control register we saved in %g5 */
- sta %g5, [%g0] ASI_M_MMUREGS ! POW... ouch
-
- /* Turn traps back on. We saved it in %g3 earlier. */
- wr %g3, 0x0, %psr ! tick tock, tick tock
-
- /* Now we burn precious CPU cycles due to bad engineering. */
- WRITE_PAUSE
-
- /* Wow, all that just to move a 32-bit value from one
- * place to another... Jump to high memory.
- */
- b go_to_highmem
+ /* Not LEON - halt */
+ ba halt_notsup
nop

-srmmu_not_viking:
- /* This works on viking's in Mbus mode and all
- * other MBUS modules. It is virtually the same as
- * the above madness sans turning traps off and flipping
- * the AC bit.
- */
- set AC_M_CTPR, %g1
- lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr
- sll %g1, 0x4, %g1 ! make physical addr
- lda [%g1] ASI_M_BYPASS, %g1 ! ptr to level 1 pg_table
- srl %g1, 0x4, %g1
- sll %g1, 0x8, %g1 ! make phys addr for l1 tbl
-
- lda [%g1] ASI_M_BYPASS, %g2 ! get level1 entry for 0x0
- add %g1, KERNBASE >> (PGDIR_SHIFT - 2), %g3
- sta %g2, [%g3] ASI_M_BYPASS ! place at KERNBASE entry
- b go_to_highmem
- nop ! wheee....
-
-
leon_remap:
/* Sanity-check, is MMU enabled */
lda [%g0] ASI_LEON_MMUREGS, %g1
@@ -343,8 +235,6 @@ leon_remap:
lda [%g1] ASI_M_BYPASS, %g2 ! get level1 entry for 0x0
add %g1, KERNBASE >> (PGDIR_SHIFT - 2), %g3
sta %g2, [%g3] ASI_M_BYPASS ! place at KERNBASE entry
- b go_to_highmem
- nop ! wheee....

/* Now do a non-relative jump so that PC is in high-memory */
go_to_highmem:
@@ -413,13 +303,13 @@ execute_in_high_mem:
ldub [%o2 + 0x4], %l1

cmp %l1, 'm'
- be sun4m_init
+ be no_sun4_here ! sun4m
cmp %l1, 's'
- be sun4m_init
+ be no_sun4_here ! sun4m
cmp %l1, 'd'
- be sun4d_init
+ be no_sun4_here ! sun4d
cmp %l1, 'e'
- be no_sun4e_here ! Could be a sun4e.
+ be no_sun4_here ! Could be a sun4e.
nop
b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))
nop
@@ -441,68 +331,6 @@ leon_init:
/* Update boot_cpu_id only on boot cpu */
stub %g1, [%g2 + %lo(boot_cpu_id)]

- ba continue_boot
- nop
-
-/* CPUID in bootbus can be found at PA 0xff0140000 */
-#define SUN4D_BOOTBUS_CPUID 0xf0140000
-
-sun4d_init:
- /* Need to patch call to handler_irq */
- set patch_handler_irq, %g4
- set sun4d_handler_irq, %g5
- sethi %hi(0x40000000), %g3 ! call
- sub %g5, %g4, %g5
- srl %g5, 2, %g5
- or %g5, %g3, %g5
- st %g5, [%g4]
-
-#ifdef CONFIG_SMP
- /* Get our CPU id out of bootbus */
- set SUN4D_BOOTBUS_CPUID, %g3
- lduba [%g3] ASI_M_CTL, %g3
- and %g3, 0xf8, %g3
- srl %g3, 3, %g4
- sta %g4, [%g0] ASI_M_VIKING_TMP1
- sethi %hi(boot_cpu_id), %g5
- stb %g4, [%g5 + %lo(boot_cpu_id)]
-#endif
-
- /* Fall through to sun4m_init */
-
-sun4m_init:
-/* Ok, the PROM could have done funny things and apple cider could still
- * be sitting in the fault status/address registers. Read them all to
- * clear them so we don't get magic faults later on.
- */
-/* This sucks, apparently this makes Vikings call prom panic, will fix later */
-2:
- rd %psr, %o1
- srl %o1, PSR_IMPL_SHIFT, %o1 ! Get a type of the CPU
-
- subcc %o1, PSR_IMPL_TI, %g0 ! TI: Viking or MicroSPARC
- be continue_boot
- nop
-
- set AC_M_SFSR, %o0
- lda [%o0] ASI_M_MMUREGS, %g0
- set AC_M_SFAR, %o0
- lda [%o0] ASI_M_MMUREGS, %g0
-
- /* Fujitsu MicroSPARC-II has no asynchronous flavors of FARs */
- subcc %o1, 0, %g0
- be continue_boot
- nop
-
- set AC_M_AFSR, %o0
- lda [%o0] ASI_M_MMUREGS, %g0
- set AC_M_AFAR, %o0
- lda [%o0] ASI_M_MMUREGS, %g0
- nop
-
-
-continue_boot:
-
/* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's
* show-time!
*/
@@ -670,9 +498,9 @@ continue_boot:
call halt_me
nop

-no_sun4e_here:
+no_sun4_here:
ld [%g7 + 0x68], %o1
- set sun4e_notsup, %o0
+ set notsup, %o0
call %o1
nop
b halt_me
--
2.27.0

2020-12-18 20:46:23

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 05/13] sparc32: Drop run-time patching of ipi trap

There is no longer any need for the run-time patching of the ipi trap
with the removal of sun4m and sun4d. Remove the patching and drop the
ipi implementation for the two machines.

The patch includes removal of patching from pcic as this was needed to
fix the build. pcic will be removed in a later commit.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Christian Brauner <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/kernel/entry.S | 70 ++---------------------------------
arch/sparc/kernel/kernel.h | 4 --
arch/sparc/kernel/leon_smp.c | 3 --
arch/sparc/kernel/pcic.c | 11 ------
arch/sparc/kernel/sun4d_smp.c | 3 --
arch/sparc/kernel/ttable_32.S | 9 ++---
6 files changed, 7 insertions(+), 93 deletions(-)

diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 9985b08a3467..1a2e20a7e584 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -174,32 +174,6 @@ maybe_smp4m_msg_check_resched:
maybe_smp4m_msg_out:
RESTORE_ALL

- .align 4
- .globl linux_trap_ipi15_sun4m
-linux_trap_ipi15_sun4m:
- SAVE_ALL
- sethi %hi(0x80000000), %o2
- GET_PROCESSOR4M_ID(o0)
- sethi %hi(sun4m_irq_percpu), %l5
- or %l5, %lo(sun4m_irq_percpu), %o5
- sll %o0, 2, %o0
- ld [%o5 + %o0], %o5
- ld [%o5 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending
- andcc %o3, %o2, %g0
- be sun4m_nmi_error ! Must be an NMI async memory error
- st %o2, [%o5 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x80000000
- WRITE_PAUSE
- ld [%o5 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending
- WRITE_PAUSE
- or %l0, PSR_PIL, %l4
- wr %l4, 0x0, %psr
- WRITE_PAUSE
- wr %l4, PSR_ET, %psr
- WRITE_PAUSE
- call smp4m_cross_call_irq
- nop
- b ret_trap_lockless_ipi
- clr %l6

.globl smp4d_ticker
/* SMP per-cpu ticker interrupts are handled specially. */
@@ -220,44 +194,6 @@ smp4d_ticker:
WRITE_PAUSE
RESTORE_ALL

- .align 4
- .globl linux_trap_ipi15_sun4d
-linux_trap_ipi15_sun4d:
- SAVE_ALL
- sethi %hi(CC_BASE), %o4
- sethi %hi(MXCC_ERR_ME|MXCC_ERR_PEW|MXCC_ERR_ASE|MXCC_ERR_PEE), %o2
- or %o4, (CC_EREG - CC_BASE), %o0
- ldda [%o0] ASI_M_MXCC, %o0
- andcc %o0, %o2, %g0
- bne 1f
- sethi %hi(BB_STAT2), %o2
- lduba [%o2] ASI_M_CTL, %o2
- andcc %o2, BB_STAT2_MASK, %g0
- bne 2f
- or %o4, (CC_ICLR - CC_BASE), %o0
- sethi %hi(1 << 15), %o1
- stha %o1, [%o0] ASI_M_MXCC /* Clear PIL 15 in MXCC's ICLR */
- or %l0, PSR_PIL, %l4
- wr %l4, 0x0, %psr
- WRITE_PAUSE
- wr %l4, PSR_ET, %psr
- WRITE_PAUSE
- call smp4d_cross_call_irq
- nop
- b ret_trap_lockless_ipi
- clr %l6
-
-1: /* MXCC error */
-2: /* BB error */
- /* Disable PIL 15 */
- set CC_IMSK, %l4
- lduha [%l4] ASI_M_MXCC, %l5
- sethi %hi(1 << 15), %l7
- or %l5, %l7, %l5
- stha %l5, [%l4] ASI_M_MXCC
- /* FIXME */
-1: b,a 1b
-
.globl smpleon_ipi
.extern leon_ipi_interrupt
/* SMP per-cpu IPI interrupts are handled specially. */
@@ -618,11 +554,11 @@ sun4m_nmi_error:

#ifndef CONFIG_SMP
.align 4
- .globl linux_trap_ipi15_sun4m
-linux_trap_ipi15_sun4m:
+ .globl linux_trap_ipi15_leon
+linux_trap_ipi15_leon:
SAVE_ALL

- ba sun4m_nmi_error
+ ba sun4m_nmi_error
nop
#endif /* CONFIG_SMP */

diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 7328d13875e4..c9e1b13d955f 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -135,10 +135,6 @@ void leonsmp_ipi_interrupt(void);
void leon_cross_call_irq(void);

/* head_32.S */
-extern unsigned int t_nmi[];
-extern unsigned int linux_trap_ipi15_sun4d[];
-extern unsigned int linux_trap_ipi15_sun4m[];
-
extern struct tt_entry trapbase;
extern struct tt_entry trapbase_cpu1;
extern struct tt_entry trapbase_cpu2;
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index 1eed26d423fb..b0d75783d337 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -461,8 +461,5 @@ static const struct sparc32_ipi_ops leon_ipi_ops = {

void __init leon_init_smp(void)
{
- /* Patch ipi15 trap table */
- t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_leon - linux_trap_ipi15_sun4m);
-
sparc32_ipi_ops = &leon_ipi_ops;
}
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index ee4c9a9a171c..87bdcb16019b 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -354,17 +354,6 @@ int __init pcic_probe(void)
prom_getstring(node, "name", namebuf, 63); namebuf[63] = 0;
strcpy(pbm->prom_name, namebuf);

- {
- extern int pcic_nmi_trap_patch[4];
-
- t_nmi[0] = pcic_nmi_trap_patch[0];
- t_nmi[1] = pcic_nmi_trap_patch[1];
- t_nmi[2] = pcic_nmi_trap_patch[2];
- t_nmi[3] = pcic_nmi_trap_patch[3];
- swift_flush_dcache();
- pcic_regs = pcic->pcic_regs;
- }
-
prom_getstring(prom_root_node, "name", namebuf, 63); namebuf[63] = 0;
{
struct pcic_sn2list *p;
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index ff30f03beb7c..cecdda746baa 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -401,9 +401,6 @@ void __init sun4d_init_smp(void)
{
int i;

- /* Patch ipi15 trap table */
- t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m);
-
sparc32_ipi_ops = &sun4d_ipi_ops;

for (i = 0; i < NR_CPUS; i++) {
diff --git a/arch/sparc/kernel/ttable_32.S b/arch/sparc/kernel/ttable_32.S
index e79fd786fbbb..78bbf2548e1f 100644
--- a/arch/sparc/kernel/ttable_32.S
+++ b/arch/sparc/kernel/ttable_32.S
@@ -43,8 +43,7 @@ t_irq12:TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */
t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */
t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */

- .globl t_nmi
-t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
+t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15_leon)

t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */
t_iacce:BAD_TRAP(0x21) /* Instr Access Error */
@@ -146,7 +145,7 @@ trapbase_cpu1:
TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10)
TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12)
TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14)
- TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
+ TRAP_ENTRY(0x1f, linux_trap_ipi15_leon)
TRAP_ENTRY(0x20, do_reg_access)
BAD_TRAP(0x21)
BAD_TRAP(0x22)
@@ -245,7 +244,7 @@ trapbase_cpu2:
TRAP_ENTRY_INTERRUPT(12)
TRAP_ENTRY_INTERRUPT(13)
TRAP_ENTRY_INTERRUPT(14)
- TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
+ TRAP_ENTRY(0x1f, linux_trap_ipi15_leon)
TRAP_ENTRY(0x20, do_reg_access)
BAD_TRAP(0x21)
BAD_TRAP(0x22)
@@ -345,7 +344,7 @@ trapbase_cpu3:
TRAP_ENTRY_INTERRUPT(12)
TRAP_ENTRY_INTERRUPT(13)
TRAP_ENTRY_INTERRUPT(14)
- TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
+ TRAP_ENTRY(0x1f, linux_trap_ipi15_leon)
TRAP_ENTRY(0x20, do_reg_access)
BAD_TRAP(0x21)
BAD_TRAP(0x22)
--
2.27.0

2020-12-18 20:46:27

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 06/13] sparc32: Drop patching of interrupt vector

Drop the sun4m specific handling and the patching that
takes place in sun4d and LEON.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Christian Brauner <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/kernel/entry.S | 98 ---------------------------------
arch/sparc/kernel/kernel.h | 1 -
arch/sparc/kernel/leon_kernel.c | 16 ------
arch/sparc/kernel/sun4d_irq.c | 25 ---------
4 files changed, 140 deletions(-)

diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 1a2e20a7e584..e7cf5013aa40 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -79,15 +79,6 @@ bad_trap_handler:
real_irq_entry:
SAVE_ALL

-#ifdef CONFIG_SMP
- .globl patchme_maybe_smp_msg
-
- cmp %l7, 11
-patchme_maybe_smp_msg:
- bgu maybe_smp4m_msg
- nop
-#endif
-
real_irq_continue:
or %l0, PSR_PIL, %g2
wr %g2, 0x0, %psr
@@ -105,95 +96,6 @@ patch_handler_irq:
RESTORE_ALL

#ifdef CONFIG_SMP
- /* SMP per-cpu ticker interrupts are handled specially. */
-smp4m_ticker:
- bne real_irq_continue+4
- or %l0, PSR_PIL, %g2
- wr %g2, 0x0, %psr
- WRITE_PAUSE
- wr %g2, PSR_ET, %psr
- WRITE_PAUSE
- call smp4m_percpu_timer_interrupt
- add %sp, STACKFRAME_SZ, %o0
- wr %l0, PSR_ET, %psr
- WRITE_PAUSE
- RESTORE_ALL
-
-#define GET_PROCESSOR4M_ID(reg) \
- rd %tbr, %reg; \
- srl %reg, 12, %reg; \
- and %reg, 3, %reg;
-
- /* Here is where we check for possible SMP IPI passed to us
- * on some level other than 15 which is the NMI and only used
- * for cross calls. That has a separate entry point below.
- *
- * IPIs are sent on Level 12, 13 and 14. See IRQ_IPI_*.
- */
-maybe_smp4m_msg:
- GET_PROCESSOR4M_ID(o3)
- sethi %hi(sun4m_irq_percpu), %l5
- sll %o3, 2, %o3
- or %l5, %lo(sun4m_irq_percpu), %o5
- sethi %hi(0x70000000), %o2 ! Check all soft-IRQs
- ld [%o5 + %o3], %o1
- ld [%o1 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending
- andcc %o3, %o2, %g0
- be,a smp4m_ticker
- cmp %l7, 14
- /* Soft-IRQ IPI */
- st %o2, [%o1 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x70000000
- WRITE_PAUSE
- ld [%o1 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending
- WRITE_PAUSE
- or %l0, PSR_PIL, %l4
- wr %l4, 0x0, %psr
- WRITE_PAUSE
- wr %l4, PSR_ET, %psr
- WRITE_PAUSE
- srl %o3, 28, %o2 ! shift for simpler checks below
-maybe_smp4m_msg_check_single:
- andcc %o2, 0x1, %g0
- beq,a maybe_smp4m_msg_check_mask
- andcc %o2, 0x2, %g0
- call smp_call_function_single_interrupt
- nop
- andcc %o2, 0x2, %g0
-maybe_smp4m_msg_check_mask:
- beq,a maybe_smp4m_msg_check_resched
- andcc %o2, 0x4, %g0
- call smp_call_function_interrupt
- nop
- andcc %o2, 0x4, %g0
-maybe_smp4m_msg_check_resched:
- /* rescheduling is done in RESTORE_ALL regardless, but incr stats */
- beq,a maybe_smp4m_msg_out
- nop
- call smp_resched_interrupt
- nop
-maybe_smp4m_msg_out:
- RESTORE_ALL
-
-
- .globl smp4d_ticker
- /* SMP per-cpu ticker interrupts are handled specially. */
-smp4d_ticker:
- SAVE_ALL
- or %l0, PSR_PIL, %g2
- sethi %hi(CC_ICLR), %o0
- sethi %hi(1 << 14), %o1
- or %o0, %lo(CC_ICLR), %o0
- stha %o1, [%o0] ASI_M_MXCC /* Clear PIL 14 in MXCC's ICLR */
- wr %g2, 0x0, %psr
- WRITE_PAUSE
- wr %g2, PSR_ET, %psr
- WRITE_PAUSE
- call smp4d_percpu_timer_interrupt
- add %sp, STACKFRAME_SZ, %o0
- wr %l0, PSR_ET, %psr
- WRITE_PAUSE
- RESTORE_ALL
-
.globl smpleon_ipi
.extern leon_ipi_interrupt
/* SMP per-cpu IPI interrupts are handled specially. */
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index c9e1b13d955f..e313d2e15ba9 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -146,7 +146,6 @@ extern char cputypval[];
extern unsigned long lvl14_save[4];
extern unsigned int real_irq_entry[];
extern unsigned int smp4d_ticker[];
-extern unsigned int patchme_maybe_smp_msg[];

/* trampoline_32.S */
extern unsigned long sun4m_cpu_startup;
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 39229940d725..49b37a0dcc2b 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -423,22 +423,6 @@ void __init leon_init_timers(void)
if (eirq != 0)
leon_eirq_setup(eirq);

-#ifdef CONFIG_SMP
- {
- unsigned long flags;
-
- /*
- * In SMP, sun4m adds a IPI handler to IRQ trap handler that
- * LEON never must take, sun4d and LEON overwrites the branch
- * with a NOP.
- */
- local_irq_save(flags);
- patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
- local_ops->cache_all();
- local_irq_restore(flags);
- }
-#endif
-
config = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config);
if (config & (1 << LEON3_GPTIMER_SEPIRQ))
leon3_gptimer_irq += leon3_gptimer_idx;
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 9a137c70e8d1..7140cff04b54 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -391,30 +391,6 @@ static unsigned int sun4d_build_timer_irq(unsigned int board,
}


-static void __init sun4d_fixup_trap_table(void)
-{
-#ifdef CONFIG_SMP
- unsigned long flags;
- struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
-
- /* Adjust so that we jump directly to smp4d_ticker */
- lvl14_save[2] += smp4d_ticker - real_irq_entry;
-
- /* For SMP we use the level 14 ticker, however the bootup code
- * has copied the firmware's level 14 vector into the boot cpu's
- * trap table, we must fix this now or we get squashed.
- */
- local_irq_save(flags);
- patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
- trap_table->inst_one = lvl14_save[0];
- trap_table->inst_two = lvl14_save[1];
- trap_table->inst_three = lvl14_save[2];
- trap_table->inst_four = lvl14_save[3];
- local_ops->cache_all();
- local_irq_restore(flags);
-#endif
-}
-
static void __init sun4d_init_timers(void)
{
struct device_node *dp;
@@ -478,7 +454,6 @@ static void __init sun4d_init_timers(void)
prom_halt();
}
sun4d_load_profile_irqs();
- sun4d_fixup_trap_table();
}

void __init sun4d_init_sbi_irq(void)
--
2.27.0

2020-12-18 20:46:37

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 09/13] sparc32: Drop pcic support

pcic is only used by MicroSPARC-IIep and not relevant for LEON.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Christian Brauner <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: [email protected]
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/Kconfig | 5 -
arch/sparc/include/asm/pcic.h | 130 ------
arch/sparc/kernel/Makefile | 1 -
arch/sparc/kernel/entry.S | 48 --
arch/sparc/kernel/irq_32.c | 1 -
arch/sparc/kernel/kernel.h | 4 -
arch/sparc/kernel/pcic.c | 830 ----------------------------------
arch/sparc/kernel/time_32.c | 6 +-
8 files changed, 1 insertion(+), 1024 deletions(-)
delete mode 100644 arch/sparc/include/asm/pcic.h
delete mode 100644 arch/sparc/kernel/pcic.c

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 8447f5b7bb90..a22b55024a46 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -427,11 +427,6 @@ config SUN_LDOMS
Say Y here is you want to support virtual devices via
Logical Domains.

-config PCIC_PCI
- bool
- depends on PCI && SPARC32 && !SPARC_LEON
- default y
-
config LEON_PCI
bool
depends on PCI && SPARC_LEON
diff --git a/arch/sparc/include/asm/pcic.h b/arch/sparc/include/asm/pcic.h
deleted file mode 100644
index 238376b1ffcc..000000000000
--- a/arch/sparc/include/asm/pcic.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * pcic.h: JavaEngine 1 specific PCI definitions.
- *
- * Copyright (C) 1998 V. Roganov and G. Raiko
- */
-
-#ifndef __SPARC_PCIC_H
-#define __SPARC_PCIC_H
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-#include <linux/smp.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <asm/pbm.h>
-
-struct linux_pcic {
- void __iomem *pcic_regs;
- unsigned long pcic_io;
- void __iomem *pcic_config_space_addr;
- void __iomem *pcic_config_space_data;
- struct resource pcic_res_regs;
- struct resource pcic_res_io;
- struct resource pcic_res_cfg_addr;
- struct resource pcic_res_cfg_data;
- struct linux_pbm_info pbm;
- struct pcic_ca2irq *pcic_imap;
- int pcic_imdim;
-};
-
-#ifdef CONFIG_PCIC_PCI
-int pcic_present(void);
-int pcic_probe(void);
-void pci_time_init(void);
-void sun4m_pci_init_IRQ(void);
-#else
-static inline int pcic_present(void) { return 0; }
-static inline int pcic_probe(void) { return 0; }
-static inline void pci_time_init(void) {}
-static inline void sun4m_pci_init_IRQ(void) {}
-#endif
-#endif
-
-/* Size of PCI I/O space which we relocate. */
-#define PCI_SPACE_SIZE 0x1000000 /* 16 MB */
-
-/* PCIC Register Set. */
-#define PCI_DIAGNOSTIC_0 0x40 /* 32 bits */
-#define PCI_SIZE_0 0x44 /* 32 bits */
-#define PCI_SIZE_1 0x48 /* 32 bits */
-#define PCI_SIZE_2 0x4c /* 32 bits */
-#define PCI_SIZE_3 0x50 /* 32 bits */
-#define PCI_SIZE_4 0x54 /* 32 bits */
-#define PCI_SIZE_5 0x58 /* 32 bits */
-#define PCI_PIO_CONTROL 0x60 /* 8 bits */
-#define PCI_DVMA_CONTROL 0x62 /* 8 bits */
-#define PCI_DVMA_CONTROL_INACTIVITY_REQ (1<<0)
-#define PCI_DVMA_CONTROL_IOTLB_ENABLE (1<<0)
-#define PCI_DVMA_CONTROL_IOTLB_DISABLE 0
-#define PCI_DVMA_CONTROL_INACTIVITY_ACK (1<<4)
-#define PCI_INTERRUPT_CONTROL 0x63 /* 8 bits */
-#define PCI_CPU_INTERRUPT_PENDING 0x64 /* 32 bits */
-#define PCI_DIAGNOSTIC_1 0x68 /* 16 bits */
-#define PCI_SOFTWARE_INT_CLEAR 0x6a /* 16 bits */
-#define PCI_SOFTWARE_INT_SET 0x6e /* 16 bits */
-#define PCI_SYS_INT_PENDING 0x70 /* 32 bits */
-#define PCI_SYS_INT_PENDING_PIO 0x40000000
-#define PCI_SYS_INT_PENDING_DMA 0x20000000
-#define PCI_SYS_INT_PENDING_PCI 0x10000000
-#define PCI_SYS_INT_PENDING_APSR 0x08000000
-#define PCI_SYS_INT_TARGET_MASK 0x74 /* 32 bits */
-#define PCI_SYS_INT_TARGET_MASK_CLEAR 0x78 /* 32 bits */
-#define PCI_SYS_INT_TARGET_MASK_SET 0x7c /* 32 bits */
-#define PCI_SYS_INT_PENDING_CLEAR 0x83 /* 8 bits */
-#define PCI_SYS_INT_PENDING_CLEAR_ALL 0x80
-#define PCI_SYS_INT_PENDING_CLEAR_PIO 0x40
-#define PCI_SYS_INT_PENDING_CLEAR_DMA 0x20
-#define PCI_SYS_INT_PENDING_CLEAR_PCI 0x10
-#define PCI_IOTLB_CONTROL 0x84 /* 8 bits */
-#define PCI_INT_SELECT_LO 0x88 /* 16 bits */
-#define PCI_ARBITRATION_SELECT 0x8a /* 16 bits */
-#define PCI_INT_SELECT_HI 0x8c /* 16 bits */
-#define PCI_HW_INT_OUTPUT 0x8e /* 16 bits */
-#define PCI_IOTLB_RAM_INPUT 0x90 /* 32 bits */
-#define PCI_IOTLB_CAM_INPUT 0x94 /* 32 bits */
-#define PCI_IOTLB_RAM_OUTPUT 0x98 /* 32 bits */
-#define PCI_IOTLB_CAM_OUTPUT 0x9c /* 32 bits */
-#define PCI_SMBAR0 0xa0 /* 8 bits */
-#define PCI_MSIZE0 0xa1 /* 8 bits */
-#define PCI_PMBAR0 0xa2 /* 8 bits */
-#define PCI_SMBAR1 0xa4 /* 8 bits */
-#define PCI_MSIZE1 0xa5 /* 8 bits */
-#define PCI_PMBAR1 0xa6 /* 8 bits */
-#define PCI_SIBAR 0xa8 /* 8 bits */
-#define PCI_SIBAR_ADDRESS_MASK 0xf
-#define PCI_ISIZE 0xa9 /* 8 bits */
-#define PCI_ISIZE_16M 0xf
-#define PCI_ISIZE_32M 0xe
-#define PCI_ISIZE_64M 0xc
-#define PCI_ISIZE_128M 0x8
-#define PCI_ISIZE_256M 0x0
-#define PCI_PIBAR 0xaa /* 8 bits */
-#define PCI_CPU_COUNTER_LIMIT_HI 0xac /* 32 bits */
-#define PCI_CPU_COUNTER_LIMIT_LO 0xb0 /* 32 bits */
-#define PCI_CPU_COUNTER_LIMIT 0xb4 /* 32 bits */
-#define PCI_SYS_LIMIT 0xb8 /* 32 bits */
-#define PCI_SYS_COUNTER 0xbc /* 32 bits */
-#define PCI_SYS_COUNTER_OVERFLOW (1<<31) /* Limit reached */
-#define PCI_SYS_LIMIT_PSEUDO 0xc0 /* 32 bits */
-#define PCI_USER_TIMER_CONTROL 0xc4 /* 8 bits */
-#define PCI_USER_TIMER_CONFIG 0xc5 /* 8 bits */
-#define PCI_COUNTER_IRQ 0xc6 /* 8 bits */
-#define PCI_COUNTER_IRQ_SET(sys_irq, cpu_irq) ((((sys_irq) & 0xf) << 4) | \
- ((cpu_irq) & 0xf))
-#define PCI_COUNTER_IRQ_SYS(v) (((v) >> 4) & 0xf)
-#define PCI_COUNTER_IRQ_CPU(v) ((v) & 0xf)
-#define PCI_PIO_ERROR_COMMAND 0xc7 /* 8 bits */
-#define PCI_PIO_ERROR_ADDRESS 0xc8 /* 32 bits */
-#define PCI_IOTLB_ERROR_ADDRESS 0xcc /* 32 bits */
-#define PCI_SYS_STATUS 0xd0 /* 8 bits */
-#define PCI_SYS_STATUS_RESET_ENABLE (1<<0)
-#define PCI_SYS_STATUS_RESET (1<<1)
-#define PCI_SYS_STATUS_WATCHDOG_RESET (1<<4)
-#define PCI_SYS_STATUS_PCI_RESET (1<<5)
-#define PCI_SYS_STATUS_PCI_RESET_ENABLE (1<<6)
-#define PCI_SYS_STATUS_PCI_SATTELITE_MODE (1<<7)
-
-#endif /* !(__SPARC_PCIC_H) */
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 5ddc11cfd84a..ffdfb64f1d02 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -75,7 +75,6 @@ obj-$(CONFIG_SPARC64) += pcr.o
obj-$(CONFIG_SPARC64) += nmi.o
obj-$(CONFIG_SPARC64_SMP) += cpumap.o

-obj-$(CONFIG_PCIC_PCI) += pcic.o
obj-$(CONFIG_LEON_PCI) += leon_pci.o
obj-$(CONFIG_SPARC_GRPCI2)+= leon_pci_grpci2.o
obj-$(CONFIG_SPARC_GRPCI1)+= leon_pci_grpci1.o
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index e7cf5013aa40..451eaae85760 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -967,54 +967,6 @@ restore_current:
retl
nop

-#ifdef CONFIG_PCIC_PCI
-#include <asm/pcic.h>
-
- .align 4
- .globl linux_trap_ipi15_pcic
-linux_trap_ipi15_pcic:
- rd %wim, %l3
- SAVE_ALL
-
- /*
- * First deactivate NMI
- * or we cannot drop ET, cannot get window spill traps.
- * The busy loop is necessary because the PIO error
- * sometimes does not go away quickly and we trap again.
- */
- sethi %hi(pcic_regs), %o1
- ld [%o1 + %lo(pcic_regs)], %o2
-
- ! Get pending status for printouts later.
- ld [%o2 + PCI_SYS_INT_PENDING], %o0
-
- mov PCI_SYS_INT_PENDING_CLEAR_ALL, %o1
- stb %o1, [%o2 + PCI_SYS_INT_PENDING_CLEAR]
-1:
- ld [%o2 + PCI_SYS_INT_PENDING], %o1
- andcc %o1, ((PCI_SYS_INT_PENDING_PIO|PCI_SYS_INT_PENDING_PCI)>>24), %g0
- bne 1b
- nop
-
- or %l0, PSR_PIL, %l4
- wr %l4, 0x0, %psr
- WRITE_PAUSE
- wr %l4, PSR_ET, %psr
- WRITE_PAUSE
-
- call pcic_nmi
- add %sp, STACKFRAME_SZ, %o1 ! struct pt_regs *regs
- RESTORE_ALL
-
- .globl pcic_nmi_trap_patch
-pcic_nmi_trap_patch:
- sethi %hi(linux_trap_ipi15_pcic), %l3
- jmpl %l3 + %lo(linux_trap_ipi15_pcic), %g0
- rd %psr, %l0
- .word 0
-
-#endif /* CONFIG_PCIC_PCI */
-
.globl flushw_all
flushw_all:
save %sp, -0x40, %sp
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index 135170f362c1..a6af08fce796 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -19,7 +19,6 @@
#include <asm/cacheflush.h>
#include <asm/cpudata.h>
#include <asm/setup.h>
-#include <asm/pcic.h>
#include <asm/leon.h>

#include "kernel.h"
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 8b7cc8899122..15cab96caf14 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -157,10 +157,6 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn);
/* windows.c */
void try_to_clear_window_buffer(struct pt_regs *regs, int who);

-/* pcic.c */
-extern void __iomem *pcic_regs;
-void pcic_nmi(unsigned int pend, struct pt_regs *regs);
-
/* time_32.c */
void __init time_init(void);

diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
deleted file mode 100644
index 87bdcb16019b..000000000000
--- a/arch/sparc/kernel/pcic.c
+++ /dev/null
@@ -1,830 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * pcic.c: MicroSPARC-IIep PCI controller support
- *
- * Copyright (C) 1998 V. Roganov and G. Raiko
- *
- * Code is derived from Ultra/PCI PSYCHO controller support, see that
- * for author info.
- *
- * Support for diverse IIep based platforms by Pete Zaitcev.
- * CP-1200 by Eric Brower.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-
-#include <asm/swift.h> /* for cache flushing. */
-#include <asm/io.h>
-
-#include <linux/ctype.h>
-#include <linux/pci.h>
-#include <linux/time.h>
-#include <linux/timex.h>
-#include <linux/interrupt.h>
-#include <linux/export.h>
-
-#include <asm/irq.h>
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/pcic.h>
-#include <asm/timex.h>
-#include <asm/timer.h>
-#include <linux/uaccess.h>
-#include <asm/irq_regs.h>
-
-#include "kernel.h"
-#include "irq.h"
-
-/*
- * I studied different documents and many live PROMs both from 2.30
- * family and 3.xx versions. I came to the amazing conclusion: there is
- * absolutely no way to route interrupts in IIep systems relying on
- * information which PROM presents. We must hardcode interrupt routing
- * schematics. And this actually sucks. -- zaitcev 1999/05/12
- *
- * To find irq for a device we determine which routing map
- * is in effect or, in other words, on which machine we are running.
- * We use PROM name for this although other techniques may be used
- * in special cases (Gleb reports a PROMless IIep based system).
- * Once we know the map we take device configuration address and
- * find PCIC pin number where INT line goes. Then we may either program
- * preferred irq into the PCIC or supply the preexisting irq to the device.
- */
-struct pcic_ca2irq {
- unsigned char busno; /* PCI bus number */
- unsigned char devfn; /* Configuration address */
- unsigned char pin; /* PCIC external interrupt pin */
- unsigned char irq; /* Preferred IRQ (mappable in PCIC) */
- unsigned int force; /* Enforce preferred IRQ */
-};
-
-struct pcic_sn2list {
- char *sysname;
- struct pcic_ca2irq *intmap;
- int mapdim;
-};
-
-/*
- * JavaEngine-1 apparently has different versions.
- *
- * According to communications with Sun folks, for P2 build 501-4628-03:
- * pin 0 - parallel, audio;
- * pin 1 - Ethernet;
- * pin 2 - su;
- * pin 3 - PS/2 kbd and mouse.
- *
- * OEM manual (805-1486):
- * pin 0: Ethernet
- * pin 1: All EBus
- * pin 2: IGA (unused)
- * pin 3: Not connected
- * OEM manual says that 501-4628 & 501-4811 are the same thing,
- * only the latter has NAND flash in place.
- *
- * So far unofficial Sun wins over the OEM manual. Poor OEMs...
- */
-static struct pcic_ca2irq pcic_i_je1a[] = { /* 501-4811-03 */
- { 0, 0x00, 2, 12, 0 }, /* EBus: hogs all */
- { 0, 0x01, 1, 6, 1 }, /* Happy Meal */
- { 0, 0x80, 0, 7, 0 }, /* IGA (unused) */
-};
-
-/* XXX JS-E entry is incomplete - PCI Slot 2 address (pin 7)? */
-static struct pcic_ca2irq pcic_i_jse[] = {
- { 0, 0x00, 0, 13, 0 }, /* Ebus - serial and keyboard */
- { 0, 0x01, 1, 6, 0 }, /* hme */
- { 0, 0x08, 2, 9, 0 }, /* VGA - we hope not used :) */
- { 0, 0x10, 6, 8, 0 }, /* PCI INTA# in Slot 1 */
- { 0, 0x18, 7, 12, 0 }, /* PCI INTA# in Slot 2, shared w. RTC */
- { 0, 0x38, 4, 9, 0 }, /* All ISA devices. Read 8259. */
- { 0, 0x80, 5, 11, 0 }, /* EIDE */
- /* {0,0x88, 0,0,0} - unknown device... PMU? Probably no interrupt. */
- { 0, 0xA0, 4, 9, 0 }, /* USB */
- /*
- * Some pins belong to non-PCI devices, we hardcode them in drivers.
- * sun4m timers - irq 10, 14
- * PC style RTC - pin 7, irq 4 ?
- * Smart card, Parallel - pin 4 shared with USB, ISA
- * audio - pin 3, irq 5 ?
- */
-};
-
-/* SPARCengine-6 was the original release name of CP1200.
- * The documentation differs between the two versions
- */
-static struct pcic_ca2irq pcic_i_se6[] = {
- { 0, 0x08, 0, 2, 0 }, /* SCSI */
- { 0, 0x01, 1, 6, 0 }, /* HME */
- { 0, 0x00, 3, 13, 0 }, /* EBus */
-};
-
-/*
- * Krups (courtesy of Varol Kaptan)
- * No documentation available, but it was easy to guess
- * because it was very similar to Espresso.
- *
- * pin 0 - kbd, mouse, serial;
- * pin 1 - Ethernet;
- * pin 2 - igs (we do not use it);
- * pin 3 - audio;
- * pin 4,5,6 - unused;
- * pin 7 - RTC (from P2 onwards as David B. says).
- */
-static struct pcic_ca2irq pcic_i_jk[] = {
- { 0, 0x00, 0, 13, 0 }, /* Ebus - serial and keyboard */
- { 0, 0x01, 1, 6, 0 }, /* hme */
-};
-
-/*
- * Several entries in this list may point to the same routing map
- * as several PROMs may be installed on the same physical board.
- */
-#define SN2L_INIT(name, map) \
- { name, map, ARRAY_SIZE(map) }
-
-static struct pcic_sn2list pcic_known_sysnames[] = {
- SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */
- SN2L_INIT("SUNW,JS-E", pcic_i_jse), /* PROLL JavaStation-E */
- SN2L_INIT("SUNW,SPARCengine-6", pcic_i_se6), /* SPARCengine-6/CP-1200 */
- SN2L_INIT("SUNW,JS-NC", pcic_i_jk), /* PROLL JavaStation-NC */
- SN2L_INIT("SUNW,JSIIep", pcic_i_jk), /* OBP JavaStation-NC */
- { NULL, NULL, 0 }
-};
-
-/*
- * Only one PCIC per IIep,
- * and since we have no SMP IIep, only one per system.
- */
-static int pcic0_up;
-static struct linux_pcic pcic0;
-
-void __iomem *pcic_regs;
-static volatile int pcic_speculative;
-static volatile int pcic_trapped;
-
-/* forward */
-unsigned int pcic_build_device_irq(struct platform_device *op,
- unsigned int real_irq);
-
-#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3))
-
-static int pcic_read_config_dword(unsigned int busno, unsigned int devfn,
- int where, u32 *value)
-{
- struct linux_pcic *pcic;
- unsigned long flags;
-
- pcic = &pcic0;
-
- local_irq_save(flags);
-#if 0 /* does not fail here */
- pcic_speculative = 1;
- pcic_trapped = 0;
-#endif
- writel(CONFIG_CMD(busno, devfn, where), pcic->pcic_config_space_addr);
-#if 0 /* does not fail here */
- nop();
- if (pcic_trapped) {
- local_irq_restore(flags);
- *value = ~0;
- return 0;
- }
-#endif
- pcic_speculative = 2;
- pcic_trapped = 0;
- *value = readl(pcic->pcic_config_space_data + (where&4));
- nop();
- if (pcic_trapped) {
- pcic_speculative = 0;
- local_irq_restore(flags);
- *value = ~0;
- return 0;
- }
- pcic_speculative = 0;
- local_irq_restore(flags);
- return 0;
-}
-
-static int pcic_read_config(struct pci_bus *bus, unsigned int devfn,
- int where, int size, u32 *val)
-{
- unsigned int v;
-
- if (bus->number != 0) return -EINVAL;
- switch (size) {
- case 1:
- pcic_read_config_dword(bus->number, devfn, where&~3, &v);
- *val = 0xff & (v >> (8*(where & 3)));
- return 0;
- case 2:
- if (where&1) return -EINVAL;
- pcic_read_config_dword(bus->number, devfn, where&~3, &v);
- *val = 0xffff & (v >> (8*(where & 3)));
- return 0;
- case 4:
- if (where&3) return -EINVAL;
- pcic_read_config_dword(bus->number, devfn, where&~3, val);
- return 0;
- }
- return -EINVAL;
-}
-
-static int pcic_write_config_dword(unsigned int busno, unsigned int devfn,
- int where, u32 value)
-{
- struct linux_pcic *pcic;
- unsigned long flags;
-
- pcic = &pcic0;
-
- local_irq_save(flags);
- writel(CONFIG_CMD(busno, devfn, where), pcic->pcic_config_space_addr);
- writel(value, pcic->pcic_config_space_data + (where&4));
- local_irq_restore(flags);
- return 0;
-}
-
-static int pcic_write_config(struct pci_bus *bus, unsigned int devfn,
- int where, int size, u32 val)
-{
- unsigned int v;
-
- if (bus->number != 0) return -EINVAL;
- switch (size) {
- case 1:
- pcic_read_config_dword(bus->number, devfn, where&~3, &v);
- v = (v & ~(0xff << (8*(where&3)))) |
- ((0xff&val) << (8*(where&3)));
- return pcic_write_config_dword(bus->number, devfn, where&~3, v);
- case 2:
- if (where&1) return -EINVAL;
- pcic_read_config_dword(bus->number, devfn, where&~3, &v);
- v = (v & ~(0xffff << (8*(where&3)))) |
- ((0xffff&val) << (8*(where&3)));
- return pcic_write_config_dword(bus->number, devfn, where&~3, v);
- case 4:
- if (where&3) return -EINVAL;
- return pcic_write_config_dword(bus->number, devfn, where, val);
- }
- return -EINVAL;
-}
-
-static struct pci_ops pcic_ops = {
- .read = pcic_read_config,
- .write = pcic_write_config,
-};
-
-/*
- * On sparc64 pcibios_init() calls pci_controller_probe().
- * We want PCIC probed little ahead so that interrupt controller
- * would be operational.
- */
-int __init pcic_probe(void)
-{
- struct linux_pcic *pcic;
- struct linux_prom_registers regs[PROMREG_MAX];
- struct linux_pbm_info* pbm;
- char namebuf[64];
- phandle node;
- int err;
-
- if (pcic0_up) {
- prom_printf("PCIC: called twice!\n");
- prom_halt();
- }
- pcic = &pcic0;
-
- node = prom_getchild (prom_root_node);
- node = prom_searchsiblings (node, "pci");
- if (node == 0)
- return -ENODEV;
- /*
- * Map in PCIC register set, config space, and IO base
- */
- err = prom_getproperty(node, "reg", (char*)regs, sizeof(regs));
- if (err == 0 || err == -1) {
- prom_printf("PCIC: Error, cannot get PCIC registers "
- "from PROM.\n");
- prom_halt();
- }
-
- pcic0_up = 1;
-
- pcic->pcic_res_regs.name = "pcic_registers";
- pcic->pcic_regs = ioremap(regs[0].phys_addr, regs[0].reg_size);
- if (!pcic->pcic_regs) {
- prom_printf("PCIC: Error, cannot map PCIC registers.\n");
- prom_halt();
- }
-
- pcic->pcic_res_io.name = "pcic_io";
- if ((pcic->pcic_io = (unsigned long)
- ioremap(regs[1].phys_addr, 0x10000)) == 0) {
- prom_printf("PCIC: Error, cannot map PCIC IO Base.\n");
- prom_halt();
- }
-
- pcic->pcic_res_cfg_addr.name = "pcic_cfg_addr";
- if ((pcic->pcic_config_space_addr =
- ioremap(regs[2].phys_addr, regs[2].reg_size * 2)) == NULL) {
- prom_printf("PCIC: Error, cannot map "
- "PCI Configuration Space Address.\n");
- prom_halt();
- }
-
- /*
- * Docs say three least significant bits in address and data
- * must be the same. Thus, we need adjust size of data.
- */
- pcic->pcic_res_cfg_data.name = "pcic_cfg_data";
- if ((pcic->pcic_config_space_data =
- ioremap(regs[3].phys_addr, regs[3].reg_size * 2)) == NULL) {
- prom_printf("PCIC: Error, cannot map "
- "PCI Configuration Space Data.\n");
- prom_halt();
- }
-
- pbm = &pcic->pbm;
- pbm->prom_node = node;
- prom_getstring(node, "name", namebuf, 63); namebuf[63] = 0;
- strcpy(pbm->prom_name, namebuf);
-
- prom_getstring(prom_root_node, "name", namebuf, 63); namebuf[63] = 0;
- {
- struct pcic_sn2list *p;
-
- for (p = pcic_known_sysnames; p->sysname != NULL; p++) {
- if (strcmp(namebuf, p->sysname) == 0)
- break;
- }
- pcic->pcic_imap = p->intmap;
- pcic->pcic_imdim = p->mapdim;
- }
- if (pcic->pcic_imap == NULL) {
- /*
- * We do not panic here for the sake of embedded systems.
- */
- printk("PCIC: System %s is unknown, cannot route interrupts\n",
- namebuf);
- }
-
- return 0;
-}
-
-static void __init pcic_pbm_scan_bus(struct linux_pcic *pcic)
-{
- struct linux_pbm_info *pbm = &pcic->pbm;
-
- pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, &pcic_ops, pbm);
- if (!pbm->pci_bus)
- return;
-
-#if 0 /* deadwood transplanted from sparc64 */
- 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);
-#endif
- pci_bus_add_devices(pbm->pci_bus);
-}
-
-/*
- * Main entry point from the PCI subsystem.
- */
-static int __init pcic_init(void)
-{
- struct linux_pcic *pcic;
-
- /*
- * PCIC should be initialized at start of the timer.
- * So, here we report the presence of PCIC and do some magic passes.
- */
- if(!pcic0_up)
- return 0;
- pcic = &pcic0;
-
- /*
- * Switch off IOTLB translation.
- */
- writeb(PCI_DVMA_CONTROL_IOTLB_DISABLE,
- pcic->pcic_regs+PCI_DVMA_CONTROL);
-
- /*
- * Increase mapped size for PCI memory space (DMA access).
- * Should be done in that order (size first, address second).
- * Why we couldn't set up 4GB and forget about it? XXX
- */
- writel(0xF0000000UL, pcic->pcic_regs+PCI_SIZE_0);
- writel(0+PCI_BASE_ADDRESS_SPACE_MEMORY,
- pcic->pcic_regs+PCI_BASE_ADDRESS_0);
-
- pcic_pbm_scan_bus(pcic);
-
- return 0;
-}
-
-int pcic_present(void)
-{
- return pcic0_up;
-}
-
-static int pdev_to_pnode(struct linux_pbm_info *pbm, struct pci_dev *pdev)
-{
- struct linux_prom_pci_registers regs[PROMREG_MAX];
- int err;
- phandle node = prom_getchild(pbm->prom_node);
-
- while(node) {
- err = prom_getproperty(node, "reg",
- (char *)&regs[0], sizeof(regs));
- if(err != 0 && err != -1) {
- unsigned long devfn = (regs[0].which_io >> 8) & 0xff;
- if(devfn == pdev->devfn)
- return node;
- }
- node = prom_getsibling(node);
- }
- return 0;
-}
-
-static inline struct pcidev_cookie *pci_devcookie_alloc(void)
-{
- return kmalloc(sizeof(struct pcidev_cookie), GFP_ATOMIC);
-}
-
-static void pcic_map_pci_device(struct linux_pcic *pcic,
- struct pci_dev *dev, int node)
-{
- char namebuf[64];
- unsigned long address;
- unsigned long flags;
- int j;
-
- if (node == 0 || node == -1) {
- strcpy(namebuf, "???");
- } else {
- prom_getstring(node, "name", namebuf, 63); namebuf[63] = 0;
- }
-
- for (j = 0; j < 6; j++) {
- address = dev->resource[j].start;
- if (address == 0) break; /* are sequential */
- flags = dev->resource[j].flags;
- if ((flags & IORESOURCE_IO) != 0) {
- if (address < 0x10000) {
- /*
- * A device responds to I/O cycles on PCI.
- * We generate these cycles with memory
- * access into the fixed map (phys 0x30000000).
- *
- * Since a device driver does not want to
- * do ioremap() before accessing PC-style I/O,
- * we supply virtual, ready to access address.
- *
- * Note that request_region()
- * works for these devices.
- *
- * XXX Neat trick, but it's a *bad* idea
- * to shit into regions like that.
- * What if we want to allocate one more
- * PCI base address...
- */
- dev->resource[j].start =
- pcic->pcic_io + address;
- dev->resource[j].end = 1; /* XXX */
- dev->resource[j].flags =
- (flags & ~IORESOURCE_IO) | IORESOURCE_MEM;
- } else {
- /*
- * OOPS... PCI Spec allows this. Sun does
- * not have any devices getting above 64K
- * so it must be user with a weird I/O
- * board in a PCI slot. We must remap it
- * under 64K but it is not done yet. XXX
- */
- pci_info(dev, "PCIC: Skipping I/O space at "
- "0x%lx, this will Oops if a driver "
- "attaches device '%s'\n", address,
- namebuf);
- }
- }
- }
-}
-
-static void
-pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
-{
- struct pcic_ca2irq *p;
- unsigned int real_irq;
- int i, ivec;
- char namebuf[64];
-
- if (node == 0 || node == -1) {
- strcpy(namebuf, "???");
- } else {
- prom_getstring(node, "name", namebuf, sizeof(namebuf));
- }
-
- if ((p = pcic->pcic_imap) == NULL) {
- dev->irq = 0;
- return;
- }
- for (i = 0; i < pcic->pcic_imdim; i++) {
- if (p->busno == dev->bus->number && p->devfn == dev->devfn)
- break;
- p++;
- }
- if (i >= pcic->pcic_imdim) {
- pci_info(dev, "PCIC: device %s not found in %d\n", namebuf,
- pcic->pcic_imdim);
- dev->irq = 0;
- return;
- }
-
- i = p->pin;
- if (i >= 0 && i < 4) {
- ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO);
- real_irq = ivec >> (i << 2) & 0xF;
- } else if (i >= 4 && i < 8) {
- ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI);
- real_irq = ivec >> ((i-4) << 2) & 0xF;
- } else { /* Corrupted map */
- pci_info(dev, "PCIC: BAD PIN %d\n", i); for (;;) {}
- }
-/* P3 */ /* printk("PCIC: device %s pin %d ivec 0x%x irq %x\n", namebuf, i, ivec, dev->irq); */
-
- /* real_irq means PROM did not bother to program the upper
- * half of PCIC. This happens on JS-E with PROM 3.11, for instance.
- */
- if (real_irq == 0 || p->force) {
- if (p->irq == 0 || p->irq >= 15) { /* Corrupted map */
- pci_info(dev, "PCIC: BAD IRQ %d\n", p->irq); for (;;) {}
- }
- pci_info(dev, "PCIC: setting irq %d at pin %d\n", p->irq,
- p->pin);
- real_irq = p->irq;
-
- i = p->pin;
- if (i >= 4) {
- ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI);
- ivec &= ~(0xF << ((i - 4) << 2));
- ivec |= p->irq << ((i - 4) << 2);
- writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_HI);
- } else {
- ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO);
- ivec &= ~(0xF << (i << 2));
- ivec |= p->irq << (i << 2);
- writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_LO);
- }
- }
- dev->irq = pcic_build_device_irq(NULL, real_irq);
-}
-
-/*
- * Normally called from {do_}pci_scan_bus...
- */
-void pcibios_fixup_bus(struct pci_bus *bus)
-{
- struct pci_dev *dev;
- struct linux_pcic *pcic;
- /* struct linux_pbm_info* pbm = &pcic->pbm; */
- int node;
- struct pcidev_cookie *pcp;
-
- if (!pcic0_up) {
- pci_info(bus, "pcibios_fixup_bus: no PCIC\n");
- return;
- }
- pcic = &pcic0;
-
- /*
- * Next crud is an equivalent of pbm = pcic_bus_to_pbm(bus);
- */
- if (bus->number != 0) {
- pci_info(bus, "pcibios_fixup_bus: nonzero bus 0x%x\n",
- bus->number);
- return;
- }
-
- list_for_each_entry(dev, &bus->devices, bus_list) {
- node = pdev_to_pnode(&pcic->pbm, dev);
- if(node == 0)
- node = -1;
-
- /* cookies */
- pcp = pci_devcookie_alloc();
- pcp->pbm = &pcic->pbm;
- pcp->prom_node = of_find_node_by_phandle(node);
- dev->sysdata = pcp;
-
- /* fixing I/O to look like memory */
- if ((dev->class>>16) != PCI_BASE_CLASS_BRIDGE)
- pcic_map_pci_device(pcic, dev, node);
-
- pcic_fill_irq(pcic, dev, node);
- }
-}
-
-int pcibios_enable_device(struct pci_dev *dev, int mask)
-{
- u16 cmd, oldcmd;
- int i;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- oldcmd = cmd;
-
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
- struct resource *res = &dev->resource[i];
-
- /* Only set up the requested stuff */
- if (!(mask & (1<<i)))
- continue;
-
- if (res->flags & IORESOURCE_IO)
- cmd |= PCI_COMMAND_IO;
- if (res->flags & IORESOURCE_MEM)
- cmd |= PCI_COMMAND_MEMORY;
- }
-
- if (cmd != oldcmd) {
- pci_info(dev, "enabling device (%04x -> %04x)\n", oldcmd, cmd);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
- return 0;
-}
-
-/* Makes compiler happy */
-static volatile int pcic_timer_dummy;
-
-static void pcic_clear_clock_irq(void)
-{
- pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT);
-}
-
-/* CPU frequency is 100 MHz, timer increments every 4 CPU clocks */
-#define USECS_PER_JIFFY (1000000 / HZ)
-#define TICK_TIMER_LIMIT ((100 * 1000000 / 4) / HZ)
-
-static unsigned int pcic_cycles_offset(void)
-{
- u32 value, count;
-
- value = readl(pcic0.pcic_regs + PCI_SYS_COUNTER);
- count = value & ~PCI_SYS_COUNTER_OVERFLOW;
-
- if (value & PCI_SYS_COUNTER_OVERFLOW)
- count += TICK_TIMER_LIMIT;
- /*
- * We divide all by HZ
- * to have microsecond resolution and to avoid overflow
- */
- count = ((count / HZ) * USECS_PER_JIFFY) / (TICK_TIMER_LIMIT / HZ);
-
- /* Coordinate with the sparc_config.clock_rate setting */
- return count * 2;
-}
-
-void __init pci_time_init(void)
-{
- struct linux_pcic *pcic = &pcic0;
- unsigned long v;
- int timer_irq, irq;
- int err;
-
-#ifndef CONFIG_SMP
- /*
- * The clock_rate is in SBUS dimension.
- * We take into account this in pcic_cycles_offset()
- */
- sparc_config.clock_rate = SBUS_CLOCK_RATE / HZ;
- sparc_config.features |= FEAT_L10_CLOCKEVENT;
-#endif
- sparc_config.features |= FEAT_L10_CLOCKSOURCE;
- sparc_config.get_cycles_offset = pcic_cycles_offset;
-
- writel (TICK_TIMER_LIMIT, pcic->pcic_regs+PCI_SYS_LIMIT);
- /* PROM should set appropriate irq */
- v = readb(pcic->pcic_regs+PCI_COUNTER_IRQ);
- timer_irq = PCI_COUNTER_IRQ_SYS(v);
- writel (PCI_COUNTER_IRQ_SET(timer_irq, 0),
- pcic->pcic_regs+PCI_COUNTER_IRQ);
- irq = pcic_build_device_irq(NULL, timer_irq);
- err = request_irq(irq, timer_interrupt,
- IRQF_TIMER, "timer", NULL);
- if (err) {
- prom_printf("time_init: unable to attach IRQ%d\n", timer_irq);
- prom_halt();
- }
- local_irq_enable();
-}
-
-
-#if 0
-static void watchdog_reset() {
- writeb(0, pcic->pcic_regs+PCI_SYS_STATUS);
-}
-#endif
-
-/*
- * NMI
- */
-void pcic_nmi(unsigned int pend, struct pt_regs *regs)
-{
- pend = swab32(pend);
-
- if (!pcic_speculative || (pend & PCI_SYS_INT_PENDING_PIO) == 0) {
- /*
- * XXX On CP-1200 PCI #SERR may happen, we do not know
- * what to do about it yet.
- */
- printk("Aiee, NMI pend 0x%x pc 0x%x spec %d, hanging\n",
- pend, (int)regs->pc, pcic_speculative);
- for (;;) { }
- }
- pcic_speculative = 0;
- pcic_trapped = 1;
- regs->pc = regs->npc;
- regs->npc += 4;
-}
-
-static inline unsigned long get_irqmask(int irq_nr)
-{
- return 1 << irq_nr;
-}
-
-static void pcic_mask_irq(struct irq_data *data)
-{
- unsigned long mask, flags;
-
- mask = (unsigned long)data->chip_data;
- local_irq_save(flags);
- writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_SET);
- local_irq_restore(flags);
-}
-
-static void pcic_unmask_irq(struct irq_data *data)
-{
- unsigned long mask, flags;
-
- mask = (unsigned long)data->chip_data;
- local_irq_save(flags);
- writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_CLEAR);
- local_irq_restore(flags);
-}
-
-static unsigned int pcic_startup_irq(struct irq_data *data)
-{
- irq_link(data->irq);
- pcic_unmask_irq(data);
- return 0;
-}
-
-static struct irq_chip pcic_irq = {
- .name = "pcic",
- .irq_startup = pcic_startup_irq,
- .irq_mask = pcic_mask_irq,
- .irq_unmask = pcic_unmask_irq,
-};
-
-unsigned int pcic_build_device_irq(struct platform_device *op,
- unsigned int real_irq)
-{
- unsigned int irq;
- unsigned long mask;
-
- irq = 0;
- mask = get_irqmask(real_irq);
- if (mask == 0)
- goto out;
-
- irq = irq_alloc(real_irq, real_irq);
- if (irq == 0)
- goto out;
-
- irq_set_chip_and_handler_name(irq, &pcic_irq,
- handle_level_irq, "PCIC");
- irq_set_chip_data(irq, (void *)mask);
-
-out:
- return irq;
-}
-
-
-static void pcic_load_profile_irq(int cpu, unsigned int limit)
-{
- printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__);
-}
-
-void __init sun4m_pci_init_IRQ(void)
-{
- sparc_config.build_device_irq = pcic_build_device_irq;
- sparc_config.clear_clock_irq = pcic_clear_clock_irq;
- sparc_config.load_profile_irq = pcic_load_profile_irq;
-}
-
-subsys_initcall(pcic_init);
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index 8a08830e4a65..0093cf4ecb06 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -44,7 +44,6 @@
#include <asm/io.h>
#include <asm/idprom.h>
#include <asm/page.h>
-#include <asm/pcic.h>
#include <asm/irq_regs.h>
#include <asm/setup.h>

@@ -348,9 +347,6 @@ void __init time_init(void)
sparc_config.features = 0;
late_time_init = sparc32_late_time_init;

- if (pcic_present())
- pci_time_init();
- else
- sbus_time_init();
+ sbus_time_init();
}

--
2.27.0

2020-12-18 20:46:40

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 13/13] sparc32: drop use of sparc_config

sparc_config were used to handle the differences between the machines.
With only LEON supported sparc_config is no longer required.

This has the added benefit that we get rid of a rw variable
with several function pointers thus reducing our attack surface.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/include/asm/timer_32.h | 1 +
arch/sparc/kernel/irq.h | 32 ++-------
arch/sparc/kernel/irq_32.c | 3 -
arch/sparc/kernel/leon_kernel.c | 27 ++------
arch/sparc/kernel/of_device_32.c | 4 +-
arch/sparc/kernel/time_32.c | 110 +++++++++++++-----------------
6 files changed, 61 insertions(+), 116 deletions(-)

diff --git a/arch/sparc/include/asm/timer_32.h b/arch/sparc/include/asm/timer_32.h
index eecd2696922d..1cd89a99966f 100644
--- a/arch/sparc/include/asm/timer_32.h
+++ b/arch/sparc/include/asm/timer_32.h
@@ -17,6 +17,7 @@
#include <asm/cpu_type.h> /* For SUN4M_NCPUS */

#define SBUS_CLOCK_RATE 2000000 /* 2MHz */
+#define LEON_CLOCK_RATE 1000000
#define TIMER_VALUE_SHIFT 9
#define TIMER_VALUE_MASK 0x3fffff
#define TIMER_LIMIT_BIT (1 << 31) /* Bit 31 in Counter-Timer register */
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h
index 0d9b740725b4..ba0db1e4df6f 100644
--- a/arch/sparc/kernel/irq.h
+++ b/arch/sparc/kernel/irq.h
@@ -49,33 +49,6 @@ extern struct sun4m_irq_global __iomem *sun4m_irq_global;
#define FEAT_L10_CLOCKEVENT (1 << 1) /* L10 timer is used as a clockevent */
#define FEAT_L14_ONESHOT (1 << 2) /* L14 timer clockevent can oneshot */

-/*
- * Platform specific configuration
- * The individual platforms assign their platform
- * specifics in their init functions.
- */
-struct sparc_config {
- void (*init_timers)(void);
- unsigned int (*build_device_irq)(struct platform_device *op,
- unsigned int real_irq);
-
- /* generic clockevent features - see FEAT_* above */
- int features;
-
- /* clock rate used for clock event timer */
- int clock_rate;
-
- /* one period for clock source timer */
- unsigned int cs_period;
-
- /* function to obtain offsett for cs period */
- unsigned int (*get_cycles_offset)(void);
-
- void (*clear_clock_irq)(void);
- void (*load_profile_irq)(int cpu, unsigned int limit);
-};
-extern struct sparc_config sparc_config;
-
unsigned int irq_alloc(unsigned int real_irq, unsigned int pil);
void irq_link(unsigned int irq);
void irq_unlink(unsigned int irq);
@@ -89,6 +62,11 @@ void sun4m_nmi(struct pt_regs *regs);
/* sun4d_irq.c */
void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs);

+/* leon_kernel.c */
+void leon_clear_clock_irq(void);
+void leon_load_profile_irq(int cpu, unsigned int limit);
+u32 leon_cycles_offset(void);
+
#ifdef CONFIG_SMP

/* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index a6af08fce796..f76f57073323 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -24,9 +24,6 @@
#include "kernel.h"
#include "irq.h"

-/* platform specific irq setup */
-struct sparc_config sparc_config;
-
unsigned long arch_local_irq_save(void)
{
unsigned long retval;
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 49b37a0dcc2b..491dff89f52c 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -239,12 +239,6 @@ unsigned int leon_build_device_irq(unsigned int real_irq,
return irq;
}

-static unsigned int _leon_build_device_irq(struct platform_device *op,
- unsigned int real_irq)
-{
- return leon_build_device_irq(real_irq, handle_simple_irq, "edge", 0);
-}
-
void leon_update_virq_handling(unsigned int virq,
irq_flow_handler_t flow_handler,
const char *name, int do_ack)
@@ -260,7 +254,7 @@ void leon_update_virq_handling(unsigned int virq,
irq_set_chip_data(virq, (void *)mask);
}

-static u32 leon_cycles_offset(void)
+u32 leon_cycles_offset(void)
{
u32 rld, val, ctrl, off;

@@ -314,14 +308,6 @@ void __init leon_init_timers(void)
u32 config;
u32 ctrl;

- sparc_config.get_cycles_offset = leon_cycles_offset;
- sparc_config.cs_period = 1000000 / HZ;
- sparc_config.features |= FEAT_L10_CLOCKSOURCE;
-
-#ifndef CONFIG_SMP
- sparc_config.features |= FEAT_L10_CLOCKEVENT;
-#endif
-
leondebug_irq_disable = 0;
leon_debug_irqout = 0;
master_l10_counter = (u32 __iomem *)&dummy_master_l10_counter;
@@ -436,7 +422,7 @@ void __init leon_init_timers(void)
err = request_irq(irq, leon_percpu_timer_ce_interrupt,
IRQF_PERCPU | IRQF_TIMER, "timer", NULL);
#else
- irq = _leon_build_device_irq(NULL, leon3_gptimer_irq);
+ irq = leon_build_device_irq(leon3_gptimer_irq, handle_simple_irq, "edge", 0);
err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
#endif
if (err) {
@@ -455,7 +441,7 @@ void __init leon_init_timers(void)
return;
}

-static void leon_clear_clock_irq(void)
+void leon_clear_clock_irq(void)
{
u32 ctrl;

@@ -464,7 +450,7 @@ static void leon_clear_clock_irq(void)
ctrl & leon3_gptimer_ackmask);
}

-static void leon_load_profile_irq(int cpu, unsigned int limit)
+void leon_load_profile_irq(int cpu, unsigned int limit)
{
}

@@ -487,9 +473,4 @@ void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu)

void __init leon_init_IRQ(void)
{
- sparc_config.init_timers = leon_init_timers;
- sparc_config.build_device_irq = _leon_build_device_irq;
- sparc_config.clock_rate = 1000000;
- sparc_config.clear_clock_irq = leon_clear_clock_irq;
- sparc_config.load_profile_irq = leon_load_profile_irq;
}
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
index 4ebf51e6e78e..c846acdb4455 100644
--- a/arch/sparc/kernel/of_device_32.c
+++ b/arch/sparc/kernel/of_device_32.c
@@ -358,7 +358,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp,
op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs);
for (i = 0; i < op->archdata.num_irqs; i++)
op->archdata.irqs[i] =
- sparc_config.build_device_irq(op, intr[i].pri);
+ leon_build_device_irq(intr[i].pri, handle_simple_irq, "edge", 0);
} else {
const unsigned int *irq =
of_get_property(dp, "interrupts", &len);
@@ -367,7 +367,7 @@ static struct platform_device * __init scan_one_device(struct device_node *dp,
op->archdata.num_irqs = len / sizeof(unsigned int);
for (i = 0; i < op->archdata.num_irqs; i++)
op->archdata.irqs[i] =
- sparc_config.build_device_irq(op, irq[i]);
+ leon_build_device_irq(irq[i], handle_simple_irq, "edge", 0);
} else {
op->archdata.num_irqs = 0;
}
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index 0093cf4ecb06..8619a3d9953f 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -45,6 +45,7 @@
#include <asm/idprom.h>
#include <asm/page.h>
#include <asm/irq_regs.h>
+#include <asm/leon.h>
#include <asm/setup.h>

#include "kernel.h"
@@ -89,10 +90,10 @@ irqreturn_t notrace timer_interrupt(int dummy, void *dev_id)
if (timer_cs_enabled) {
write_seqlock(&timer_cs_lock);
timer_cs_internal_counter++;
- sparc_config.clear_clock_irq();
+ leon_clear_clock_irq();
write_sequnlock(&timer_cs_lock);
} else {
- sparc_config.clear_clock_irq();
+ leon_clear_clock_irq();
}

if (timer_ce_enabled)
@@ -101,39 +102,6 @@ irqreturn_t notrace timer_interrupt(int dummy, void *dev_id)
return IRQ_HANDLED;
}

-static int timer_ce_shutdown(struct clock_event_device *evt)
-{
- timer_ce_enabled = 0;
- smp_mb();
- return 0;
-}
-
-static int timer_ce_set_periodic(struct clock_event_device *evt)
-{
- timer_ce_enabled = 1;
- smp_mb();
- return 0;
-}
-
-static __init void setup_timer_ce(void)
-{
- struct clock_event_device *ce = &timer_ce;
-
- BUG_ON(smp_processor_id() != boot_cpu_id);
-
- ce->name = "timer_ce";
- ce->rating = 100;
- ce->features = CLOCK_EVT_FEAT_PERIODIC;
- ce->set_state_shutdown = timer_ce_shutdown;
- ce->set_state_periodic = timer_ce_set_periodic;
- ce->tick_resume = timer_ce_set_periodic;
- ce->cpumask = cpu_possible_mask;
- ce->shift = 32;
- ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC,
- ce->shift);
- clockevents_register_device(ce);
-}
-
static unsigned int sbus_cycles_offset(void)
{
u32 val, offset;
@@ -143,7 +111,7 @@ static unsigned int sbus_cycles_offset(void)

/* Limit hit? */
if (val & TIMER_LIMIT_BIT)
- offset += sparc_config.cs_period;
+ offset += 1000000 / HZ;

return offset;
}
@@ -157,11 +125,11 @@ static u64 timer_cs_read(struct clocksource *cs)
seq = read_seqbegin(&timer_cs_lock);

cycles = timer_cs_internal_counter;
- offset = sparc_config.get_cycles_offset();
+ offset = sbus_cycles_offset();
} while (read_seqretry(&timer_cs_lock, seq));

/* Count absolute cycles */
- cycles *= sparc_config.cs_period;
+ cycles *= LEON_CLOCK_RATE / HZ;
cycles += offset;

return cycles;
@@ -178,15 +146,47 @@ static struct clocksource timer_cs = {
static __init int setup_timer_cs(void)
{
timer_cs_enabled = 1;
- return clocksource_register_hz(&timer_cs, sparc_config.clock_rate);
+ return clocksource_register_hz(&timer_cs, LEON_CLOCK_RATE);
}

#ifdef CONFIG_SMP
+static int timer_ce_shutdown(struct clock_event_device *evt)
+{
+ timer_ce_enabled = 0;
+ smp_mb();
+ return 0;
+}
+
+static int timer_ce_set_periodic(struct clock_event_device *evt)
+{
+ timer_ce_enabled = 1;
+ smp_mb();
+ return 0;
+}
+
+static __init void setup_timer_ce(void)
+{
+ struct clock_event_device *ce = &timer_ce;
+
+ BUG_ON(smp_processor_id() != boot_cpu_id);
+
+ ce->name = "timer_ce";
+ ce->rating = 100;
+ ce->features = CLOCK_EVT_FEAT_PERIODIC;
+ ce->set_state_shutdown = timer_ce_shutdown;
+ ce->set_state_periodic = timer_ce_set_periodic;
+ ce->tick_resume = timer_ce_set_periodic;
+ ce->cpumask = cpu_possible_mask;
+ ce->shift = 32;
+ ce->mult = div_sc(LEON_CLOCK_RATE, NSEC_PER_SEC, ce->shift);
+ clockevents_register_device(ce);
+}
+
static int percpu_ce_shutdown(struct clock_event_device *evt)
{
int cpu = cpumask_first(evt->cpumask);

- sparc_config.load_profile_irq(cpu, 0);
+ leon_load_profile_irq(cpu, 0);
return 0;
}

@@ -194,7 +194,7 @@ static int percpu_ce_set_periodic(struct clock_event_device *evt)
{
int cpu = cpumask_first(evt->cpumask);

- sparc_config.load_profile_irq(cpu, SBUS_CLOCK_RATE / HZ);
+ leon_load_profile_irq(cpu, SBUS_CLOCK_RATE / HZ);
return 0;
}

@@ -204,7 +204,7 @@ static int percpu_ce_set_next_event(unsigned long delta,
int cpu = cpumask_first(evt->cpumask);
unsigned int next = (unsigned int)delta;

- sparc_config.load_profile_irq(cpu, next);
+ leon_load_profile_irq(cpu, next);
return 0;
}

@@ -213,9 +213,6 @@ void register_percpu_ce(int cpu)
struct clock_event_device *ce = &per_cpu(sparc32_clockevent, cpu);
unsigned int features = CLOCK_EVT_FEAT_PERIODIC;

- if (sparc_config.features & FEAT_L14_ONESHOT)
- features |= CLOCK_EVT_FEAT_ONESHOT;
-
ce->name = "percpu_ce";
ce->rating = 200;
ce->features = features;
@@ -225,10 +222,9 @@ void register_percpu_ce(int cpu)
ce->set_next_event = percpu_ce_set_next_event;
ce->cpumask = cpumask_of(cpu);
ce->shift = 32;
- ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC,
- ce->shift);
- ce->max_delta_ns = clockevent_delta2ns(sparc_config.clock_rate, ce);
- ce->max_delta_ticks = (unsigned long)sparc_config.clock_rate;
+ ce->mult = div_sc(LEON_CLOCK_RATE, NSEC_PER_SEC, ce->shift);
+ ce->max_delta_ns = clockevent_delta2ns(LEON_CLOCK_RATE, ce);
+ ce->max_delta_ticks = (unsigned long)LEON_CLOCK_RATE;
ce->min_delta_ns = clockevent_delta2ns(100, ce);
ce->min_delta_ticks = 100;

@@ -327,26 +323,18 @@ fs_initcall(clock_init);

static void __init sparc32_late_time_init(void)
{
- if (sparc_config.features & FEAT_L10_CLOCKEVENT)
- setup_timer_ce();
- if (sparc_config.features & FEAT_L10_CLOCKSOURCE)
- setup_timer_cs();
+ setup_timer_cs();
+
#ifdef CONFIG_SMP
+ setup_timer_ce();
register_percpu_ce(smp_processor_id());
#endif
}

-static void __init sbus_time_init(void)
-{
- sparc_config.get_cycles_offset = sbus_cycles_offset;
- sparc_config.init_timers();
-}
-
void __init time_init(void)
{
- sparc_config.features = 0;
late_time_init = sparc32_late_time_init;

- sbus_time_init();
+ leon_init_timers();
}

--
2.27.0

2020-12-18 20:46:49

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 12/13] sparc32: drop check for sparc_model

sparc32 is always LEON, so no need to check for the model.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Stephen Rothwell <[email protected]>
Cc: Anshuman Khandual <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Arvind Sankar <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/include/asm/cpu_type.h | 18 -------
arch/sparc/include/asm/io_32.h | 4 +-
arch/sparc/include/asm/pgtable_32.h | 24 ---------
arch/sparc/kernel/devices.c | 7 +--
arch/sparc/kernel/ioport.c | 6 +--
arch/sparc/kernel/leon_pmc.c | 14 +++--
arch/sparc/kernel/setup_32.c | 79 +----------------------------
7 files changed, 12 insertions(+), 140 deletions(-)

diff --git a/arch/sparc/include/asm/cpu_type.h b/arch/sparc/include/asm/cpu_type.h
index 2b59799859d1..3e0154c3f41d 100644
--- a/arch/sparc/include/asm/cpu_type.h
+++ b/arch/sparc/include/asm/cpu_type.h
@@ -2,28 +2,10 @@
#ifndef __ASM_CPU_TYPE_H
#define __ASM_CPU_TYPE_H

-/*
- * Sparc (general) CPU types
- */
-enum sparc_cpu {
- sun4m = 0x00,
- sun4d = 0x01,
- sun4e = 0x02,
- sun4u = 0x03, /* V8 ploos ploos */
- sun_unknown = 0x04,
- ap1000 = 0x05, /* almost a sun4m */
- sparc_leon = 0x06, /* Leon SoC */
-};
-
#ifdef CONFIG_SPARC32
-extern enum sparc_cpu sparc_cpu_model;

#define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */

-#else
-
-#define sparc_cpu_model sun4u
-
#endif

#endif /* __ASM_CPU_TYPE_H */
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 549f0a72280d..83abe709d120 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -138,11 +138,11 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *);

static inline int sbus_can_dma_64bit(void)
{
- return 0; /* actually, sparc_cpu_model==sun4d */
+ return 0;
}
static inline int sbus_can_burst64(void)
{
- return 0; /* actually, sparc_cpu_model==sun4d */
+ return 0;
}
struct device;
void sbus_set_sbus64(struct device *, int);
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 632cdb959542..9c4da6ed81ef 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -356,30 +356,6 @@ static inline swp_entry_t __swp_entry(unsigned long type, unsigned long offset)
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })

-static inline unsigned long
-__get_phys (unsigned long addr)
-{
- switch (sparc_cpu_model){
- case sun4m:
- case sun4d:
- return ((srmmu_get_pte (addr) & 0xffffff00) << 4);
- default:
- return 0;
- }
-}
-
-static inline int
-__get_iospace (unsigned long addr)
-{
- switch (sparc_cpu_model){
- case sun4m:
- case sun4d:
- return (srmmu_get_pte (addr) >> 28);
- default:
- return -1;
- }
-}
-
extern unsigned long *sparc_valid_addr_bitmap;

/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c
index b3c2d51b22c4..2963e89611a3 100644
--- a/arch/sparc/kernel/devices.c
+++ b/arch/sparc/kernel/devices.c
@@ -26,8 +26,6 @@

static char *cpu_mid_prop(void)
{
- if (sparc_cpu_model == sun4d)
- return "cpu-id";
return "mid";
}

@@ -40,8 +38,6 @@ static int check_cpu_node(phandle nd, int *cur_inst,
*prom_node = nd;
if (mid) {
*mid = prom_getintdefault(nd, cpu_mid_prop(), 0);
- if (sparc_cpu_model == sun4m)
- *mid &= 3;
}
return 0;
}
@@ -92,8 +88,7 @@ static int cpu_mid_compare(phandle nd, int instance, void *_arg)
int this_mid;

this_mid = prom_getintdefault(nd, cpu_mid_prop(), 0);
- if (this_mid == desired_mid
- || (sparc_cpu_model == sun4m && (this_mid & 3) == desired_mid))
+ if (this_mid == desired_mid)
return 0;
return -ENODEV;
}
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 8e1d72a16759..50fb0a8431aa 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -57,10 +57,8 @@
*/
static inline void dma_make_coherent(unsigned long pa, unsigned long len)
{
- if (sparc_cpu_model == sparc_leon) {
- if (!sparc_leon3_snooping_enabled())
- leon_flush_dcache_all();
- }
+ if (!sparc_leon3_snooping_enabled())
+ leon_flush_dcache_all();
}

static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz);
diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c
index 396f46bca52e..625924dd0e5b 100644
--- a/arch/sparc/kernel/leon_pmc.c
+++ b/arch/sparc/kernel/leon_pmc.c
@@ -75,15 +75,13 @@ static void pmc_leon_idle(void)
/* Install LEON Power Down function */
static int __init leon_pmc_install(void)
{
- if (sparc_cpu_model == sparc_leon) {
- /* Assign power management IDLE handler */
- if (pmc_leon_need_fixup())
- sparc_idle = pmc_leon_idle_fixup;
- else
- sparc_idle = pmc_leon_idle;
+ /* Assign power management IDLE handler */
+ if (pmc_leon_need_fixup())
+ sparc_idle = pmc_leon_idle_fixup;
+ else
+ sparc_idle = pmc_leon_idle;

- printk(KERN_INFO "leon: power management initialized\n");
- }
+ printk(KERN_INFO "leon: power management initialized\n");

return 0;
}
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index b6fd87928c73..91c0c043a95d 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -202,30 +202,12 @@ static void __init per_cpu_patch(void)
{
struct cpuid_patch_entry *p;

- if (sparc_cpu_model == sun4m) {
- /* Nothing to do, this is what the unpatched code
- * targets.
- */
- return;
- }
-
p = &__cpuid_patch;
while (p < &__cpuid_patch_end) {
unsigned long addr = p->addr;
unsigned int *insns;

- switch (sparc_cpu_model) {
- case sun4d:
- insns = &p->sun4d[0];
- break;
-
- case sparc_leon:
- insns = &p->leon[0];
- break;
- default:
- prom_printf("Unknown cpu type, halting.\n");
- prom_halt();
- }
+ insns = &p->leon[0];
*(unsigned int *) (addr + 0) = insns[0];
flushi(addr + 0);
*(unsigned int *) (addr + 4) = insns[1];
@@ -237,31 +219,9 @@ static void __init per_cpu_patch(void)
}
}

-struct leon_1insn_patch_entry {
- unsigned int addr;
- unsigned int insn;
-};
-
-enum sparc_cpu sparc_cpu_model;
-EXPORT_SYMBOL(sparc_cpu_model);
-
static __init void leon_patch(void)
{
- struct leon_1insn_patch_entry *start = (void *)__leon_1insn_patch;
- struct leon_1insn_patch_entry *end = (void *)__leon_1insn_patch_end;
-
/* Default instruction is leon - no patching */
- if (sparc_cpu_model == sparc_leon)
- return;
-
- while (start < end) {
- unsigned long addr = start->addr;
-
- *(unsigned int *)(addr) = start->insn;
- flushi(addr);
-
- start++;
- }
}

struct tt_entry *sparc_ttable;
@@ -273,22 +233,6 @@ static struct pt_regs fake_swapper_regs;
void __init sparc32_start_kernel(struct linux_romvec *rp)
{
prom_init(rp);
-
- /* Set sparc_cpu_model */
- sparc_cpu_model = sun_unknown;
- if (!strcmp(&cputypval[0], "sun4m"))
- sparc_cpu_model = sun4m;
- if (!strcmp(&cputypval[0], "sun4s"))
- sparc_cpu_model = sun4m; /* CP-1200 with PROM 2.30 -E */
- if (!strcmp(&cputypval[0], "sun4d"))
- sparc_cpu_model = sun4d;
- if (!strcmp(&cputypval[0], "sun4e"))
- sparc_cpu_model = sun4e;
- if (!strcmp(&cputypval[0], "sun4u"))
- sparc_cpu_model = sun4u;
- if (!strncmp(&cputypval[0], "leon" , 4))
- sparc_cpu_model = sparc_leon;
-
leon_patch();
start_kernel();
}
@@ -309,27 +253,6 @@ void __init setup_arch(char **cmdline_p)

register_console(&prom_early_console);

- switch(sparc_cpu_model) {
- case sun4m:
- pr_info("ARCH: SUN4M\n");
- break;
- case sun4d:
- pr_info("ARCH: SUN4D\n");
- break;
- case sun4e:
- pr_info("ARCH: SUN4E\n");
- break;
- case sun4u:
- pr_info("ARCH: SUN4U\n");
- break;
- case sparc_leon:
- pr_info("ARCH: LEON\n");
- break;
- default:
- pr_info("ARCH: UNKNOWN!\n");
- break;
- }
-
idprom_init();
load_mmu();

--
2.27.0

2020-12-18 20:46:49

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 11/13] sparc32: Drop unused mmu models

Drop mmu models not used by LEON, including their header files.
This includes removal of unused includes in various files to fix the
build.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Christian Brauner <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: Ira Weiny <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/include/asm/mxcc.h | 138 ------
arch/sparc/include/asm/ross.h | 192 --------
arch/sparc/include/asm/swift.h | 107 -----
arch/sparc/include/asm/tsunami.h | 65 ---
arch/sparc/include/asm/viking.h | 255 ----------
arch/sparc/kernel/entry.S | 1 -
arch/sparc/mm/Makefile | 1 -
arch/sparc/mm/hypersparc.S | 414 -----------------
arch/sparc/mm/io-unit.c | 1 -
arch/sparc/mm/iommu.c | 31 +-
arch/sparc/mm/mm_32.h | 1 -
arch/sparc/mm/srmmu.c | 776 +------------------------------
arch/sparc/mm/swift.S | 256 ----------
arch/sparc/mm/tsunami.S | 132 ------
arch/sparc/mm/viking.S | 284 -----------
15 files changed, 21 insertions(+), 2633 deletions(-)
delete mode 100644 arch/sparc/include/asm/mxcc.h
delete mode 100644 arch/sparc/include/asm/ross.h
delete mode 100644 arch/sparc/include/asm/swift.h
delete mode 100644 arch/sparc/include/asm/tsunami.h
delete mode 100644 arch/sparc/include/asm/viking.h
delete mode 100644 arch/sparc/mm/hypersparc.S
delete mode 100644 arch/sparc/mm/swift.S
delete mode 100644 arch/sparc/mm/tsunami.S
delete mode 100644 arch/sparc/mm/viking.S

diff --git a/arch/sparc/include/asm/mxcc.h b/arch/sparc/include/asm/mxcc.h
deleted file mode 100644
index 3a2561bea4dd..000000000000
--- a/arch/sparc/include/asm/mxcc.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * mxcc.h: Definitions of the Viking MXCC registers
- *
- * Copyright (C) 1995 David S. Miller ([email protected])
- */
-
-#ifndef _SPARC_MXCC_H
-#define _SPARC_MXCC_H
-
-/* These registers are accessed through ASI 0x2. */
-#define MXCC_DATSTREAM 0x1C00000 /* Data stream register */
-#define MXCC_SRCSTREAM 0x1C00100 /* Source stream register */
-#define MXCC_DESSTREAM 0x1C00200 /* Destination stream register */
-#define MXCC_RMCOUNT 0x1C00300 /* Count of references and misses */
-#define MXCC_STEST 0x1C00804 /* Internal self-test */
-#define MXCC_CREG 0x1C00A04 /* Control register */
-#define MXCC_SREG 0x1C00B00 /* Status register */
-#define MXCC_RREG 0x1C00C04 /* Reset register */
-#define MXCC_EREG 0x1C00E00 /* Error code register */
-#define MXCC_PREG 0x1C00F04 /* Address port register */
-
-/* Some MXCC constants. */
-#define MXCC_STREAM_SIZE 0x20 /* Size in bytes of one stream r/w */
-
-/* The MXCC Control Register:
- *
- * ----------------------------------------------------------------------
- * | | RRC | RSV |PRE|MCE|PARE|ECE|RSV|
- * ----------------------------------------------------------------------
- * 31 10 9 8-6 5 4 3 2 1-0
- *
- * RRC: Controls what you read from MXCC_RMCOUNT reg.
- * 0=Misses 1=References
- * PRE: Prefetch enable
- * MCE: Multiple Command Enable
- * PARE: Parity enable
- * ECE: External cache enable
- */
-
-#define MXCC_CTL_RRC 0x00000200
-#define MXCC_CTL_PRE 0x00000020
-#define MXCC_CTL_MCE 0x00000010
-#define MXCC_CTL_PARE 0x00000008
-#define MXCC_CTL_ECE 0x00000004
-
-/* The MXCC Error Register:
- *
- * --------------------------------------------------------
- * |ME| RSV|CE|PEW|PEE|ASE|EIV| MOPC|ECODE|PRIV|RSV|HPADDR|
- * --------------------------------------------------------
- * 31 30 29 28 27 26 25 24-15 14-7 6 5-3 2-0
- *
- * ME: Multiple Errors have occurred
- * CE: Cache consistency Error
- * PEW: Parity Error during a Write operation
- * PEE: Parity Error involving the External cache
- * ASE: ASynchronous Error
- * EIV: This register is toast
- * MOPC: MXCC Operation Code for instance causing error
- * ECODE: The Error CODE
- * PRIV: A privileged mode error? 0=no 1=yes
- * HPADDR: High PhysicalADDRess bits (35-32)
- */
-
-#define MXCC_ERR_ME 0x80000000
-#define MXCC_ERR_CE 0x20000000
-#define MXCC_ERR_PEW 0x10000000
-#define MXCC_ERR_PEE 0x08000000
-#define MXCC_ERR_ASE 0x04000000
-#define MXCC_ERR_EIV 0x02000000
-#define MXCC_ERR_MOPC 0x01FF8000
-#define MXCC_ERR_ECODE 0x00007F80
-#define MXCC_ERR_PRIV 0x00000040
-#define MXCC_ERR_HPADDR 0x0000000f
-
-/* The MXCC Port register:
- *
- * -----------------------------------------------------
- * | | MID | |
- * -----------------------------------------------------
- * 31 21 20-18 17 0
- *
- * MID: The moduleID of the cpu your read this from.
- */
-
-#ifndef __ASSEMBLY__
-
-static inline void mxcc_set_stream_src(unsigned long *paddr)
-{
- unsigned long data0 = paddr[0];
- unsigned long data1 = paddr[1];
-
- __asm__ __volatile__ ("or %%g0, %0, %%g2\n\t"
- "or %%g0, %1, %%g3\n\t"
- "stda %%g2, [%2] %3\n\t" : :
- "r" (data0), "r" (data1),
- "r" (MXCC_SRCSTREAM),
- "i" (ASI_M_MXCC) : "g2", "g3");
-}
-
-static inline void mxcc_set_stream_dst(unsigned long *paddr)
-{
- unsigned long data0 = paddr[0];
- unsigned long data1 = paddr[1];
-
- __asm__ __volatile__ ("or %%g0, %0, %%g2\n\t"
- "or %%g0, %1, %%g3\n\t"
- "stda %%g2, [%2] %3\n\t" : :
- "r" (data0), "r" (data1),
- "r" (MXCC_DESSTREAM),
- "i" (ASI_M_MXCC) : "g2", "g3");
-}
-
-static inline unsigned long mxcc_get_creg(void)
-{
- unsigned long mxcc_control;
-
- __asm__ __volatile__("set 0xffffffff, %%g2\n\t"
- "set 0xffffffff, %%g3\n\t"
- "stda %%g2, [%1] %2\n\t"
- "lda [%3] %2, %0\n\t" :
- "=r" (mxcc_control) :
- "r" (MXCC_EREG), "i" (ASI_M_MXCC),
- "r" (MXCC_CREG) : "g2", "g3");
- return mxcc_control;
-}
-
-static inline void mxcc_set_creg(unsigned long mxcc_control)
-{
- __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
- "r" (mxcc_control), "r" (MXCC_CREG),
- "i" (ASI_M_MXCC));
-}
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* !(_SPARC_MXCC_H) */
diff --git a/arch/sparc/include/asm/ross.h b/arch/sparc/include/asm/ross.h
deleted file mode 100644
index 79a54d66a2c0..000000000000
--- a/arch/sparc/include/asm/ross.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * ross.h: Ross module specific definitions and defines.
- *
- * Copyright (C) 1995 David S. Miller ([email protected])
- */
-
-#ifndef _SPARC_ROSS_H
-#define _SPARC_ROSS_H
-
-#include <asm/asi.h>
-#include <asm/page.h>
-
-/* Ross made Hypersparcs have a %psr 'impl' field of '0001'. The 'vers'
- * field has '1111'.
- */
-
-/* The MMU control register fields on the HyperSparc.
- *
- * -----------------------------------------------------------------
- * |implvers| RSV |CWR|SE|WBE| MID |BM| C|CS|MR|CM|RSV|CE|RSV|NF|ME|
- * -----------------------------------------------------------------
- * 31 24 23-22 21 20 19 18-15 14 13 12 11 10 9 8 7-2 1 0
- *
- * Phew, lots of fields there ;-)
- *
- * CWR: Cache Wrapping Enabled, if one cache wrapping is on.
- * SE: Snoop Enable, turns on bus snooping for cache activity if one.
- * WBE: Write Buffer Enable, one turns it on.
- * MID: The ModuleID of the chip for MBus transactions.
- * BM: Boot-Mode. One indicates the MMU is in boot mode.
- * C: Indicates whether accesses are cachable while the MMU is
- * disabled.
- * CS: Cache Size -- 0 = 128k, 1 = 256k
- * MR: Memory Reflection, one indicates that the memory bus connected
- * to the MBus supports memory reflection.
- * CM: Cache Mode -- 0 = write-through, 1 = copy-back
- * CE: Cache Enable -- 0 = no caching, 1 = cache is on
- * NF: No Fault -- 0 = faults trap the CPU from supervisor mode
- * 1 = faults from supervisor mode do not generate traps
- * ME: MMU Enable -- 0 = MMU is off, 1 = MMU is on
- */
-
-#define HYPERSPARC_CWENABLE 0x00200000
-#define HYPERSPARC_SBENABLE 0x00100000
-#define HYPERSPARC_WBENABLE 0x00080000
-#define HYPERSPARC_MIDMASK 0x00078000
-#define HYPERSPARC_BMODE 0x00004000
-#define HYPERSPARC_ACENABLE 0x00002000
-#define HYPERSPARC_CSIZE 0x00001000
-#define HYPERSPARC_MRFLCT 0x00000800
-#define HYPERSPARC_CMODE 0x00000400
-#define HYPERSPARC_CENABLE 0x00000100
-#define HYPERSPARC_NFAULT 0x00000002
-#define HYPERSPARC_MENABLE 0x00000001
-
-
-/* The ICCR instruction cache register on the HyperSparc.
- *
- * -----------------------------------------------
- * | | FTD | ICE |
- * -----------------------------------------------
- * 31 1 0
- *
- * This register is accessed using the V8 'wrasr' and 'rdasr'
- * opcodes, since not all assemblers understand them and those
- * that do use different semantics I will just hard code the
- * instruction with a '.word' statement.
- *
- * FTD: If set to one flush instructions executed during an
- * instruction cache hit occurs, the corresponding line
- * for said cache-hit is invalidated. If FTD is zero,
- * an unimplemented 'flush' trap will occur when any
- * flush is executed by the processor.
- *
- * ICE: If set to one, the instruction cache is enabled. If
- * zero, the cache will not be used for instruction fetches.
- *
- * All other bits are read as zeros, and writes to them have no
- * effect.
- *
- * Wheee, not many assemblers understand the %iccr register nor
- * the generic asr r/w instructions.
- *
- * 1000 0011 0100 0111 1100 0000 0000 0000 ! rd %iccr, %g1
- *
- * 0x 8 3 4 7 c 0 0 0 ! 0x8347c000
- *
- * 1011 1111 1000 0000 0110 0000 0000 0000 ! wr %g1, 0x0, %iccr
- *
- * 0x b f 8 0 6 0 0 0 ! 0xbf806000
- *
- */
-
-#define HYPERSPARC_ICCR_FTD 0x00000002
-#define HYPERSPARC_ICCR_ICE 0x00000001
-
-#ifndef __ASSEMBLY__
-
-static inline unsigned int get_ross_icr(void)
-{
- unsigned int icreg;
-
- __asm__ __volatile__(".word 0x8347c000\n\t" /* rd %iccr, %g1 */
- "mov %%g1, %0\n\t"
- : "=r" (icreg)
- : /* no inputs */
- : "g1", "memory");
-
- return icreg;
-}
-
-static inline void put_ross_icr(unsigned int icreg)
-{
- __asm__ __volatile__("or %%g0, %0, %%g1\n\t"
- ".word 0xbf806000\n\t" /* wr %g1, 0x0, %iccr */
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- : /* no outputs */
- : "r" (icreg)
- : "g1", "memory");
-
- return;
-}
-
-/* HyperSparc specific cache flushing. */
-
-/* This is for the on-chip instruction cache. */
-static inline void hyper_flush_whole_icache(void)
-{
- __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
- : /* no outputs */
- : "i" (ASI_M_FLUSH_IWHOLE)
- : "memory");
- return;
-}
-
-extern int vac_cache_size;
-extern int vac_line_size;
-
-static inline void hyper_clear_all_tags(void)
-{
- unsigned long addr;
-
- for(addr = 0; addr < vac_cache_size; addr += vac_line_size)
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (addr), "i" (ASI_M_DATAC_TAG)
- : "memory");
-}
-
-static inline void hyper_flush_unconditional_combined(void)
-{
- unsigned long addr;
-
- for (addr = 0; addr < vac_cache_size; addr += vac_line_size)
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (addr), "i" (ASI_M_FLUSH_CTX)
- : "memory");
-}
-
-static inline void hyper_flush_cache_user(void)
-{
- unsigned long addr;
-
- for (addr = 0; addr < vac_cache_size; addr += vac_line_size)
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (addr), "i" (ASI_M_FLUSH_USER)
- : "memory");
-}
-
-static inline void hyper_flush_cache_page(unsigned long page)
-{
- unsigned long end;
-
- page &= PAGE_MASK;
- end = page + PAGE_SIZE;
- while (page < end) {
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (page), "i" (ASI_M_FLUSH_PAGE)
- : "memory");
- page += vac_line_size;
- }
-}
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(_SPARC_ROSS_H) */
diff --git a/arch/sparc/include/asm/swift.h b/arch/sparc/include/asm/swift.h
deleted file mode 100644
index 96f6526b964e..000000000000
--- a/arch/sparc/include/asm/swift.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* swift.h: Specific definitions for the _broken_ Swift SRMMU
- * MMU module.
- *
- * Copyright (C) 1996 David S. Miller ([email protected])
- */
-
-#ifndef _SPARC_SWIFT_H
-#define _SPARC_SWIFT_H
-
-/* Swift is so brain damaged, here is the mmu control register. */
-#define SWIFT_ST 0x00800000 /* SW tablewalk enable */
-#define SWIFT_WP 0x00400000 /* Watchpoint enable */
-
-/* Branch folding (buggy, disable on production systems!) */
-#define SWIFT_BF 0x00200000
-#define SWIFT_PMC 0x00180000 /* Page mode control */
-#define SWIFT_PE 0x00040000 /* Parity enable */
-#define SWIFT_PC 0x00020000 /* Parity control */
-#define SWIFT_AP 0x00010000 /* Graphics page mode control (TCX/SX) */
-#define SWIFT_AC 0x00008000 /* Alternate Cacheability (see viking.h) */
-#define SWIFT_BM 0x00004000 /* Boot mode */
-#define SWIFT_RC 0x00003c00 /* DRAM refresh control */
-#define SWIFT_IE 0x00000200 /* Instruction cache enable */
-#define SWIFT_DE 0x00000100 /* Data cache enable */
-#define SWIFT_SA 0x00000080 /* Store Allocate */
-#define SWIFT_NF 0x00000002 /* No fault mode */
-#define SWIFT_EN 0x00000001 /* MMU enable */
-
-/* Bits [13:5] select one of 512 instruction cache tags */
-static inline void swift_inv_insn_tag(unsigned long addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (addr), "i" (ASI_M_TXTC_TAG)
- : "memory");
-}
-
-/* Bits [12:4] select one of 512 data cache tags */
-static inline void swift_inv_data_tag(unsigned long addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (addr), "i" (ASI_M_DATAC_TAG)
- : "memory");
-}
-
-static inline void swift_flush_dcache(void)
-{
- unsigned long addr;
-
- for (addr = 0; addr < 0x2000; addr += 0x10)
- swift_inv_data_tag(addr);
-}
-
-static inline void swift_flush_icache(void)
-{
- unsigned long addr;
-
- for (addr = 0; addr < 0x4000; addr += 0x20)
- swift_inv_insn_tag(addr);
-}
-
-static inline void swift_idflash_clear(void)
-{
- unsigned long addr;
-
- for (addr = 0; addr < 0x2000; addr += 0x10) {
- swift_inv_insn_tag(addr<<1);
- swift_inv_data_tag(addr);
- }
-}
-
-/* Swift is so broken, it isn't even safe to use the following. */
-static inline void swift_flush_page(unsigned long page)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (page), "i" (ASI_M_FLUSH_PAGE)
- : "memory");
-}
-
-static inline void swift_flush_segment(unsigned long addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (addr), "i" (ASI_M_FLUSH_SEG)
- : "memory");
-}
-
-static inline void swift_flush_region(unsigned long addr)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (addr), "i" (ASI_M_FLUSH_REGION)
- : "memory");
-}
-
-static inline void swift_flush_context(void)
-{
- __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
- : /* no outputs */
- : "i" (ASI_M_FLUSH_CTX)
- : "memory");
-}
-
-#endif /* !(_SPARC_SWIFT_H) */
diff --git a/arch/sparc/include/asm/tsunami.h b/arch/sparc/include/asm/tsunami.h
deleted file mode 100644
index acaf014eff46..000000000000
--- a/arch/sparc/include/asm/tsunami.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * tsunami.h: Module specific definitions for Tsunami V8 Sparcs
- *
- * Copyright (C) 1995 David S. Miller ([email protected])
- */
-
-#ifndef _SPARC_TSUNAMI_H
-#define _SPARC_TSUNAMI_H
-
-#include <asm/asi.h>
-
-/* The MMU control register on the Tsunami:
- *
- * -----------------------------------------------------------------------
- * | implvers |SW|AV|DV|MV| RSV |PC|ITD|ALC| RSV |PE| RC |IE|DE|RSV|NF|ME|
- * -----------------------------------------------------------------------
- * 31 24 23 22 21 20 19-18 17 16 14 13-12 11 10-9 8 7 6-2 1 0
- *
- * SW: Enable Software Table Walks 0=off 1=on
- * AV: Address View bit
- * DV: Data View bit
- * MV: Memory View bit
- * PC: Parity Control
- * ITD: ITBR disable
- * ALC: Alternate Cacheable
- * PE: Parity Enable 0=off 1=on
- * RC: Refresh Control
- * IE: Instruction cache Enable 0=off 1=on
- * DE: Data cache Enable 0=off 1=on
- * NF: No Fault, same as all other SRMMUs
- * ME: MMU Enable, same as all other SRMMUs
- */
-
-#define TSUNAMI_SW 0x00800000
-#define TSUNAMI_AV 0x00400000
-#define TSUNAMI_DV 0x00200000
-#define TSUNAMI_MV 0x00100000
-#define TSUNAMI_PC 0x00020000
-#define TSUNAMI_ITD 0x00010000
-#define TSUNAMI_ALC 0x00008000
-#define TSUNAMI_PE 0x00001000
-#define TSUNAMI_RCMASK 0x00000C00
-#define TSUNAMI_IENAB 0x00000200
-#define TSUNAMI_DENAB 0x00000100
-#define TSUNAMI_NF 0x00000002
-#define TSUNAMI_ME 0x00000001
-
-static inline void tsunami_flush_icache(void)
-{
- __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
- : /* no outputs */
- : "i" (ASI_M_IC_FLCLEAR)
- : "memory");
-}
-
-static inline void tsunami_flush_dcache(void)
-{
- __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
- : /* no outputs */
- : "i" (ASI_M_DC_FLCLEAR)
- : "memory");
-}
-
-#endif /* !(_SPARC_TSUNAMI_H) */
diff --git a/arch/sparc/include/asm/viking.h b/arch/sparc/include/asm/viking.h
deleted file mode 100644
index 08ffc605035f..000000000000
--- a/arch/sparc/include/asm/viking.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * viking.h: Defines specific to the GNU/Viking MBUS module.
- * This is SRMMU stuff.
- *
- * Copyright (C) 1995 David S. Miller ([email protected])
- */
-#ifndef _SPARC_VIKING_H
-#define _SPARC_VIKING_H
-
-#include <asm/asi.h>
-#include <asm/mxcc.h>
-#include <asm/pgtable.h>
-#include <asm/pgtsrmmu.h>
-
-/* Bits in the SRMMU control register for GNU/Viking modules.
- *
- * -----------------------------------------------------------
- * |impl-vers| RSV |TC|AC|SP|BM|PC|MBM|SB|IC|DC|PSO|RSV|NF|ME|
- * -----------------------------------------------------------
- * 31 24 23-17 16 15 14 13 12 11 10 9 8 7 6-2 1 0
- *
- * TC: Tablewalk Cacheable -- 0 = Twalks are not cacheable in E-cache
- * 1 = Twalks are cacheable in E-cache
- *
- * GNU/Viking will only cache tablewalks in the E-cache (mxcc) if present
- * and never caches them internally (or so states the docs). Therefore
- * for machines lacking an E-cache (ie. in MBUS mode) this bit must
- * remain cleared.
- *
- * AC: Alternate Cacheable -- 0 = Passthru physical accesses not cacheable
- * 1 = Passthru physical accesses cacheable
- *
- * This indicates whether accesses are cacheable when no cachable bit
- * is present in the pte when the processor is in boot-mode or the
- * access does not need pte's for translation (ie. pass-thru ASI's).
- * "Cachable" is only referring to E-cache (if present) and not the
- * on chip split I/D caches of the GNU/Viking.
- *
- * SP: SnooP Enable -- 0 = bus snooping off, 1 = bus snooping on
- *
- * This enables snooping on the GNU/Viking bus. This must be on
- * for the hardware cache consistency mechanisms of the GNU/Viking
- * to work at all. On non-mxcc GNU/Viking modules the split I/D
- * caches will snoop regardless of whether they are enabled, this
- * takes care of the case where the I or D or both caches are turned
- * off yet still contain valid data. Note also that this bit does
- * not affect GNU/Viking store-buffer snoops, those happen if the
- * store-buffer is enabled no matter what.
- *
- * BM: Boot Mode -- 0 = not in boot mode, 1 = in boot mode
- *
- * This indicates whether the GNU/Viking is in boot-mode or not,
- * if it is then all instruction fetch physical addresses are
- * computed as 0xff0000000 + low 28 bits of requested address.
- * GNU/Viking boot-mode does not affect data accesses. Also,
- * in boot mode instruction accesses bypass the split on chip I/D
- * caches, they may be cached by the GNU/MXCC if present and enabled.
- *
- * MBM: MBus Mode -- 0 = not in MBus mode, 1 = in MBus mode
- *
- * This indicated the GNU/Viking configuration present. If in
- * MBUS mode, the GNU/Viking lacks a GNU/MXCC E-cache. If it is
- * not then the GNU/Viking is on a module VBUS connected directly
- * to a GNU/MXCC cache controller. The GNU/MXCC can be thus connected
- * to either an GNU/MBUS (sun4m) or the packet-switched GNU/XBus (sun4d).
- *
- * SB: StoreBuffer enable -- 0 = store buffer off, 1 = store buffer on
- *
- * The GNU/Viking store buffer allows the chip to continue execution
- * after a store even if the data cannot be placed in one of the
- * caches during that cycle. If disabled, all stores operations
- * occur synchronously.
- *
- * IC: Instruction Cache -- 0 = off, 1 = on
- * DC: Data Cache -- 0 = off, 1 = 0n
- *
- * These bits enable the on-cpu GNU/Viking split I/D caches. Note,
- * as mentioned above, these caches will snoop the bus in GNU/MBUS
- * configurations even when disabled to avoid data corruption.
- *
- * NF: No Fault -- 0 = faults generate traps, 1 = faults don't trap
- * ME: MMU enable -- 0 = mmu not translating, 1 = mmu translating
- *
- */
-
-#define VIKING_MMUENABLE 0x00000001
-#define VIKING_NOFAULT 0x00000002
-#define VIKING_PSO 0x00000080
-#define VIKING_DCENABLE 0x00000100 /* Enable data cache */
-#define VIKING_ICENABLE 0x00000200 /* Enable instruction cache */
-#define VIKING_SBENABLE 0x00000400 /* Enable store buffer */
-#define VIKING_MMODE 0x00000800 /* MBUS mode */
-#define VIKING_PCENABLE 0x00001000 /* Enable parity checking */
-#define VIKING_BMODE 0x00002000
-#define VIKING_SPENABLE 0x00004000 /* Enable bus cache snooping */
-#define VIKING_ACENABLE 0x00008000 /* Enable alternate caching */
-#define VIKING_TCENABLE 0x00010000 /* Enable table-walks to be cached */
-#define VIKING_DPENABLE 0x00040000 /* Enable the data prefetcher */
-
-/*
- * GNU/Viking Breakpoint Action Register fields.
- */
-#define VIKING_ACTION_MIX 0x00001000 /* Enable multiple instructions */
-
-/*
- * GNU/Viking Cache Tags.
- */
-#define VIKING_PTAG_VALID 0x01000000 /* Cache block is valid */
-#define VIKING_PTAG_DIRTY 0x00010000 /* Block has been modified */
-#define VIKING_PTAG_SHARED 0x00000100 /* Shared with some other cache */
-
-#ifndef __ASSEMBLY__
-
-static inline void viking_flush_icache(void)
-{
- __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
- : /* no outputs */
- : "i" (ASI_M_IC_FLCLEAR)
- : "memory");
-}
-
-static inline void viking_flush_dcache(void)
-{
- __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
- : /* no outputs */
- : "i" (ASI_M_DC_FLCLEAR)
- : "memory");
-}
-
-static inline void viking_unlock_icache(void)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (0x80000000), "i" (ASI_M_IC_FLCLEAR)
- : "memory");
-}
-
-static inline void viking_unlock_dcache(void)
-{
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
- : /* no outputs */
- : "r" (0x80000000), "i" (ASI_M_DC_FLCLEAR)
- : "memory");
-}
-
-static inline void viking_set_bpreg(unsigned long regval)
-{
- __asm__ __volatile__("sta %0, [%%g0] %1\n\t"
- : /* no outputs */
- : "r" (regval), "i" (ASI_M_ACTION)
- : "memory");
-}
-
-static inline unsigned long viking_get_bpreg(void)
-{
- unsigned long regval;
-
- __asm__ __volatile__("lda [%%g0] %1, %0\n\t"
- : "=r" (regval)
- : "i" (ASI_M_ACTION));
- return regval;
-}
-
-static inline void viking_get_dcache_ptag(int set, int block,
- unsigned long *data)
-{
- unsigned long ptag = ((set & 0x7f) << 5) | ((block & 0x3) << 26) |
- 0x80000000;
- unsigned long info, page;
-
- __asm__ __volatile__ ("ldda [%2] %3, %%g2\n\t"
- "or %%g0, %%g2, %0\n\t"
- "or %%g0, %%g3, %1\n\t"
- : "=r" (info), "=r" (page)
- : "r" (ptag), "i" (ASI_M_DATAC_TAG)
- : "g2", "g3");
- data[0] = info;
- data[1] = page;
-}
-
-static inline void viking_mxcc_turn_off_parity(unsigned long *mregp,
- unsigned long *mxcc_cregp)
-{
- unsigned long mreg = *mregp;
- unsigned long mxcc_creg = *mxcc_cregp;
-
- mreg &= ~(VIKING_PCENABLE);
- mxcc_creg &= ~(MXCC_CTL_PARE);
-
- __asm__ __volatile__ ("set 1f, %%g2\n\t"
- "andcc %%g2, 4, %%g0\n\t"
- "bne 2f\n\t"
- " nop\n"
- "1:\n\t"
- "sta %0, [%%g0] %3\n\t"
- "sta %1, [%2] %4\n\t"
- "b 1f\n\t"
- " nop\n\t"
- "nop\n"
- "2:\n\t"
- "sta %0, [%%g0] %3\n\t"
- "sta %1, [%2] %4\n"
- "1:\n\t"
- : /* no output */
- : "r" (mreg), "r" (mxcc_creg),
- "r" (MXCC_CREG), "i" (ASI_M_MMUREGS),
- "i" (ASI_M_MXCC)
- : "g2", "memory", "cc");
- *mregp = mreg;
- *mxcc_cregp = mxcc_creg;
-}
-
-static inline unsigned long viking_hwprobe(unsigned long vaddr)
-{
- unsigned long val;
-
- vaddr &= PAGE_MASK;
- /* Probe all MMU entries. */
- __asm__ __volatile__("lda [%1] %2, %0\n\t"
- : "=r" (val)
- : "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
- if (!val)
- return 0;
-
- /* Probe region. */
- __asm__ __volatile__("lda [%1] %2, %0\n\t"
- : "=r" (val)
- : "r" (vaddr | 0x200), "i" (ASI_M_FLUSH_PROBE));
- if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
- vaddr &= ~PGDIR_MASK;
- vaddr >>= PAGE_SHIFT;
- return val | (vaddr << 8);
- }
-
- /* Probe segment. */
- __asm__ __volatile__("lda [%1] %2, %0\n\t"
- : "=r" (val)
- : "r" (vaddr | 0x100), "i" (ASI_M_FLUSH_PROBE));
- if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
- vaddr &= ~PMD_MASK;
- vaddr >>= PAGE_SHIFT;
- return val | (vaddr << 8);
- }
-
- /* Probe page. */
- __asm__ __volatile__("lda [%1] %2, %0\n\t"
- : "=r" (val)
- : "r" (vaddr), "i" (ASI_M_FLUSH_PROBE));
- return val;
-}
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* !(_SPARC_VIKING_H) */
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 451eaae85760..a24dcfa44e19 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -24,7 +24,6 @@
#include <asm/winmacro.h>
#include <asm/signal.h>
#include <asm/obio.h>
-#include <asm/mxcc.h>
#include <asm/thread_info.h>
#include <asm/param.h>
#include <asm/unistd.h>
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
index 68db1f859b02..087d35e81e7b 100644
--- a/arch/sparc/mm/Makefile
+++ b/arch/sparc/mm/Makefile
@@ -10,7 +10,6 @@ obj-y += fault_$(BITS).o
obj-y += init_$(BITS).o
obj-$(CONFIG_SPARC32) += extable.o srmmu.o iommu.o io-unit.o
obj-$(CONFIG_SPARC32) += srmmu_access.o
-obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o
obj-$(CONFIG_SPARC32) += leon_mm.o

# Only used by sparc64
diff --git a/arch/sparc/mm/hypersparc.S b/arch/sparc/mm/hypersparc.S
deleted file mode 100644
index 6c2521e85a42..000000000000
--- a/arch/sparc/mm/hypersparc.S
+++ /dev/null
@@ -1,414 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * hypersparc.S: High speed Hypersparc mmu/cache operations.
- *
- * Copyright (C) 1997 David S. Miller ([email protected])
- */
-
-#include <asm/ptrace.h>
-#include <asm/psr.h>
-#include <asm/asm-offsets.h>
-#include <asm/asi.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/pgtsrmmu.h>
-#include <linux/init.h>
-
- .text
- .align 4
-
- .globl hypersparc_flush_cache_all, hypersparc_flush_cache_mm
- .globl hypersparc_flush_cache_range, hypersparc_flush_cache_page
- .globl hypersparc_flush_page_to_ram
- .globl hypersparc_flush_page_for_dma, hypersparc_flush_sig_insns
- .globl hypersparc_flush_tlb_all, hypersparc_flush_tlb_mm
- .globl hypersparc_flush_tlb_range, hypersparc_flush_tlb_page
-
-hypersparc_flush_cache_all:
- WINDOW_FLUSH(%g4, %g5)
- sethi %hi(vac_cache_size), %g4
- ld [%g4 + %lo(vac_cache_size)], %g5
- sethi %hi(vac_line_size), %g1
- ld [%g1 + %lo(vac_line_size)], %g2
-1:
- subcc %g5, %g2, %g5 ! hyper_flush_unconditional_combined
- bne 1b
- sta %g0, [%g5] ASI_M_FLUSH_CTX
- retl
- sta %g0, [%g0] ASI_M_FLUSH_IWHOLE ! hyper_flush_whole_icache
-
- /* We expand the window flush to get maximum performance. */
-hypersparc_flush_cache_mm:
-#ifndef CONFIG_SMP
- ld [%o0 + AOFF_mm_context], %g1
- cmp %g1, -1
- be hypersparc_flush_cache_mm_out
-#endif
- WINDOW_FLUSH(%g4, %g5)
-
- sethi %hi(vac_line_size), %g1
- ld [%g1 + %lo(vac_line_size)], %o1
- sethi %hi(vac_cache_size), %g2
- ld [%g2 + %lo(vac_cache_size)], %o0
- add %o1, %o1, %g1
- add %o1, %g1, %g2
- add %o1, %g2, %g3
- add %o1, %g3, %g4
- add %o1, %g4, %g5
- add %o1, %g5, %o4
- add %o1, %o4, %o5
-
- /* BLAMMO! */
-1:
- subcc %o0, %o5, %o0 ! hyper_flush_cache_user
- sta %g0, [%o0 + %g0] ASI_M_FLUSH_USER
- sta %g0, [%o0 + %o1] ASI_M_FLUSH_USER
- sta %g0, [%o0 + %g1] ASI_M_FLUSH_USER
- sta %g0, [%o0 + %g2] ASI_M_FLUSH_USER
- sta %g0, [%o0 + %g3] ASI_M_FLUSH_USER
- sta %g0, [%o0 + %g4] ASI_M_FLUSH_USER
- sta %g0, [%o0 + %g5] ASI_M_FLUSH_USER
- bne 1b
- sta %g0, [%o0 + %o4] ASI_M_FLUSH_USER
-hypersparc_flush_cache_mm_out:
- retl
- nop
-
- /* The things we do for performance... */
-hypersparc_flush_cache_range:
- ld [%o0 + VMA_VM_MM], %o0
-#ifndef CONFIG_SMP
- ld [%o0 + AOFF_mm_context], %g1
- cmp %g1, -1
- be hypersparc_flush_cache_range_out
-#endif
- WINDOW_FLUSH(%g4, %g5)
-
- sethi %hi(vac_line_size), %g1
- ld [%g1 + %lo(vac_line_size)], %o4
- sethi %hi(vac_cache_size), %g2
- ld [%g2 + %lo(vac_cache_size)], %o3
-
- /* Here comes the fun part... */
- add %o2, (PAGE_SIZE - 1), %o2
- andn %o1, (PAGE_SIZE - 1), %o1
- add %o4, %o4, %o5
- andn %o2, (PAGE_SIZE - 1), %o2
- add %o4, %o5, %g1
- sub %o2, %o1, %g4
- add %o4, %g1, %g2
- sll %o3, 2, %g5
- add %o4, %g2, %g3
- cmp %g4, %g5
- add %o4, %g3, %g4
- blu 0f
- add %o4, %g4, %g5
- add %o4, %g5, %g7
-
- /* Flush entire user space, believe it or not this is quicker
- * than page at a time flushings for range > (cache_size<<2).
- */
-1:
- subcc %o3, %g7, %o3
- sta %g0, [%o3 + %g0] ASI_M_FLUSH_USER
- sta %g0, [%o3 + %o4] ASI_M_FLUSH_USER
- sta %g0, [%o3 + %o5] ASI_M_FLUSH_USER
- sta %g0, [%o3 + %g1] ASI_M_FLUSH_USER
- sta %g0, [%o3 + %g2] ASI_M_FLUSH_USER
- sta %g0, [%o3 + %g3] ASI_M_FLUSH_USER
- sta %g0, [%o3 + %g4] ASI_M_FLUSH_USER
- bne 1b
- sta %g0, [%o3 + %g5] ASI_M_FLUSH_USER
- retl
- nop
-
- /* Below our threshold, flush one page at a time. */
-0:
- ld [%o0 + AOFF_mm_context], %o0
- mov SRMMU_CTX_REG, %g7
- lda [%g7] ASI_M_MMUREGS, %o3
- sta %o0, [%g7] ASI_M_MMUREGS
- add %o2, -PAGE_SIZE, %o0
-1:
- or %o0, 0x400, %g7
- lda [%g7] ASI_M_FLUSH_PROBE, %g7
- orcc %g7, 0, %g0
- be,a 3f
- mov %o0, %o2
- add %o4, %g5, %g7
-2:
- sub %o2, %g7, %o2
- sta %g0, [%o2 + %g0] ASI_M_FLUSH_PAGE
- sta %g0, [%o2 + %o4] ASI_M_FLUSH_PAGE
- sta %g0, [%o2 + %o5] ASI_M_FLUSH_PAGE
- sta %g0, [%o2 + %g1] ASI_M_FLUSH_PAGE
- sta %g0, [%o2 + %g2] ASI_M_FLUSH_PAGE
- sta %g0, [%o2 + %g3] ASI_M_FLUSH_PAGE
- andcc %o2, 0xffc, %g0
- sta %g0, [%o2 + %g4] ASI_M_FLUSH_PAGE
- bne 2b
- sta %g0, [%o2 + %g5] ASI_M_FLUSH_PAGE
-3:
- cmp %o2, %o1
- bne 1b
- add %o2, -PAGE_SIZE, %o0
- mov SRMMU_FAULT_STATUS, %g5
- lda [%g5] ASI_M_MMUREGS, %g0
- mov SRMMU_CTX_REG, %g7
- sta %o3, [%g7] ASI_M_MMUREGS
-hypersparc_flush_cache_range_out:
- retl
- nop
-
- /* HyperSparc requires a valid mapping where we are about to flush
- * in order to check for a physical tag match during the flush.
- */
- /* Verified, my ass... */
-hypersparc_flush_cache_page:
- ld [%o0 + VMA_VM_MM], %o0
- ld [%o0 + AOFF_mm_context], %g2
-#ifndef CONFIG_SMP
- cmp %g2, -1
- be hypersparc_flush_cache_page_out
-#endif
- WINDOW_FLUSH(%g4, %g5)
-
- sethi %hi(vac_line_size), %g1
- ld [%g1 + %lo(vac_line_size)], %o4
- mov SRMMU_CTX_REG, %o3
- andn %o1, (PAGE_SIZE - 1), %o1
- lda [%o3] ASI_M_MMUREGS, %o2
- sta %g2, [%o3] ASI_M_MMUREGS
- or %o1, 0x400, %o5
- lda [%o5] ASI_M_FLUSH_PROBE, %g1
- orcc %g0, %g1, %g0
- be 2f
- add %o4, %o4, %o5
- sub %o1, -PAGE_SIZE, %o1
- add %o4, %o5, %g1
- add %o4, %g1, %g2
- add %o4, %g2, %g3
- add %o4, %g3, %g4
- add %o4, %g4, %g5
- add %o4, %g5, %g7
-
- /* BLAMMO! */
-1:
- sub %o1, %g7, %o1
- sta %g0, [%o1 + %g0] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o4] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o5] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %g1] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %g2] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %g3] ASI_M_FLUSH_PAGE
- andcc %o1, 0xffc, %g0
- sta %g0, [%o1 + %g4] ASI_M_FLUSH_PAGE
- bne 1b
- sta %g0, [%o1 + %g5] ASI_M_FLUSH_PAGE
-2:
- mov SRMMU_FAULT_STATUS, %g7
- mov SRMMU_CTX_REG, %g4
- lda [%g7] ASI_M_MMUREGS, %g0
- sta %o2, [%g4] ASI_M_MMUREGS
-hypersparc_flush_cache_page_out:
- retl
- nop
-
-hypersparc_flush_sig_insns:
- flush %o1
- retl
- flush %o1 + 4
-
- /* HyperSparc is copy-back. */
-hypersparc_flush_page_to_ram:
- sethi %hi(vac_line_size), %g1
- ld [%g1 + %lo(vac_line_size)], %o4
- andn %o0, (PAGE_SIZE - 1), %o0
- add %o4, %o4, %o5
- or %o0, 0x400, %g7
- lda [%g7] ASI_M_FLUSH_PROBE, %g5
- add %o4, %o5, %g1
- orcc %g5, 0, %g0
- be 2f
- add %o4, %g1, %g2
- add %o4, %g2, %g3
- sub %o0, -PAGE_SIZE, %o0
- add %o4, %g3, %g4
- add %o4, %g4, %g5
- add %o4, %g5, %g7
-
- /* BLAMMO! */
-1:
- sub %o0, %g7, %o0
- sta %g0, [%o0 + %g0] ASI_M_FLUSH_PAGE
- sta %g0, [%o0 + %o4] ASI_M_FLUSH_PAGE
- sta %g0, [%o0 + %o5] ASI_M_FLUSH_PAGE
- sta %g0, [%o0 + %g1] ASI_M_FLUSH_PAGE
- sta %g0, [%o0 + %g2] ASI_M_FLUSH_PAGE
- sta %g0, [%o0 + %g3] ASI_M_FLUSH_PAGE
- andcc %o0, 0xffc, %g0
- sta %g0, [%o0 + %g4] ASI_M_FLUSH_PAGE
- bne 1b
- sta %g0, [%o0 + %g5] ASI_M_FLUSH_PAGE
-2:
- mov SRMMU_FAULT_STATUS, %g1
- retl
- lda [%g1] ASI_M_MMUREGS, %g0
-
- /* HyperSparc is IO cache coherent. */
-hypersparc_flush_page_for_dma:
- retl
- nop
-
- /* It was noted that at boot time a TLB flush all in a delay slot
- * can deliver an illegal instruction to the processor if the timing
- * is just right...
- */
-hypersparc_flush_tlb_all:
- mov 0x400, %g1
- sta %g0, [%g1] ASI_M_FLUSH_PROBE
- retl
- nop
-
-hypersparc_flush_tlb_mm:
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + AOFF_mm_context], %o1
- lda [%g1] ASI_M_MMUREGS, %g5
-#ifndef CONFIG_SMP
- cmp %o1, -1
- be hypersparc_flush_tlb_mm_out
-#endif
- mov 0x300, %g2
- sta %o1, [%g1] ASI_M_MMUREGS
- sta %g0, [%g2] ASI_M_FLUSH_PROBE
-hypersparc_flush_tlb_mm_out:
- retl
- sta %g5, [%g1] ASI_M_MMUREGS
-
-hypersparc_flush_tlb_range:
- ld [%o0 + VMA_VM_MM], %o0
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + AOFF_mm_context], %o3
- lda [%g1] ASI_M_MMUREGS, %g5
-#ifndef CONFIG_SMP
- cmp %o3, -1
- be hypersparc_flush_tlb_range_out
-#endif
- sethi %hi(~((1 << PGDIR_SHIFT) - 1)), %o4
- sta %o3, [%g1] ASI_M_MMUREGS
- and %o1, %o4, %o1
- add %o1, 0x200, %o1
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
-1:
- sub %o1, %o4, %o1
- cmp %o1, %o2
- blu,a 1b
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
-hypersparc_flush_tlb_range_out:
- retl
- sta %g5, [%g1] ASI_M_MMUREGS
-
-hypersparc_flush_tlb_page:
- ld [%o0 + VMA_VM_MM], %o0
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + AOFF_mm_context], %o3
- andn %o1, (PAGE_SIZE - 1), %o1
-#ifndef CONFIG_SMP
- cmp %o3, -1
- be hypersparc_flush_tlb_page_out
-#endif
- lda [%g1] ASI_M_MMUREGS, %g5
- sta %o3, [%g1] ASI_M_MMUREGS
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
-hypersparc_flush_tlb_page_out:
- retl
- sta %g5, [%g1] ASI_M_MMUREGS
-
- __INIT
-
- /* High speed page clear/copy. */
-hypersparc_bzero_1page:
-/* NOTE: This routine has to be shorter than 40insns --jj */
- clr %g1
- mov 32, %g2
- mov 64, %g3
- mov 96, %g4
- mov 128, %g5
- mov 160, %g7
- mov 192, %o2
- mov 224, %o3
- mov 16, %o1
-1:
- stda %g0, [%o0 + %g0] ASI_M_BFILL
- stda %g0, [%o0 + %g2] ASI_M_BFILL
- stda %g0, [%o0 + %g3] ASI_M_BFILL
- stda %g0, [%o0 + %g4] ASI_M_BFILL
- stda %g0, [%o0 + %g5] ASI_M_BFILL
- stda %g0, [%o0 + %g7] ASI_M_BFILL
- stda %g0, [%o0 + %o2] ASI_M_BFILL
- stda %g0, [%o0 + %o3] ASI_M_BFILL
- subcc %o1, 1, %o1
- bne 1b
- add %o0, 256, %o0
-
- retl
- nop
-
-hypersparc_copy_1page:
-/* NOTE: This routine has to be shorter than 70insns --jj */
- sub %o1, %o0, %o2 ! difference
- mov 16, %g1
-1:
- sta %o0, [%o0 + %o2] ASI_M_BCOPY
- add %o0, 32, %o0
- sta %o0, [%o0 + %o2] ASI_M_BCOPY
- add %o0, 32, %o0
- sta %o0, [%o0 + %o2] ASI_M_BCOPY
- add %o0, 32, %o0
- sta %o0, [%o0 + %o2] ASI_M_BCOPY
- add %o0, 32, %o0
- sta %o0, [%o0 + %o2] ASI_M_BCOPY
- add %o0, 32, %o0
- sta %o0, [%o0 + %o2] ASI_M_BCOPY
- add %o0, 32, %o0
- sta %o0, [%o0 + %o2] ASI_M_BCOPY
- add %o0, 32, %o0
- sta %o0, [%o0 + %o2] ASI_M_BCOPY
- subcc %g1, 1, %g1
- bne 1b
- add %o0, 32, %o0
-
- retl
- nop
-
- .globl hypersparc_setup_blockops
-hypersparc_setup_blockops:
- sethi %hi(bzero_1page), %o0
- or %o0, %lo(bzero_1page), %o0
- sethi %hi(hypersparc_bzero_1page), %o1
- or %o1, %lo(hypersparc_bzero_1page), %o1
- sethi %hi(hypersparc_copy_1page), %o2
- or %o2, %lo(hypersparc_copy_1page), %o2
- ld [%o1], %o4
-1:
- add %o1, 4, %o1
- st %o4, [%o0]
- add %o0, 4, %o0
- cmp %o1, %o2
- bne 1b
- ld [%o1], %o4
- sethi %hi(__copy_1page), %o0
- or %o0, %lo(__copy_1page), %o0
- sethi %hi(hypersparc_setup_blockops), %o2
- or %o2, %lo(hypersparc_setup_blockops), %o2
- ld [%o1], %o4
-1:
- add %o1, 4, %o1
- st %o4, [%o0]
- add %o0, 4, %o0
- cmp %o1, %o2
- bne 1b
- ld [%o1], %o4
- sta %g0, [%g0] ASI_M_FLUSH_IWHOLE
- retl
- nop
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 49ded623995f..779bc9384989 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -17,7 +17,6 @@

#include <asm/io.h>
#include <asm/io-unit.h>
-#include <asm/mxcc.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/dma.h>
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 125a3e96e3d2..1df742119ac5 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -17,7 +17,6 @@
#include <linux/of_device.h>

#include <asm/io.h>
-#include <asm/mxcc.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/bitext.h>
@@ -36,11 +35,6 @@
#define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 256KB */
#define IOMMU_ORDER 6 /* 4096 * (1<<6) */

-static int viking_flush;
-/* viking.S */
-extern void viking_flush_page(unsigned long page);
-extern void viking_mxcc_flush_page(unsigned long page);
-
/*
* Values precomputed according to CPU type.
*/
@@ -155,21 +149,9 @@ static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte)
start = (unsigned long)iopte;
end = PAGE_ALIGN(start + niopte*sizeof(iopte_t));
start &= PAGE_MASK;
- if (viking_mxcc_present) {
- while(start < end) {
- viking_mxcc_flush_page(start);
- start += PAGE_SIZE;
- }
- } else if (viking_flush) {
- while(start < end) {
- viking_flush_page(start);
- start += PAGE_SIZE;
- }
- } else {
- while(start < end) {
- __flush_page_to_ram(start);
- start += PAGE_SIZE;
- }
+ while(start < end) {
+ __flush_page_to_ram(start);
+ start += PAGE_SIZE;
}
}

@@ -343,12 +325,7 @@ static void *sbus_iommu_alloc(struct device *dev, size_t len,
pmd_t *pmdp;
pte_t *ptep;

- if (viking_mxcc_present)
- viking_mxcc_flush_page(page);
- else if (viking_flush)
- viking_flush_page(page);
- else
- __flush_page_to_ram(page);
+ __flush_page_to_ram(page);

pmdp = pmd_off_k(addr);
ptep = pte_offset_map(pmdp, addr);
diff --git a/arch/sparc/mm/mm_32.h b/arch/sparc/mm/mm_32.h
index ce750a99eea9..759d6f7de798 100644
--- a/arch/sparc/mm/mm_32.h
+++ b/arch/sparc/mm/mm_32.h
@@ -11,7 +11,6 @@ void window_ret_fault(struct pt_regs *regs);

/* srmmu.c */
extern char *srmmu_name;
-extern int viking_mxcc_present;
extern int flush_page_for_dma_global;

extern void (*poke_srmmu)(void);
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 802529aa02b9..d96dcc46387c 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -40,13 +40,7 @@
#include <asm/io.h>

/* Now the cpu specific definitions. */
-#include <asm/turbosparc.h>
-#include <asm/tsunami.h>
-#include <asm/viking.h>
-#include <asm/swift.h>
#include <asm/leon.h>
-#include <asm/mxcc.h>
-#include <asm/ross.h>

#include "mm_32.h"

@@ -65,12 +59,6 @@ EXPORT_SYMBOL(sparc32_cachetlb_ops);

#ifdef CONFIG_SMP
const struct sparc32_cachetlb_ops *local_ops;
-
-#define FLUSH_BEGIN(mm)
-#define FLUSH_END
-#else
-#define FLUSH_BEGIN(mm) if ((mm)->context != NO_CONTEXT) {
-#define FLUSH_END }
#endif

int flush_page_for_dma_global = 1;
@@ -80,11 +68,8 @@ char *srmmu_name;
ctxd_t *srmmu_ctx_table_phys;
static ctxd_t *srmmu_context_table;

-int viking_mxcc_present;
static DEFINE_SPINLOCK(srmmu_context_spinlock);

-static int is_hypersparc;
-
static int srmmu_cache_pagetables;

/* these will be initialized in srmmu_nocache_calcsize() */
@@ -112,25 +97,6 @@ static inline void srmmu_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp)
set_pte((pte_t *)ctxp, pte);
}

-/*
- * Locations of MSI Registers.
- */
-#define MSI_MBUS_ARBEN 0xe0001008 /* MBus Arbiter Enable register */
-
-/*
- * Useful bits in the MSI Registers.
- */
-#define MSI_ASYNC_MODE 0x80000000 /* Operate the MSI asynchronously */
-
-static void msi_set_sync(void)
-{
- __asm__ __volatile__ ("lda [%0] %1, %%g3\n\t"
- "andn %%g3, %2, %%g3\n\t"
- "sta %%g3, [%0] %1\n\t" : :
- "r" (MSI_MBUS_ARBEN),
- "i" (ASI_M_CTL), "r" (MSI_ASYNC_MODE) : "g3");
-}
-
void pmd_set(pmd_t *pmdp, pte_t *ptep)
{
unsigned long ptp = __nocache_pa(ptep) >> 4;
@@ -477,11 +443,7 @@ void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm,
srmmu_ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
}

- if (sparc_cpu_model == sparc_leon)
- leon_switch_mm();
-
- if (is_hypersparc)
- hyper_flush_whole_icache();
+ leon_switch_mm();

srmmu_set_context(mm->context);
}
@@ -556,110 +518,6 @@ void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len)
flush_tlb_all();
}

-/* tsunami.S */
-extern void tsunami_flush_cache_all(void);
-extern void tsunami_flush_cache_mm(struct mm_struct *mm);
-extern void tsunami_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
-extern void tsunami_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
-extern void tsunami_flush_page_to_ram(unsigned long page);
-extern void tsunami_flush_page_for_dma(unsigned long page);
-extern void tsunami_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
-extern void tsunami_flush_tlb_all(void);
-extern void tsunami_flush_tlb_mm(struct mm_struct *mm);
-extern void tsunami_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
-extern void tsunami_flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
-extern void tsunami_setup_blockops(void);
-
-/* swift.S */
-extern void swift_flush_cache_all(void);
-extern void swift_flush_cache_mm(struct mm_struct *mm);
-extern void swift_flush_cache_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end);
-extern void swift_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
-extern void swift_flush_page_to_ram(unsigned long page);
-extern void swift_flush_page_for_dma(unsigned long page);
-extern void swift_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
-extern void swift_flush_tlb_all(void);
-extern void swift_flush_tlb_mm(struct mm_struct *mm);
-extern void swift_flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end);
-extern void swift_flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
-
-#if 0 /* P3: deadwood to debug precise flushes on Swift. */
-void swift_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
- int cctx, ctx1;
-
- page &= PAGE_MASK;
- if ((ctx1 = vma->vm_mm->context) != -1) {
- cctx = srmmu_get_context();
-/* Is context # ever different from current context? P3 */
- if (cctx != ctx1) {
- printk("flush ctx %02x curr %02x\n", ctx1, cctx);
- srmmu_set_context(ctx1);
- swift_flush_page(page);
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
- "r" (page), "i" (ASI_M_FLUSH_PROBE));
- srmmu_set_context(cctx);
- } else {
- /* Rm. prot. bits from virt. c. */
- /* swift_flush_cache_all(); */
- /* swift_flush_cache_page(vma, page); */
- swift_flush_page(page);
-
- __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
- "r" (page), "i" (ASI_M_FLUSH_PROBE));
- /* same as above: srmmu_flush_tlb_page() */
- }
- }
-}
-#endif
-
-/*
- * The following are all MBUS based SRMMU modules, and therefore could
- * be found in a multiprocessor configuration. On the whole, these
- * chips seems to be much more touchy about DVMA and page tables
- * with respect to cache coherency.
- */
-
-/* viking.S */
-extern void viking_flush_cache_all(void);
-extern void viking_flush_cache_mm(struct mm_struct *mm);
-extern void viking_flush_cache_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end);
-extern void viking_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
-extern void viking_flush_page_to_ram(unsigned long page);
-extern void viking_flush_page_for_dma(unsigned long page);
-extern void viking_flush_sig_insns(struct mm_struct *mm, unsigned long addr);
-extern void viking_flush_page(unsigned long page);
-extern void viking_mxcc_flush_page(unsigned long page);
-extern void viking_flush_tlb_all(void);
-extern void viking_flush_tlb_mm(struct mm_struct *mm);
-extern void viking_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end);
-extern void viking_flush_tlb_page(struct vm_area_struct *vma,
- unsigned long page);
-extern void sun4dsmp_flush_tlb_all(void);
-extern void sun4dsmp_flush_tlb_mm(struct mm_struct *mm);
-extern void sun4dsmp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end);
-extern void sun4dsmp_flush_tlb_page(struct vm_area_struct *vma,
- unsigned long page);
-
-/* hypersparc.S */
-extern void hypersparc_flush_cache_all(void);
-extern void hypersparc_flush_cache_mm(struct mm_struct *mm);
-extern void hypersparc_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
-extern void hypersparc_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
-extern void hypersparc_flush_page_to_ram(unsigned long page);
-extern void hypersparc_flush_page_for_dma(unsigned long page);
-extern void hypersparc_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
-extern void hypersparc_flush_tlb_all(void);
-extern void hypersparc_flush_tlb_mm(struct mm_struct *mm);
-extern void hypersparc_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
-extern void hypersparc_flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
-extern void hypersparc_setup_blockops(void);
-
/*
* NOTE: All of this startup code assumes the low 16mb (approx.) of
* kernel mappings are done with one single contiguous chunk of
@@ -746,18 +604,7 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start,
/* These flush types are not available on all chips... */
static inline unsigned long srmmu_probe(unsigned long vaddr)
{
- unsigned long retval;
-
- if (sparc_cpu_model != sparc_leon) {
-
- vaddr &= PAGE_MASK;
- __asm__ __volatile__("lda [%1] %2, %0\n\t" :
- "=r" (retval) :
- "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
- } else {
- retval = leon_swprobe(vaddr, NULL);
- }
- return retval;
+ return leon_swprobe(vaddr, NULL);
}

/*
@@ -903,20 +750,16 @@ void __init srmmu_paging_init(void)
init_mm.context = (unsigned long) NO_CONTEXT;
sparc_iomap.start = SUN4M_IOBASE_VADDR; /* 16MB of IOSPACE on all sun4m's. */

- if (sparc_cpu_model == sun4d)
- num_contexts = 65536; /* We know it is Viking */
- else {
- /* Find the number of contexts on the srmmu. */
- cpunode = prom_getchild(prom_root_node);
- num_contexts = 0;
- while (cpunode != 0) {
- prom_getstring(cpunode, "device_type", node_str, sizeof(node_str));
- if (!strcmp(node_str, "cpu")) {
- num_contexts = prom_getintdefault(cpunode, "mmu-nctx", 0x8);
- break;
- }
- cpunode = prom_getsibling(cpunode);
+ /* Find the number of contexts on the srmmu. */
+ cpunode = prom_getchild(prom_root_node);
+ num_contexts = 0;
+ while (cpunode != 0) {
+ prom_getstring(cpunode, "device_type", node_str, sizeof(node_str));
+ if (!strcmp(node_str, "cpu")) {
+ num_contexts = prom_getintdefault(cpunode, "mmu-nctx", 0x8);
+ break;
}
+ cpunode = prom_getsibling(cpunode);
}

if (!num_contexts) {
@@ -1013,577 +856,6 @@ void destroy_context(struct mm_struct *mm)
}
}

-/* Init various srmmu chip types. */
-static void __init srmmu_is_bad(void)
-{
- prom_printf("Could not determine SRMMU chip type.\n");
- prom_halt();
-}
-
-static void __init init_vac_layout(void)
-{
- phandle nd;
- int cache_lines;
- char node_str[128];
-#ifdef CONFIG_SMP
- int cpu = 0;
- unsigned long max_size = 0;
- unsigned long min_line_size = 0x10000000;
-#endif
-
- nd = prom_getchild(prom_root_node);
- while ((nd = prom_getsibling(nd)) != 0) {
- prom_getstring(nd, "device_type", node_str, sizeof(node_str));
- if (!strcmp(node_str, "cpu")) {
- vac_line_size = prom_getint(nd, "cache-line-size");
- if (vac_line_size == -1) {
- prom_printf("can't determine cache-line-size, halting.\n");
- prom_halt();
- }
- cache_lines = prom_getint(nd, "cache-nlines");
- if (cache_lines == -1) {
- prom_printf("can't determine cache-nlines, halting.\n");
- prom_halt();
- }
-
- vac_cache_size = cache_lines * vac_line_size;
-#ifdef CONFIG_SMP
- if (vac_cache_size > max_size)
- max_size = vac_cache_size;
- if (vac_line_size < min_line_size)
- min_line_size = vac_line_size;
- //FIXME: cpus not contiguous!!
- cpu++;
- if (cpu >= nr_cpu_ids || !cpu_online(cpu))
- break;
-#else
- break;
-#endif
- }
- }
- if (nd == 0) {
- prom_printf("No CPU nodes found, halting.\n");
- prom_halt();
- }
-#ifdef CONFIG_SMP
- vac_cache_size = max_size;
- vac_line_size = min_line_size;
-#endif
- printk("SRMMU: Using VAC size of %d bytes, line size %d bytes.\n",
- (int)vac_cache_size, (int)vac_line_size);
-}
-
-static void poke_hypersparc(void)
-{
- volatile unsigned long clear;
- unsigned long mreg = srmmu_get_mmureg();
-
- hyper_flush_unconditional_combined();
-
- mreg &= ~(HYPERSPARC_CWENABLE);
- mreg |= (HYPERSPARC_CENABLE | HYPERSPARC_WBENABLE);
- mreg |= (HYPERSPARC_CMODE);
-
- srmmu_set_mmureg(mreg);
-
-#if 0 /* XXX I think this is bad news... -DaveM */
- hyper_clear_all_tags();
-#endif
-
- put_ross_icr(HYPERSPARC_ICCR_FTD | HYPERSPARC_ICCR_ICE);
- hyper_flush_whole_icache();
- clear = srmmu_get_faddr();
- clear = srmmu_get_fstatus();
-}
-
-static const struct sparc32_cachetlb_ops hypersparc_ops = {
- .cache_all = hypersparc_flush_cache_all,
- .cache_mm = hypersparc_flush_cache_mm,
- .cache_page = hypersparc_flush_cache_page,
- .cache_range = hypersparc_flush_cache_range,
- .tlb_all = hypersparc_flush_tlb_all,
- .tlb_mm = hypersparc_flush_tlb_mm,
- .tlb_page = hypersparc_flush_tlb_page,
- .tlb_range = hypersparc_flush_tlb_range,
- .page_to_ram = hypersparc_flush_page_to_ram,
- .sig_insns = hypersparc_flush_sig_insns,
- .page_for_dma = hypersparc_flush_page_for_dma,
-};
-
-static void __init init_hypersparc(void)
-{
- srmmu_name = "ROSS HyperSparc";
-
- init_vac_layout();
-
- is_hypersparc = 1;
- sparc32_cachetlb_ops = &hypersparc_ops;
-
- poke_srmmu = poke_hypersparc;
-
- hypersparc_setup_blockops();
-}
-
-static void poke_swift(void)
-{
- unsigned long mreg;
-
- /* Clear any crap from the cache or else... */
- swift_flush_cache_all();
-
- /* Enable I & D caches */
- mreg = srmmu_get_mmureg();
- mreg |= (SWIFT_IE | SWIFT_DE);
- /*
- * The Swift branch folding logic is completely broken. At
- * trap time, if things are just right, if can mistakenly
- * think that a trap is coming from kernel mode when in fact
- * it is coming from user mode (it mis-executes the branch in
- * the trap code). So you see things like crashme completely
- * hosing your machine which is completely unacceptable. Turn
- * this shit off... nice job Fujitsu.
- */
- mreg &= ~(SWIFT_BF);
- srmmu_set_mmureg(mreg);
-}
-
-static const struct sparc32_cachetlb_ops swift_ops = {
- .cache_all = swift_flush_cache_all,
- .cache_mm = swift_flush_cache_mm,
- .cache_page = swift_flush_cache_page,
- .cache_range = swift_flush_cache_range,
- .tlb_all = swift_flush_tlb_all,
- .tlb_mm = swift_flush_tlb_mm,
- .tlb_page = swift_flush_tlb_page,
- .tlb_range = swift_flush_tlb_range,
- .page_to_ram = swift_flush_page_to_ram,
- .sig_insns = swift_flush_sig_insns,
- .page_for_dma = swift_flush_page_for_dma,
-};
-
-#define SWIFT_MASKID_ADDR 0x10003018
-static void __init init_swift(void)
-{
- unsigned long swift_rev;
-
- __asm__ __volatile__("lda [%1] %2, %0\n\t"
- "srl %0, 0x18, %0\n\t" :
- "=r" (swift_rev) :
- "r" (SWIFT_MASKID_ADDR), "i" (ASI_M_BYPASS));
- srmmu_name = "Fujitsu Swift";
-
- sparc32_cachetlb_ops = &swift_ops;
- flush_page_for_dma_global = 0;
-
- /*
- * Are you now convinced that the Swift is one of the
- * biggest VLSI abortions of all time? Bravo Fujitsu!
- * Fujitsu, the !#?!%$'d up processor people. I bet if
- * you examined the microcode of the Swift you'd find
- * XXX's all over the place.
- */
- poke_srmmu = poke_swift;
-}
-
-static void turbosparc_flush_cache_all(void)
-{
- flush_user_windows();
- turbosparc_idflash_clear();
-}
-
-static void turbosparc_flush_cache_mm(struct mm_struct *mm)
-{
- FLUSH_BEGIN(mm)
- flush_user_windows();
- turbosparc_idflash_clear();
- FLUSH_END
-}
-
-static void turbosparc_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
-{
- FLUSH_BEGIN(vma->vm_mm)
- flush_user_windows();
- turbosparc_idflash_clear();
- FLUSH_END
-}
-
-static void turbosparc_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
-{
- FLUSH_BEGIN(vma->vm_mm)
- flush_user_windows();
- if (vma->vm_flags & VM_EXEC)
- turbosparc_flush_icache();
- turbosparc_flush_dcache();
- FLUSH_END
-}
-
-/* TurboSparc is copy-back, if we turn it on, but this does not work. */
-static void turbosparc_flush_page_to_ram(unsigned long page)
-{
-#ifdef TURBOSPARC_WRITEBACK
- volatile unsigned long clear;
-
- if (srmmu_probe(page))
- turbosparc_flush_page_cache(page);
- clear = srmmu_get_fstatus();
-#endif
-}
-
-static void turbosparc_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
-{
-}
-
-static void turbosparc_flush_page_for_dma(unsigned long page)
-{
- turbosparc_flush_dcache();
-}
-
-static void turbosparc_flush_tlb_all(void)
-{
- srmmu_flush_whole_tlb();
-}
-
-static void turbosparc_flush_tlb_mm(struct mm_struct *mm)
-{
- FLUSH_BEGIN(mm)
- srmmu_flush_whole_tlb();
- FLUSH_END
-}
-
-static void turbosparc_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
-{
- FLUSH_BEGIN(vma->vm_mm)
- srmmu_flush_whole_tlb();
- FLUSH_END
-}
-
-static void turbosparc_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
- FLUSH_BEGIN(vma->vm_mm)
- srmmu_flush_whole_tlb();
- FLUSH_END
-}
-
-
-static void poke_turbosparc(void)
-{
- unsigned long mreg = srmmu_get_mmureg();
- unsigned long ccreg;
-
- /* Clear any crap from the cache or else... */
- turbosparc_flush_cache_all();
- /* Temporarily disable I & D caches */
- mreg &= ~(TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE);
- mreg &= ~(TURBOSPARC_PCENABLE); /* Don't check parity */
- srmmu_set_mmureg(mreg);
-
- ccreg = turbosparc_get_ccreg();
-
-#ifdef TURBOSPARC_WRITEBACK
- ccreg |= (TURBOSPARC_SNENABLE); /* Do DVMA snooping in Dcache */
- ccreg &= ~(TURBOSPARC_uS2 | TURBOSPARC_WTENABLE);
- /* Write-back D-cache, emulate VLSI
- * abortion number three, not number one */
-#else
- /* For now let's play safe, optimize later */
- ccreg |= (TURBOSPARC_SNENABLE | TURBOSPARC_WTENABLE);
- /* Do DVMA snooping in Dcache, Write-thru D-cache */
- ccreg &= ~(TURBOSPARC_uS2);
- /* Emulate VLSI abortion number three, not number one */
-#endif
-
- switch (ccreg & 7) {
- case 0: /* No SE cache */
- case 7: /* Test mode */
- break;
- default:
- ccreg |= (TURBOSPARC_SCENABLE);
- }
- turbosparc_set_ccreg(ccreg);
-
- mreg |= (TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); /* I & D caches on */
- mreg |= (TURBOSPARC_ICSNOOP); /* Icache snooping on */
- srmmu_set_mmureg(mreg);
-}
-
-static const struct sparc32_cachetlb_ops turbosparc_ops = {
- .cache_all = turbosparc_flush_cache_all,
- .cache_mm = turbosparc_flush_cache_mm,
- .cache_page = turbosparc_flush_cache_page,
- .cache_range = turbosparc_flush_cache_range,
- .tlb_all = turbosparc_flush_tlb_all,
- .tlb_mm = turbosparc_flush_tlb_mm,
- .tlb_page = turbosparc_flush_tlb_page,
- .tlb_range = turbosparc_flush_tlb_range,
- .page_to_ram = turbosparc_flush_page_to_ram,
- .sig_insns = turbosparc_flush_sig_insns,
- .page_for_dma = turbosparc_flush_page_for_dma,
-};
-
-static void __init init_turbosparc(void)
-{
- srmmu_name = "Fujitsu TurboSparc";
- sparc32_cachetlb_ops = &turbosparc_ops;
- poke_srmmu = poke_turbosparc;
-}
-
-static void poke_tsunami(void)
-{
- unsigned long mreg = srmmu_get_mmureg();
-
- tsunami_flush_icache();
- tsunami_flush_dcache();
- mreg &= ~TSUNAMI_ITD;
- mreg |= (TSUNAMI_IENAB | TSUNAMI_DENAB);
- srmmu_set_mmureg(mreg);
-}
-
-static const struct sparc32_cachetlb_ops tsunami_ops = {
- .cache_all = tsunami_flush_cache_all,
- .cache_mm = tsunami_flush_cache_mm,
- .cache_page = tsunami_flush_cache_page,
- .cache_range = tsunami_flush_cache_range,
- .tlb_all = tsunami_flush_tlb_all,
- .tlb_mm = tsunami_flush_tlb_mm,
- .tlb_page = tsunami_flush_tlb_page,
- .tlb_range = tsunami_flush_tlb_range,
- .page_to_ram = tsunami_flush_page_to_ram,
- .sig_insns = tsunami_flush_sig_insns,
- .page_for_dma = tsunami_flush_page_for_dma,
-};
-
-static void __init init_tsunami(void)
-{
- /*
- * Tsunami's pretty sane, Sun and TI actually got it
- * somewhat right this time. Fujitsu should have
- * taken some lessons from them.
- */
-
- srmmu_name = "TI Tsunami";
- sparc32_cachetlb_ops = &tsunami_ops;
- poke_srmmu = poke_tsunami;
-
- tsunami_setup_blockops();
-}
-
-static void poke_viking(void)
-{
- unsigned long mreg = srmmu_get_mmureg();
- static int smp_catch;
-
- if (viking_mxcc_present) {
- unsigned long mxcc_control = mxcc_get_creg();
-
- mxcc_control |= (MXCC_CTL_ECE | MXCC_CTL_PRE | MXCC_CTL_MCE);
- mxcc_control &= ~(MXCC_CTL_RRC);
- mxcc_set_creg(mxcc_control);
-
- /*
- * We don't need memory parity checks.
- * XXX This is a mess, have to dig out later. ecd.
- viking_mxcc_turn_off_parity(&mreg, &mxcc_control);
- */
-
- /* We do cache ptables on MXCC. */
- mreg |= VIKING_TCENABLE;
- } else {
- unsigned long bpreg;
-
- mreg &= ~(VIKING_TCENABLE);
- if (smp_catch++) {
- /* Must disable mixed-cmd mode here for other cpu's. */
- bpreg = viking_get_bpreg();
- bpreg &= ~(VIKING_ACTION_MIX);
- viking_set_bpreg(bpreg);
-
- /* Just in case PROM does something funny. */
- msi_set_sync();
- }
- }
-
- mreg |= VIKING_SPENABLE;
- mreg |= (VIKING_ICENABLE | VIKING_DCENABLE);
- mreg |= VIKING_SBENABLE;
- mreg &= ~(VIKING_ACENABLE);
- srmmu_set_mmureg(mreg);
-}
-
-static struct sparc32_cachetlb_ops viking_ops __ro_after_init = {
- .cache_all = viking_flush_cache_all,
- .cache_mm = viking_flush_cache_mm,
- .cache_page = viking_flush_cache_page,
- .cache_range = viking_flush_cache_range,
- .tlb_all = viking_flush_tlb_all,
- .tlb_mm = viking_flush_tlb_mm,
- .tlb_page = viking_flush_tlb_page,
- .tlb_range = viking_flush_tlb_range,
- .page_to_ram = viking_flush_page_to_ram,
- .sig_insns = viking_flush_sig_insns,
- .page_for_dma = viking_flush_page_for_dma,
-};
-
-#ifdef CONFIG_SMP
-/* On sun4d the cpu broadcasts local TLB flushes, so we can just
- * perform the local TLB flush and all the other cpus will see it.
- * But, unfortunately, there is a bug in the sun4d XBUS backplane
- * that requires that we add some synchronization to these flushes.
- *
- * The bug is that the fifo which keeps track of all the pending TLB
- * broadcasts in the system is an entry or two too small, so if we
- * have too many going at once we'll overflow that fifo and lose a TLB
- * flush resulting in corruption.
- *
- * Our workaround is to take a global spinlock around the TLB flushes,
- * which guarentees we won't ever have too many pending. It's a big
- * hammer, but a semaphore like system to make sure we only have N TLB
- * flushes going at once will require SMP locking anyways so there's
- * no real value in trying any harder than this.
- */
-static struct sparc32_cachetlb_ops viking_sun4d_smp_ops __ro_after_init = {
- .cache_all = viking_flush_cache_all,
- .cache_mm = viking_flush_cache_mm,
- .cache_page = viking_flush_cache_page,
- .cache_range = viking_flush_cache_range,
- .tlb_all = sun4dsmp_flush_tlb_all,
- .tlb_mm = sun4dsmp_flush_tlb_mm,
- .tlb_page = sun4dsmp_flush_tlb_page,
- .tlb_range = sun4dsmp_flush_tlb_range,
- .page_to_ram = viking_flush_page_to_ram,
- .sig_insns = viking_flush_sig_insns,
- .page_for_dma = viking_flush_page_for_dma,
-};
-#endif
-
-static void __init init_viking(void)
-{
- unsigned long mreg = srmmu_get_mmureg();
-
- /* Ahhh, the viking. SRMMU VLSI abortion number two... */
- if (mreg & VIKING_MMODE) {
- srmmu_name = "TI Viking";
- viking_mxcc_present = 0;
- msi_set_sync();
-
- /*
- * We need this to make sure old viking takes no hits
- * on it's cache for dma snoops to workaround the
- * "load from non-cacheable memory" interrupt bug.
- * This is only necessary because of the new way in
- * which we use the IOMMU.
- */
- viking_ops.page_for_dma = viking_flush_page;
-#ifdef CONFIG_SMP
- viking_sun4d_smp_ops.page_for_dma = viking_flush_page;
-#endif
- flush_page_for_dma_global = 0;
- } else {
- srmmu_name = "TI Viking/MXCC";
- viking_mxcc_present = 1;
- srmmu_cache_pagetables = 1;
- }
-
- sparc32_cachetlb_ops = (const struct sparc32_cachetlb_ops *)
- &viking_ops;
-#ifdef CONFIG_SMP
- if (sparc_cpu_model == sun4d)
- sparc32_cachetlb_ops = (const struct sparc32_cachetlb_ops *)
- &viking_sun4d_smp_ops;
-#endif
-
- poke_srmmu = poke_viking;
-}
-
-/* Probe for the srmmu chip version. */
-static void __init get_srmmu_type(void)
-{
- unsigned long mreg, psr;
- unsigned long mod_typ, mod_rev, psr_typ, psr_vers;
-
- mreg = srmmu_get_mmureg(); psr = get_psr();
- mod_typ = (mreg & 0xf0000000) >> 28;
- mod_rev = (mreg & 0x0f000000) >> 24;
- psr_typ = (psr >> 28) & 0xf;
- psr_vers = (psr >> 24) & 0xf;
-
- /* First, check for sparc-leon. */
- if (sparc_cpu_model == sparc_leon) {
- init_leon();
- return;
- }
-
- /* Second, check for HyperSparc or Cypress. */
- if (mod_typ == 1) {
- switch (mod_rev) {
- case 7:
- /* UP or MP Hypersparc */
- init_hypersparc();
- break;
- case 0:
- case 2:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- default:
- prom_printf("Sparc-Linux Cypress support does not longer exit.\n");
- prom_halt();
- break;
- }
- return;
- }
-
- /* Now Fujitsu TurboSparc. It might happen that it is
- * in Swift emulation mode, so we will check later...
- */
- if (psr_typ == 0 && psr_vers == 5) {
- init_turbosparc();
- return;
- }
-
- /* Next check for Fujitsu Swift. */
- if (psr_typ == 0 && psr_vers == 4) {
- phandle cpunode;
- char node_str[128];
-
- /* Look if it is not a TurboSparc emulating Swift... */
- cpunode = prom_getchild(prom_root_node);
- while ((cpunode = prom_getsibling(cpunode)) != 0) {
- prom_getstring(cpunode, "device_type", node_str, sizeof(node_str));
- if (!strcmp(node_str, "cpu")) {
- if (!prom_getintdefault(cpunode, "psr-implementation", 1) &&
- prom_getintdefault(cpunode, "psr-version", 1) == 5) {
- init_turbosparc();
- return;
- }
- break;
- }
- }
-
- init_swift();
- return;
- }
-
- /* Now the Viking family of srmmu. */
- if (psr_typ == 4 &&
- ((psr_vers == 0) ||
- ((psr_vers == 1) && (mod_typ == 0) && (mod_rev == 0)))) {
- init_viking();
- return;
- }
-
- /* Finally the Tsunami. */
- if (psr_typ == 4 && psr_vers == 1 && (mod_typ || mod_rev)) {
- init_tsunami();
- return;
- }
-
- /* Oh well */
- srmmu_is_bad();
-}
-
#ifdef CONFIG_SMP
/* Local cross-calls. */
static void smp_flush_page_for_dma(unsigned long page)
@@ -1736,34 +1008,20 @@ static struct sparc32_cachetlb_ops smp_cachetlb_ops __ro_after_init = {
};
#endif

-/* Load up routines and constants for sun4m and sun4d mmu */
+/* Load up routines and constants for mmu */
void __init load_mmu(void)
{
/* Functions */
- get_srmmu_type();
+ init_leon();

#ifdef CONFIG_SMP
/* El switcheroo... */
local_ops = sparc32_cachetlb_ops;

- if (sparc_cpu_model == sun4d || sparc_cpu_model == sparc_leon) {
- smp_cachetlb_ops.tlb_all = local_ops->tlb_all;
- smp_cachetlb_ops.tlb_mm = local_ops->tlb_mm;
- smp_cachetlb_ops.tlb_range = local_ops->tlb_range;
- smp_cachetlb_ops.tlb_page = local_ops->tlb_page;
- }
-
- if (poke_srmmu == poke_viking) {
- /* Avoid unnecessary cross calls. */
- smp_cachetlb_ops.cache_all = local_ops->cache_all;
- smp_cachetlb_ops.cache_mm = local_ops->cache_mm;
- smp_cachetlb_ops.cache_range = local_ops->cache_range;
- smp_cachetlb_ops.cache_page = local_ops->cache_page;
-
- smp_cachetlb_ops.page_to_ram = local_ops->page_to_ram;
- smp_cachetlb_ops.sig_insns = local_ops->sig_insns;
- smp_cachetlb_ops.page_for_dma = local_ops->page_for_dma;
- }
+ smp_cachetlb_ops.tlb_all = local_ops->tlb_all;
+ smp_cachetlb_ops.tlb_mm = local_ops->tlb_mm;
+ smp_cachetlb_ops.tlb_range = local_ops->tlb_range;
+ smp_cachetlb_ops.tlb_page = local_ops->tlb_page;

/* It really is const after this point. */
sparc32_cachetlb_ops = (const struct sparc32_cachetlb_ops *)
diff --git a/arch/sparc/mm/swift.S b/arch/sparc/mm/swift.S
deleted file mode 100644
index f414bfd8d899..000000000000
--- a/arch/sparc/mm/swift.S
+++ /dev/null
@@ -1,256 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * swift.S: MicroSparc-II mmu/cache operations.
- *
- * Copyright (C) 1999 David S. Miller ([email protected])
- */
-
-#include <asm/psr.h>
-#include <asm/asi.h>
-#include <asm/page.h>
-#include <asm/pgtsrmmu.h>
-#include <asm/asm-offsets.h>
-
- .text
- .align 4
-
-#if 1 /* XXX screw this, I can't get the VAC flushes working
- * XXX reliably... -DaveM
- */
- .globl swift_flush_cache_all, swift_flush_cache_mm
- .globl swift_flush_cache_range, swift_flush_cache_page
- .globl swift_flush_page_for_dma
- .globl swift_flush_page_to_ram
-
-swift_flush_cache_all:
-swift_flush_cache_mm:
-swift_flush_cache_range:
-swift_flush_cache_page:
-swift_flush_page_for_dma:
-swift_flush_page_to_ram:
- sethi %hi(0x2000), %o0
-1: subcc %o0, 0x10, %o0
- add %o0, %o0, %o1
- sta %g0, [%o0] ASI_M_DATAC_TAG
- bne 1b
- sta %g0, [%o1] ASI_M_TXTC_TAG
- retl
- nop
-#else
-
- .globl swift_flush_cache_all
-swift_flush_cache_all:
- WINDOW_FLUSH(%g4, %g5)
-
- /* Just clear out all the tags. */
- sethi %hi(16 * 1024), %o0
-1: subcc %o0, 16, %o0
- sta %g0, [%o0] ASI_M_TXTC_TAG
- bne 1b
- sta %g0, [%o0] ASI_M_DATAC_TAG
- retl
- nop
-
- .globl swift_flush_cache_mm
-swift_flush_cache_mm:
- ld [%o0 + AOFF_mm_context], %g2
- cmp %g2, -1
- be swift_flush_cache_mm_out
- WINDOW_FLUSH(%g4, %g5)
- rd %psr, %g1
- andn %g1, PSR_ET, %g3
- wr %g3, 0x0, %psr
- nop
- nop
- mov SRMMU_CTX_REG, %g7
- lda [%g7] ASI_M_MMUREGS, %g5
- sta %g2, [%g7] ASI_M_MMUREGS
-
-#if 1
- sethi %hi(0x2000), %o0
-1: subcc %o0, 0x10, %o0
- sta %g0, [%o0] ASI_M_FLUSH_CTX
- bne 1b
- nop
-#else
- clr %o0
- or %g0, 2048, %g7
- or %g0, 2048, %o1
- add %o1, 2048, %o2
- add %o2, 2048, %o3
- mov 16, %o4
- add %o4, 2048, %o5
- add %o5, 2048, %g2
- add %g2, 2048, %g3
-1: sta %g0, [%o0 ] ASI_M_FLUSH_CTX
- sta %g0, [%o0 + %o1] ASI_M_FLUSH_CTX
- sta %g0, [%o0 + %o2] ASI_M_FLUSH_CTX
- sta %g0, [%o0 + %o3] ASI_M_FLUSH_CTX
- sta %g0, [%o0 + %o4] ASI_M_FLUSH_CTX
- sta %g0, [%o0 + %o5] ASI_M_FLUSH_CTX
- sta %g0, [%o0 + %g2] ASI_M_FLUSH_CTX
- sta %g0, [%o0 + %g3] ASI_M_FLUSH_CTX
- subcc %g7, 32, %g7
- bne 1b
- add %o0, 32, %o0
-#endif
-
- mov SRMMU_CTX_REG, %g7
- sta %g5, [%g7] ASI_M_MMUREGS
- wr %g1, 0x0, %psr
- nop
- nop
-swift_flush_cache_mm_out:
- retl
- nop
-
- .globl swift_flush_cache_range
-swift_flush_cache_range:
- ld [%o0 + VMA_VM_MM], %o0
- sub %o2, %o1, %o2
- sethi %hi(4096), %o3
- cmp %o2, %o3
- bgu swift_flush_cache_mm
- nop
- b 70f
- nop
-
- .globl swift_flush_cache_page
-swift_flush_cache_page:
- ld [%o0 + VMA_VM_MM], %o0
-70:
- ld [%o0 + AOFF_mm_context], %g2
- cmp %g2, -1
- be swift_flush_cache_page_out
- WINDOW_FLUSH(%g4, %g5)
- rd %psr, %g1
- andn %g1, PSR_ET, %g3
- wr %g3, 0x0, %psr
- nop
- nop
- mov SRMMU_CTX_REG, %g7
- lda [%g7] ASI_M_MMUREGS, %g5
- sta %g2, [%g7] ASI_M_MMUREGS
-
- andn %o1, (PAGE_SIZE - 1), %o1
-#if 1
- sethi %hi(0x1000), %o0
-1: subcc %o0, 0x10, %o0
- sta %g0, [%o1 + %o0] ASI_M_FLUSH_PAGE
- bne 1b
- nop
-#else
- or %g0, 512, %g7
- or %g0, 512, %o0
- add %o0, 512, %o2
- add %o2, 512, %o3
- add %o3, 512, %o4
- add %o4, 512, %o5
- add %o5, 512, %g3
- add %g3, 512, %g4
-1: sta %g0, [%o1 ] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o0] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o2] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o3] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o4] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o5] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %g3] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %g4] ASI_M_FLUSH_PAGE
- subcc %g7, 16, %g7
- bne 1b
- add %o1, 16, %o1
-#endif
-
- mov SRMMU_CTX_REG, %g7
- sta %g5, [%g7] ASI_M_MMUREGS
- wr %g1, 0x0, %psr
- nop
- nop
-swift_flush_cache_page_out:
- retl
- nop
-
- /* Swift is write-thru, however it is not
- * I/O nor TLB-walk coherent. Also it has
- * caches which are virtually indexed and tagged.
- */
- .globl swift_flush_page_for_dma
- .globl swift_flush_page_to_ram
-swift_flush_page_for_dma:
-swift_flush_page_to_ram:
- andn %o0, (PAGE_SIZE - 1), %o1
-#if 1
- sethi %hi(0x1000), %o0
-1: subcc %o0, 0x10, %o0
- sta %g0, [%o1 + %o0] ASI_M_FLUSH_PAGE
- bne 1b
- nop
-#else
- or %g0, 512, %g7
- or %g0, 512, %o0
- add %o0, 512, %o2
- add %o2, 512, %o3
- add %o3, 512, %o4
- add %o4, 512, %o5
- add %o5, 512, %g3
- add %g3, 512, %g4
-1: sta %g0, [%o1 ] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o0] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o2] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o3] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o4] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %o5] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %g3] ASI_M_FLUSH_PAGE
- sta %g0, [%o1 + %g4] ASI_M_FLUSH_PAGE
- subcc %g7, 16, %g7
- bne 1b
- add %o1, 16, %o1
-#endif
- retl
- nop
-#endif
-
- .globl swift_flush_sig_insns
-swift_flush_sig_insns:
- flush %o1
- retl
- flush %o1 + 4
-
- .globl swift_flush_tlb_mm
- .globl swift_flush_tlb_range
- .globl swift_flush_tlb_all
-swift_flush_tlb_range:
- ld [%o0 + VMA_VM_MM], %o0
-swift_flush_tlb_mm:
- ld [%o0 + AOFF_mm_context], %g2
- cmp %g2, -1
- be swift_flush_tlb_all_out
-swift_flush_tlb_all:
- mov 0x400, %o1
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
-swift_flush_tlb_all_out:
- retl
- nop
-
- .globl swift_flush_tlb_page
-swift_flush_tlb_page:
- ld [%o0 + VMA_VM_MM], %o0
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + AOFF_mm_context], %o3
- andn %o1, (PAGE_SIZE - 1), %o1
- cmp %o3, -1
- be swift_flush_tlb_page_out
- nop
-#if 1
- mov 0x400, %o1
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
-#else
- lda [%g1] ASI_M_MMUREGS, %g5
- sta %o3, [%g1] ASI_M_MMUREGS
- sta %g0, [%o1] ASI_M_FLUSH_PAGE /* rem. virt. cache. prot. */
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
- sta %g5, [%g1] ASI_M_MMUREGS
-#endif
-swift_flush_tlb_page_out:
- retl
- nop
diff --git a/arch/sparc/mm/tsunami.S b/arch/sparc/mm/tsunami.S
deleted file mode 100644
index 62b742df65dc..000000000000
--- a/arch/sparc/mm/tsunami.S
+++ /dev/null
@@ -1,132 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * tsunami.S: High speed MicroSparc-I mmu/cache operations.
- *
- * Copyright (C) 1997 David S. Miller ([email protected])
- */
-
-#include <asm/ptrace.h>
-#include <asm/asm-offsets.h>
-#include <asm/psr.h>
-#include <asm/asi.h>
-#include <asm/page.h>
-#include <asm/pgtsrmmu.h>
-
- .text
- .align 4
-
- .globl tsunami_flush_cache_all, tsunami_flush_cache_mm
- .globl tsunami_flush_cache_range, tsunami_flush_cache_page
- .globl tsunami_flush_page_to_ram, tsunami_flush_page_for_dma
- .globl tsunami_flush_sig_insns
- .globl tsunami_flush_tlb_all, tsunami_flush_tlb_mm
- .globl tsunami_flush_tlb_range, tsunami_flush_tlb_page
-
- /* Sliiick... */
-tsunami_flush_cache_page:
-tsunami_flush_cache_range:
- ld [%o0 + VMA_VM_MM], %o0
-tsunami_flush_cache_mm:
- ld [%o0 + AOFF_mm_context], %g2
- cmp %g2, -1
- be tsunami_flush_cache_out
-tsunami_flush_cache_all:
- WINDOW_FLUSH(%g4, %g5)
-tsunami_flush_page_for_dma:
- sta %g0, [%g0] ASI_M_IC_FLCLEAR
- sta %g0, [%g0] ASI_M_DC_FLCLEAR
-tsunami_flush_cache_out:
-tsunami_flush_page_to_ram:
- retl
- nop
-
-tsunami_flush_sig_insns:
- flush %o1
- retl
- flush %o1 + 4
-
- /* More slick stuff... */
-tsunami_flush_tlb_range:
- ld [%o0 + VMA_VM_MM], %o0
-tsunami_flush_tlb_mm:
- ld [%o0 + AOFF_mm_context], %g2
- cmp %g2, -1
- be tsunami_flush_tlb_out
-tsunami_flush_tlb_all:
- mov 0x400, %o1
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
- nop
- nop
- nop
- nop
- nop
-tsunami_flush_tlb_out:
- retl
- nop
-
- /* This one can be done in a fine grained manner... */
-tsunami_flush_tlb_page:
- ld [%o0 + VMA_VM_MM], %o0
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + AOFF_mm_context], %o3
- andn %o1, (PAGE_SIZE - 1), %o1
- cmp %o3, -1
- be tsunami_flush_tlb_page_out
- lda [%g1] ASI_M_MMUREGS, %g5
- sta %o3, [%g1] ASI_M_MMUREGS
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
- nop
- nop
- nop
- nop
- nop
-tsunami_flush_tlb_page_out:
- retl
- sta %g5, [%g1] ASI_M_MMUREGS
-
-#define MIRROR_BLOCK(dst, src, offset, t0, t1, t2, t3) \
- ldd [src + offset + 0x18], t0; \
- std t0, [dst + offset + 0x18]; \
- ldd [src + offset + 0x10], t2; \
- std t2, [dst + offset + 0x10]; \
- ldd [src + offset + 0x08], t0; \
- std t0, [dst + offset + 0x08]; \
- ldd [src + offset + 0x00], t2; \
- std t2, [dst + offset + 0x00];
-
-tsunami_copy_1page:
-/* NOTE: This routine has to be shorter than 70insns --jj */
- or %g0, (PAGE_SIZE >> 8), %g1
-1:
- MIRROR_BLOCK(%o0, %o1, 0x00, %o2, %o3, %o4, %o5)
- MIRROR_BLOCK(%o0, %o1, 0x20, %o2, %o3, %o4, %o5)
- MIRROR_BLOCK(%o0, %o1, 0x40, %o2, %o3, %o4, %o5)
- MIRROR_BLOCK(%o0, %o1, 0x60, %o2, %o3, %o4, %o5)
- MIRROR_BLOCK(%o0, %o1, 0x80, %o2, %o3, %o4, %o5)
- MIRROR_BLOCK(%o0, %o1, 0xa0, %o2, %o3, %o4, %o5)
- MIRROR_BLOCK(%o0, %o1, 0xc0, %o2, %o3, %o4, %o5)
- MIRROR_BLOCK(%o0, %o1, 0xe0, %o2, %o3, %o4, %o5)
- subcc %g1, 1, %g1
- add %o0, 0x100, %o0
- bne 1b
- add %o1, 0x100, %o1
-
- .globl tsunami_setup_blockops
-tsunami_setup_blockops:
- sethi %hi(__copy_1page), %o0
- or %o0, %lo(__copy_1page), %o0
- sethi %hi(tsunami_copy_1page), %o1
- or %o1, %lo(tsunami_copy_1page), %o1
- sethi %hi(tsunami_setup_blockops), %o2
- or %o2, %lo(tsunami_setup_blockops), %o2
- ld [%o1], %o4
-1: add %o1, 4, %o1
- st %o4, [%o0]
- add %o0, 4, %o0
- cmp %o1, %o2
- bne 1b
- ld [%o1], %o4
- sta %g0, [%g0] ASI_M_IC_FLCLEAR
- sta %g0, [%g0] ASI_M_DC_FLCLEAR
- retl
- nop
diff --git a/arch/sparc/mm/viking.S b/arch/sparc/mm/viking.S
deleted file mode 100644
index 48f062de7a7f..000000000000
--- a/arch/sparc/mm/viking.S
+++ /dev/null
@@ -1,284 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * viking.S: High speed Viking cache/mmu operations
- *
- * Copyright (C) 1997 Eddie C. Dost ([email protected])
- * Copyright (C) 1997,1998,1999 Jakub Jelinek ([email protected])
- * Copyright (C) 1999 Pavel Semerad ([email protected])
- */
-
-#include <asm/ptrace.h>
-#include <asm/psr.h>
-#include <asm/asm-offsets.h>
-#include <asm/asi.h>
-#include <asm/mxcc.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/pgtsrmmu.h>
-#include <asm/viking.h>
-
-#ifdef CONFIG_SMP
- .data
- .align 4
-sun4dsmp_flush_tlb_spin:
- .word 0
-#endif
-
- .text
- .align 4
-
- .globl viking_flush_cache_all, viking_flush_cache_mm
- .globl viking_flush_cache_range, viking_flush_cache_page
- .globl viking_flush_page, viking_mxcc_flush_page
- .globl viking_flush_page_for_dma, viking_flush_page_to_ram
- .globl viking_flush_sig_insns
- .globl viking_flush_tlb_all, viking_flush_tlb_mm
- .globl viking_flush_tlb_range, viking_flush_tlb_page
-
-viking_flush_page:
- sethi %hi(PAGE_OFFSET), %g2
- sub %o0, %g2, %g3
- srl %g3, 12, %g1 ! ppage >> 12
-
- clr %o1 ! set counter, 0 - 127
- sethi %hi(PAGE_OFFSET + PAGE_SIZE - 0x80000000), %o3
- sethi %hi(0x80000000), %o4
- sethi %hi(VIKING_PTAG_VALID), %o5
- sethi %hi(2*PAGE_SIZE), %o0
- sethi %hi(PAGE_SIZE), %g7
- clr %o2 ! block counter, 0 - 3
-5:
- sll %o1, 5, %g4
- or %g4, %o4, %g4 ! 0x80000000 | (set << 5)
-
- sll %o2, 26, %g5 ! block << 26
-6:
- or %g5, %g4, %g5
- ldda [%g5] ASI_M_DATAC_TAG, %g2
- cmp %g3, %g1 ! ptag == ppage?
- bne 7f
- inc %o2
-
- andcc %g2, %o5, %g0 ! ptag VALID?
- be 7f
- add %g4, %o3, %g2 ! (PAGE_OFFSET + PAGE_SIZE) | (set << 5)
- ld [%g2], %g3
- ld [%g2 + %g7], %g3
- add %g2, %o0, %g2
- ld [%g2], %g3
- ld [%g2 + %g7], %g3
- add %g2, %o0, %g2
- ld [%g2], %g3
- ld [%g2 + %g7], %g3
- add %g2, %o0, %g2
- ld [%g2], %g3
- b 8f
- ld [%g2 + %g7], %g3
-
-7:
- cmp %o2, 3
- ble 6b
- sll %o2, 26, %g5 ! block << 26
-
-8: inc %o1
- cmp %o1, 0x7f
- ble 5b
- clr %o2
-
-9: retl
- nop
-
-viking_mxcc_flush_page:
- sethi %hi(PAGE_OFFSET), %g2
- sub %o0, %g2, %g3
- sub %g3, -PAGE_SIZE, %g3 ! ppage + PAGE_SIZE
- sethi %hi(MXCC_SRCSTREAM), %o3 ! assume %hi(MXCC_SRCSTREAM) == %hi(MXCC_DESTSTREAM)
- mov 0x10, %g2 ! set cacheable bit
- or %o3, %lo(MXCC_SRCSTREAM), %o2
- or %o3, %lo(MXCC_DESSTREAM), %o3
- sub %g3, MXCC_STREAM_SIZE, %g3
-6:
- stda %g2, [%o2] ASI_M_MXCC
- stda %g2, [%o3] ASI_M_MXCC
- andncc %g3, PAGE_MASK, %g0
- bne 6b
- sub %g3, MXCC_STREAM_SIZE, %g3
-
-9: retl
- nop
-
-viking_flush_cache_page:
-viking_flush_cache_range:
-#ifndef CONFIG_SMP
- ld [%o0 + VMA_VM_MM], %o0
-#endif
-viking_flush_cache_mm:
-#ifndef CONFIG_SMP
- ld [%o0 + AOFF_mm_context], %g1
- cmp %g1, -1
- bne viking_flush_cache_all
- nop
- b,a viking_flush_cache_out
-#endif
-viking_flush_cache_all:
- WINDOW_FLUSH(%g4, %g5)
-viking_flush_cache_out:
- retl
- nop
-
-viking_flush_tlb_all:
- mov 0x400, %g1
- retl
- sta %g0, [%g1] ASI_M_FLUSH_PROBE
-
-viking_flush_tlb_mm:
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + AOFF_mm_context], %o1
- lda [%g1] ASI_M_MMUREGS, %g5
-#ifndef CONFIG_SMP
- cmp %o1, -1
- be 1f
-#endif
- mov 0x300, %g2
- sta %o1, [%g1] ASI_M_MMUREGS
- sta %g0, [%g2] ASI_M_FLUSH_PROBE
- retl
- sta %g5, [%g1] ASI_M_MMUREGS
-#ifndef CONFIG_SMP
-1: retl
- nop
-#endif
-
-viking_flush_tlb_range:
- ld [%o0 + VMA_VM_MM], %o0
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + AOFF_mm_context], %o3
- lda [%g1] ASI_M_MMUREGS, %g5
-#ifndef CONFIG_SMP
- cmp %o3, -1
- be 2f
-#endif
- sethi %hi(~((1 << PGDIR_SHIFT) - 1)), %o4
- sta %o3, [%g1] ASI_M_MMUREGS
- and %o1, %o4, %o1
- add %o1, 0x200, %o1
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
-1: sub %o1, %o4, %o1
- cmp %o1, %o2
- blu,a 1b
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
- retl
- sta %g5, [%g1] ASI_M_MMUREGS
-#ifndef CONFIG_SMP
-2: retl
- nop
-#endif
-
-viking_flush_tlb_page:
- ld [%o0 + VMA_VM_MM], %o0
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + AOFF_mm_context], %o3
- lda [%g1] ASI_M_MMUREGS, %g5
-#ifndef CONFIG_SMP
- cmp %o3, -1
- be 1f
-#endif
- and %o1, PAGE_MASK, %o1
- sta %o3, [%g1] ASI_M_MMUREGS
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
- retl
- sta %g5, [%g1] ASI_M_MMUREGS
-#ifndef CONFIG_SMP
-1: retl
- nop
-#endif
-
-viking_flush_page_to_ram:
-viking_flush_page_for_dma:
-viking_flush_sig_insns:
- retl
- nop
-
-#ifdef CONFIG_SMP
- .globl sun4dsmp_flush_tlb_all, sun4dsmp_flush_tlb_mm
- .globl sun4dsmp_flush_tlb_range, sun4dsmp_flush_tlb_page
-sun4dsmp_flush_tlb_all:
- sethi %hi(sun4dsmp_flush_tlb_spin), %g3
-1: ldstub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
- tst %g5
- bne 2f
- mov 0x400, %g1
- sta %g0, [%g1] ASI_M_FLUSH_PROBE
- retl
- stb %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
-2: tst %g5
- bne,a 2b
- ldub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
- b,a 1b
-
-sun4dsmp_flush_tlb_mm:
- sethi %hi(sun4dsmp_flush_tlb_spin), %g3
-1: ldstub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
- tst %g5
- bne 2f
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + AOFF_mm_context], %o1
- lda [%g1] ASI_M_MMUREGS, %g5
- mov 0x300, %g2
- sta %o1, [%g1] ASI_M_MMUREGS
- sta %g0, [%g2] ASI_M_FLUSH_PROBE
- sta %g5, [%g1] ASI_M_MMUREGS
- retl
- stb %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
-2: tst %g5
- bne,a 2b
- ldub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
- b,a 1b
-
-sun4dsmp_flush_tlb_range:
- sethi %hi(sun4dsmp_flush_tlb_spin), %g3
-1: ldstub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
- tst %g5
- bne 3f
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + VMA_VM_MM], %o0
- ld [%o0 + AOFF_mm_context], %o3
- lda [%g1] ASI_M_MMUREGS, %g5
- sethi %hi(~((1 << PGDIR_SHIFT) - 1)), %o4
- sta %o3, [%g1] ASI_M_MMUREGS
- and %o1, %o4, %o1
- add %o1, 0x200, %o1
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
-2: sub %o1, %o4, %o1
- cmp %o1, %o2
- blu,a 2b
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
- sta %g5, [%g1] ASI_M_MMUREGS
- retl
- stb %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
-3: tst %g5
- bne,a 3b
- ldub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
- b,a 1b
-
-sun4dsmp_flush_tlb_page:
- sethi %hi(sun4dsmp_flush_tlb_spin), %g3
-1: ldstub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
- tst %g5
- bne 2f
- mov SRMMU_CTX_REG, %g1
- ld [%o0 + VMA_VM_MM], %o0
- ld [%o0 + AOFF_mm_context], %o3
- lda [%g1] ASI_M_MMUREGS, %g5
- and %o1, PAGE_MASK, %o1
- sta %o3, [%g1] ASI_M_MMUREGS
- sta %g0, [%o1] ASI_M_FLUSH_PROBE
- sta %g5, [%g1] ASI_M_MMUREGS
- retl
- stb %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
-2: tst %g5
- bne,a 2b
- ldub [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
- b,a 1b
- nop
-#endif
--
2.27.0

2020-12-18 20:46:53

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 10/13] sparc32: Drop mbus support

Only used by older SAPRC HW, not used by LEON.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Arvind Sankar <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: Ira Weiny <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/include/asm/elf_32.h | 2 -
arch/sparc/include/asm/mbus.h | 97 ---------------------------------
arch/sparc/kernel/cpu.c | 1 -
arch/sparc/kernel/setup_32.c | 1 -
arch/sparc/mm/iommu.c | 18 +-----
arch/sparc/mm/srmmu.c | 48 ----------------
6 files changed, 3 insertions(+), 164 deletions(-)
delete mode 100644 arch/sparc/include/asm/mbus.h

diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h
index 37a6016c9ccd..b2cca9be55c2 100644
--- a/arch/sparc/include/asm/elf_32.h
+++ b/arch/sparc/include/asm/elf_32.h
@@ -91,8 +91,6 @@ typedef struct {
unsigned int pr_q[64];
} elf_fpregset_t;

-#include <asm/mbus.h>
-
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
diff --git a/arch/sparc/include/asm/mbus.h b/arch/sparc/include/asm/mbus.h
deleted file mode 100644
index 8b6dbe701b9b..000000000000
--- a/arch/sparc/include/asm/mbus.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * mbus.h: Various defines for MBUS modules.
- *
- * Copyright (C) 1995 David S. Miller ([email protected])
- */
-
-#ifndef _SPARC_MBUS_H
-#define _SPARC_MBUS_H
-
-#include <asm/ross.h> /* HyperSparc stuff */
-#include <asm/viking.h> /* Ugh, bug city... */
-
-enum mbus_module {
- HyperSparc = 0,
- Swift_ok = 4,
- Swift_bad_c = 5,
- Swift_lots_o_bugs = 6,
- Tsunami = 7,
- Viking_12 = 8,
- Viking_2x = 9,
- Viking_30 = 10,
- Viking_35 = 11,
- Viking_new = 12,
- TurboSparc = 13,
- SRMMU_INVAL_MOD = 14,
-};
-
-extern enum mbus_module srmmu_modtype;
-extern unsigned int viking_rev, swift_rev, cypress_rev;
-
-/* HW Mbus module bugs we have to deal with */
-#define HWBUG_COPYBACK_BROKEN 0x00000001
-#define HWBUG_ASIFLUSH_BROKEN 0x00000002
-#define HWBUG_VACFLUSH_BITROT 0x00000004
-#define HWBUG_KERN_ACCBROKEN 0x00000008
-#define HWBUG_KERN_CBITBROKEN 0x00000010
-#define HWBUG_MODIFIED_BITROT 0x00000020
-#define HWBUG_PC_BADFAULT_ADDR 0x00000040
-#define HWBUG_SUPERSCALAR_BAD 0x00000080
-#define HWBUG_PACINIT_BITROT 0x00000100
-
-/* First the module type values. To find out which you have, just load
- * the mmu control register from ASI_M_MMUREG alternate address space and
- * shift the value right 28 bits.
- */
-/* IMPL field means the company which produced the chip. */
-#define MBUS_VIKING 0x4 /* bleech, Texas Instruments Module */
-#define MBUS_LSI 0x3 /* LSI Logics */
-#define MBUS_ROSS 0x1 /* Ross is nice */
-#define MBUS_FMI 0x0 /* Fujitsu Microelectronics/Swift */
-
-/* Ross Module versions */
-#define ROSS_604_REV_CDE 0x0 /* revisions c, d, and e */
-#define ROSS_604_REV_F 0x1 /* revision f */
-#define ROSS_605 0xf /* revision a, a.1, and a.2 */
-#define ROSS_605_REV_B 0xe /* revision b */
-
-/* TI Viking Module versions */
-#define VIKING_REV_12 0x1 /* Version 1.2 or SPARCclassic's CPU */
-#define VIKING_REV_2 0x2 /* Version 2.1, 2.2, 2.3, and 2.4 */
-#define VIKING_REV_30 0x3 /* Version 3.0 */
-#define VIKING_REV_35 0x4 /* Version 3.5 */
-
-/* LSI Logics. */
-#define LSI_L64815 0x0
-
-/* Fujitsu */
-#define FMI_AURORA 0x4 /* MB8690x, a Swift module... */
-#define FMI_TURBO 0x5 /* MB86907, a TurboSparc module... */
-
-/* For multiprocessor support we need to be able to obtain the CPU id and
- * the MBUS Module id.
- */
-
-/* The CPU ID is encoded in the trap base register, 20 bits to the left of
- * bit zero, with 2 bits being significant.
- */
-#define TBR_ID_SHIFT 20
-
-static inline int get_cpuid(void)
-{
- register int retval;
- __asm__ __volatile__("rd %%tbr, %0\n\t"
- "srl %0, %1, %0\n\t" :
- "=r" (retval) :
- "i" (TBR_ID_SHIFT));
- return (retval & 3);
-}
-
-static inline int get_modid(void)
-{
- return (get_cpuid() | 0x8);
-}
-
-
-#endif /* !(_SPARC_MBUS_H) */
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 79cd6ccfeac0..cca7de051593 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -19,7 +19,6 @@
#include <asm/page.h>
#include <asm/head.h>
#include <asm/psr.h>
-#include <asm/mbus.h>
#include <asm/cpudata.h>

#include "kernel.h"
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index eea43a1aef1b..b6fd87928c73 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -42,7 +42,6 @@
#include <asm/page.h>
#include <asm/traps.h>
#include <asm/vaddrs.h>
-#include <asm/mbus.h>
#include <asm/idprom.h>
#include <asm/cpudata.h>
#include <asm/setup.h>
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 0c0342e5b10d..125a3e96e3d2 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -18,7 +18,6 @@

#include <asm/io.h>
#include <asm/mxcc.h>
-#include <asm/mbus.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/bitext.h>
@@ -116,13 +115,7 @@ static void __init sbus_iommu_init(struct platform_device *op)
prom_halt();
}
bit_map_init(&iommu->usemap, bitmap, IOMMU_NPTES);
- /* To be coherent on HyperSparc, the page color of DVMA
- * and physical addresses must match.
- */
- if (srmmu_modtype == HyperSparc)
- iommu->usemap.num_colors = vac_cache_size >> PAGE_SHIFT;
- else
- iommu->usemap.num_colors = 1;
+ iommu->usemap.num_colors = 1;

printk(KERN_INFO "IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n",
impl, vers, iommu->page_table,
@@ -444,11 +437,6 @@ static const struct dma_map_ops sbus_iommu_dma_pflush_ops = {

void __init ld_mmu_iommu(void)
{
- if (viking_mxcc_present || srmmu_modtype == HyperSparc) {
- dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV);
- ioperm_noc = IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID;
- } else {
- dvma_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV);
- ioperm_noc = IOPTE_WRITE | IOPTE_VALID;
- }
+ dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV);
+ ioperm_noc = IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID;
}
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index d82cec45023a..802529aa02b9 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -34,7 +34,6 @@
#include <asm/cache.h>
#include <asm/traps.h>
#include <asm/oplib.h>
-#include <asm/mbus.h>
#include <asm/page.h>
#include <asm/asi.h>
#include <asm/smp.h>
@@ -51,8 +50,6 @@

#include "mm_32.h"

-enum mbus_module srmmu_modtype;
-static unsigned int hwbug_bitmask;
int vac_cache_size;
EXPORT_SYMBOL(vac_cache_size);
int vac_line_size;
@@ -1116,7 +1113,6 @@ static const struct sparc32_cachetlb_ops hypersparc_ops = {
static void __init init_hypersparc(void)
{
srmmu_name = "ROSS HyperSparc";
- srmmu_modtype = HyperSparc;

init_vac_layout();

@@ -1175,45 +1171,6 @@ static void __init init_swift(void)
"=r" (swift_rev) :
"r" (SWIFT_MASKID_ADDR), "i" (ASI_M_BYPASS));
srmmu_name = "Fujitsu Swift";
- switch (swift_rev) {
- case 0x11:
- case 0x20:
- case 0x23:
- case 0x30:
- srmmu_modtype = Swift_lots_o_bugs;
- hwbug_bitmask |= (HWBUG_KERN_ACCBROKEN | HWBUG_KERN_CBITBROKEN);
- /*
- * Gee george, I wonder why Sun is so hush hush about
- * this hardware bug... really braindamage stuff going
- * on here. However I think we can find a way to avoid
- * all of the workaround overhead under Linux. Basically,
- * any page fault can cause kernel pages to become user
- * accessible (the mmu gets confused and clears some of
- * the ACC bits in kernel ptes). Aha, sounds pretty
- * horrible eh? But wait, after extensive testing it appears
- * that if you use pgd_t level large kernel pte's (like the
- * 4MB pages on the Pentium) the bug does not get tripped
- * at all. This avoids almost all of the major overhead.
- * Welcome to a world where your vendor tells you to,
- * "apply this kernel patch" instead of "sorry for the
- * broken hardware, send it back and we'll give you
- * properly functioning parts"
- */
- break;
- case 0x25:
- case 0x31:
- srmmu_modtype = Swift_bad_c;
- hwbug_bitmask |= HWBUG_KERN_CBITBROKEN;
- /*
- * You see Sun allude to this hardware bug but never
- * admit things directly, they'll say things like,
- * "the Swift chip cache problems" or similar.
- */
- break;
- default:
- srmmu_modtype = Swift_ok;
- break;
- }

sparc32_cachetlb_ops = &swift_ops;
flush_page_for_dma_global = 0;
@@ -1366,7 +1323,6 @@ static const struct sparc32_cachetlb_ops turbosparc_ops = {
static void __init init_turbosparc(void)
{
srmmu_name = "Fujitsu TurboSparc";
- srmmu_modtype = TurboSparc;
sparc32_cachetlb_ops = &turbosparc_ops;
poke_srmmu = poke_turbosparc;
}
@@ -1405,7 +1361,6 @@ static void __init init_tsunami(void)
*/

srmmu_name = "TI Tsunami";
- srmmu_modtype = Tsunami;
sparc32_cachetlb_ops = &tsunami_ops;
poke_srmmu = poke_tsunami;

@@ -1545,9 +1500,6 @@ static void __init get_srmmu_type(void)
unsigned long mreg, psr;
unsigned long mod_typ, mod_rev, psr_typ, psr_vers;

- srmmu_modtype = SRMMU_INVAL_MOD;
- hwbug_bitmask = 0;
-
mreg = srmmu_get_mmureg(); psr = get_psr();
mod_typ = (mreg & 0xf0000000) >> 28;
mod_rev = (mreg & 0x0f000000) >> 24;
--
2.27.0

2020-12-18 20:47:00

by Sam Ravnborg

[permalink] [raw]
Subject: [PATCH v1 08/13] sparc32: Drop sun4d/sun4m smp support

Drop the sun4m and sun4d smp support code.

The sparc32 kernel will not boot unless this is a LEON system,
so drop checks for other systems as they will not trigger.

Signed-off-by: Sam Ravnborg <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Christian Brauner <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Andreas Larsson <[email protected]>
---
arch/sparc/kernel/Makefile | 2 +-
arch/sparc/kernel/smp_32.c | 102 +--------
arch/sparc/kernel/sun4d_smp.c | 410 ----------------------------------
arch/sparc/kernel/sun4m_smp.c | 273 ----------------------
arch/sparc/mm/srmmu.c | 10 +-
5 files changed, 8 insertions(+), 789 deletions(-)
delete mode 100644 arch/sparc/kernel/sun4d_smp.c
delete mode 100644 arch/sparc/kernel/sun4m_smp.c

diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 92a9fdbba0a5..5ddc11cfd84a 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -81,7 +81,7 @@ obj-$(CONFIG_SPARC_GRPCI2)+= leon_pci_grpci2.o
obj-$(CONFIG_SPARC_GRPCI1)+= leon_pci_grpci1.o

obj-$(CONFIG_SMP) += trampoline_$(BITS).o smp_$(BITS).o
-obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o leon_smp.o
+obj-$(CONFIG_SPARC32_SMP) += leon_smp.o
obj-$(CONFIG_SPARC64_SMP) += hvtramp.o

obj-$(CONFIG_SPARC64) += auxio_64.o
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 50c127ab46d5..bcda7e469da9 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -87,29 +87,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
num, bogosum/(500000/HZ),
(bogosum/(5000/HZ))%100);

- switch(sparc_cpu_model) {
- case sun4m:
- smp4m_smp_done();
- break;
- case sun4d:
- smp4d_smp_done();
- break;
- case sparc_leon:
- leon_smp_done();
- break;
- case sun4e:
- printk("SUN4E\n");
- BUG();
- break;
- case sun4u:
- printk("SUN4U\n");
- BUG();
- break;
- default:
- printk("UNKNOWN!\n");
- BUG();
- break;
- }
+ leon_smp_done();
}

void cpu_panic(void)
@@ -196,29 +174,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)

smp_store_cpu_info(boot_cpu_id);

- switch(sparc_cpu_model) {
- case sun4m:
- smp4m_boot_cpus();
- break;
- case sun4d:
- smp4d_boot_cpus();
- break;
- case sparc_leon:
- leon_boot_cpus();
- break;
- case sun4e:
- printk("SUN4E\n");
- BUG();
- break;
- case sun4u:
- printk("SUN4U\n");
- BUG();
- break;
- default:
- printk("UNKNOWN!\n");
- BUG();
- break;
- }
+ leon_boot_cpus();
}

/* Set this up early so that things like the scheduler can init
@@ -257,31 +213,7 @@ void __init smp_prepare_boot_cpu(void)

int __cpu_up(unsigned int cpu, struct task_struct *tidle)
{
- int ret=0;
-
- switch(sparc_cpu_model) {
- case sun4m:
- ret = smp4m_boot_one_cpu(cpu, tidle);
- break;
- case sun4d:
- ret = smp4d_boot_one_cpu(cpu, tidle);
- break;
- case sparc_leon:
- ret = leon_boot_one_cpu(cpu, tidle);
- break;
- case sun4e:
- printk("SUN4E\n");
- BUG();
- break;
- case sun4u:
- printk("SUN4U\n");
- BUG();
- break;
- default:
- printk("UNKNOWN!\n");
- BUG();
- break;
- }
+ int ret = leon_boot_one_cpu(cpu, tidle);

if (!ret) {
cpumask_set_cpu(cpu, &smp_commenced_mask);
@@ -296,19 +228,7 @@ static void arch_cpu_pre_starting(void *arg)
local_ops->cache_all();
local_ops->tlb_all();

- switch(sparc_cpu_model) {
- case sun4m:
- sun4m_cpu_pre_starting(arg);
- break;
- case sun4d:
- sun4d_cpu_pre_starting(arg);
- break;
- case sparc_leon:
- leon_cpu_pre_starting(arg);
- break;
- default:
- BUG();
- }
+ leon_cpu_pre_starting(arg);
}

static void arch_cpu_pre_online(void *arg)
@@ -323,19 +243,7 @@ static void arch_cpu_pre_online(void *arg)
local_ops->cache_all();
local_ops->tlb_all();

- switch(sparc_cpu_model) {
- case sun4m:
- sun4m_cpu_pre_online(arg);
- break;
- case sun4d:
- sun4d_cpu_pre_online(arg);
- break;
- case sparc_leon:
- leon_cpu_pre_online(arg);
- break;
- default:
- BUG();
- }
+ leon_cpu_pre_online(arg);
}

static void sparc_start_secondary(void *arg)
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
deleted file mode 100644
index cecdda746baa..000000000000
--- a/arch/sparc/kernel/sun4d_smp.c
+++ /dev/null
@@ -1,410 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Sparc SS1000/SC2000 SMP support.
- *
- * Copyright (C) 1998 Jakub Jelinek ([email protected])
- *
- * Based on sun4m's smp.c, which is:
- * Copyright (C) 1996 David S. Miller ([email protected])
- */
-
-#include <linux/clockchips.h>
-#include <linux/interrupt.h>
-#include <linux/profile.h>
-#include <linux/delay.h>
-#include <linux/sched/mm.h>
-#include <linux/cpu.h>
-
-#include <asm/cacheflush.h>
-#include <asm/switch_to.h>
-#include <asm/tlbflush.h>
-#include <asm/timer.h>
-#include <asm/oplib.h>
-#include <asm/sbi.h>
-#include <asm/mmu.h>
-
-#include "kernel.h"
-#include "irq.h"
-
-#define IRQ_CROSS_CALL 15
-
-static volatile int smp_processors_ready;
-static int smp_highest_cpu;
-
-static inline unsigned long sun4d_swap(volatile unsigned long *ptr, unsigned long val)
-{
- __asm__ __volatile__("swap [%1], %0\n\t" :
- "=&r" (val), "=&r" (ptr) :
- "0" (val), "1" (ptr));
- return val;
-}
-
-static void smp4d_ipi_init(void);
-
-static unsigned char cpu_leds[32];
-
-static inline void show_leds(int cpuid)
-{
- cpuid &= 0x1e;
- __asm__ __volatile__ ("stba %0, [%1] %2" : :
- "r" ((cpu_leds[cpuid] << 4) | cpu_leds[cpuid+1]),
- "r" (ECSR_BASE(cpuid) | BB_LEDS),
- "i" (ASI_M_CTL));
-}
-
-void sun4d_cpu_pre_starting(void *arg)
-{
- int cpuid = hard_smp_processor_id();
-
- /* Show we are alive */
- cpu_leds[cpuid] = 0x6;
- show_leds(cpuid);
-
- /* Enable level15 interrupt, disable level14 interrupt for now */
- cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000);
-}
-
-void sun4d_cpu_pre_online(void *arg)
-{
- unsigned long flags;
- int cpuid;
-
- cpuid = hard_smp_processor_id();
-
- /* Unblock the master CPU _only_ when the scheduler state
- * of all secondary CPUs will be up-to-date, so after
- * the SMP initialization the master will be just allowed
- * to call the scheduler code.
- */
- sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1);
- local_ops->cache_all();
- local_ops->tlb_all();
-
- while ((unsigned long)current_set[cpuid] < PAGE_OFFSET)
- barrier();
-
- while (current_set[cpuid]->cpu != cpuid)
- barrier();
-
- /* Fix idle thread fields. */
- __asm__ __volatile__("ld [%0], %%g6\n\t"
- : : "r" (&current_set[cpuid])
- : "memory" /* paranoid */);
-
- cpu_leds[cpuid] = 0x9;
- show_leds(cpuid);
-
- /* Attach to the address space of init_task. */
- mmgrab(&init_mm);
- current->active_mm = &init_mm;
-
- local_ops->cache_all();
- local_ops->tlb_all();
-
- while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
- barrier();
-
- spin_lock_irqsave(&sun4d_imsk_lock, flags);
- cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */
- spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
-}
-
-/*
- * Cycle through the processors asking the PROM to start each one.
- */
-void __init smp4d_boot_cpus(void)
-{
- smp4d_ipi_init();
- if (boot_cpu_id)
- current_set[0] = NULL;
- local_ops->cache_all();
-}
-
-int smp4d_boot_one_cpu(int i, struct task_struct *idle)
-{
- unsigned long *entry = &sun4d_cpu_startup;
- int timeout;
- int cpu_node;
-
- cpu_find_by_instance(i, &cpu_node, NULL);
- current_set[i] = task_thread_info(idle);
- /*
- * Initialize the contexts table
- * Since the call to prom_startcpu() trashes the structure,
- * we need to re-initialize it for each cpu
- */
- smp_penguin_ctable.which_io = 0;
- smp_penguin_ctable.phys_addr = (unsigned int) srmmu_ctx_table_phys;
- smp_penguin_ctable.reg_size = 0;
-
- /* whirrr, whirrr, whirrrrrrrrr... */
- printk(KERN_INFO "Starting CPU %d at %p\n", i, entry);
- local_ops->cache_all();
- prom_startcpu(cpu_node,
- &smp_penguin_ctable, 0, (char *)entry);
-
- printk(KERN_INFO "prom_startcpu returned :)\n");
-
- /* wheee... it's going... */
- for (timeout = 0; timeout < 10000; timeout++) {
- if (cpu_callin_map[i])
- break;
- udelay(200);
- }
-
- if (!(cpu_callin_map[i])) {
- printk(KERN_ERR "Processor %d is stuck.\n", i);
- return -ENODEV;
-
- }
- local_ops->cache_all();
- return 0;
-}
-
-void __init smp4d_smp_done(void)
-{
- int i, first;
- int *prev;
-
- /* setup cpu list for irq rotation */
- first = 0;
- prev = &first;
- for_each_online_cpu(i) {
- *prev = i;
- prev = &cpu_data(i).next;
- }
- *prev = first;
- local_ops->cache_all();
-
- /* Ok, they are spinning and ready to go. */
- smp_processors_ready = 1;
- sun4d_distribute_irqs();
-}
-
-/* Memory structure giving interrupt handler information about IPI generated */
-struct sun4d_ipi_work {
- int single;
- int msk;
- int resched;
-};
-
-static DEFINE_PER_CPU_SHARED_ALIGNED(struct sun4d_ipi_work, sun4d_ipi_work);
-
-/* Initialize IPIs on the SUN4D SMP machine */
-static void __init smp4d_ipi_init(void)
-{
- int cpu;
- struct sun4d_ipi_work *work;
-
- printk(KERN_INFO "smp4d: setup IPI at IRQ %d\n", SUN4D_IPI_IRQ);
-
- for_each_possible_cpu(cpu) {
- work = &per_cpu(sun4d_ipi_work, cpu);
- work->single = work->msk = work->resched = 0;
- }
-}
-
-void sun4d_ipi_interrupt(void)
-{
- struct sun4d_ipi_work *work = this_cpu_ptr(&sun4d_ipi_work);
-
- if (work->single) {
- work->single = 0;
- smp_call_function_single_interrupt();
- }
- if (work->msk) {
- work->msk = 0;
- smp_call_function_interrupt();
- }
- if (work->resched) {
- work->resched = 0;
- smp_resched_interrupt();
- }
-}
-
-/* +-------+-------------+-----------+------------------------------------+
- * | bcast | devid | sid | levels mask |
- * +-------+-------------+-----------+------------------------------------+
- * 31 30 23 22 15 14 0
- */
-#define IGEN_MESSAGE(bcast, devid, sid, levels) \
- (((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels))
-
-static void sun4d_send_ipi(int cpu, int level)
-{
- cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1)));
-}
-
-static void sun4d_ipi_single(int cpu)
-{
- struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
-
- /* Mark work */
- work->single = 1;
-
- /* Generate IRQ on the CPU */
- sun4d_send_ipi(cpu, SUN4D_IPI_IRQ);
-}
-
-static void sun4d_ipi_mask_one(int cpu)
-{
- struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
-
- /* Mark work */
- work->msk = 1;
-
- /* Generate IRQ on the CPU */
- sun4d_send_ipi(cpu, SUN4D_IPI_IRQ);
-}
-
-static void sun4d_ipi_resched(int cpu)
-{
- struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
-
- /* Mark work */
- work->resched = 1;
-
- /* Generate IRQ on the CPU (any IRQ will cause resched) */
- sun4d_send_ipi(cpu, SUN4D_IPI_IRQ);
-}
-
-static struct smp_funcall {
- smpfunc_t func;
- unsigned long arg1;
- unsigned long arg2;
- unsigned long arg3;
- unsigned long arg4;
- unsigned long arg5;
- unsigned char processors_in[NR_CPUS]; /* Set when ipi entered. */
- unsigned char processors_out[NR_CPUS]; /* Set when ipi exited. */
-} ccall_info __attribute__((aligned(8)));
-
-static DEFINE_SPINLOCK(cross_call_lock);
-
-/* Cross calls must be serialized, at least currently. */
-static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
- unsigned long arg2, unsigned long arg3,
- unsigned long arg4)
-{
- if (smp_processors_ready) {
- register int high = smp_highest_cpu;
- unsigned long flags;
-
- spin_lock_irqsave(&cross_call_lock, flags);
-
- {
- /*
- * If you make changes here, make sure
- * gcc generates proper code...
- */
- register smpfunc_t f asm("i0") = func;
- register unsigned long a1 asm("i1") = arg1;
- register unsigned long a2 asm("i2") = arg2;
- register unsigned long a3 asm("i3") = arg3;
- register unsigned long a4 asm("i4") = arg4;
- register unsigned long a5 asm("i5") = 0;
-
- __asm__ __volatile__(
- "std %0, [%6]\n\t"
- "std %2, [%6 + 8]\n\t"
- "std %4, [%6 + 16]\n\t" : :
- "r"(f), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5),
- "r" (&ccall_info.func));
- }
-
- /* Init receive/complete mapping, plus fire the IPI's off. */
- {
- register int i;
-
- cpumask_clear_cpu(smp_processor_id(), &mask);
- cpumask_and(&mask, cpu_online_mask, &mask);
- for (i = 0; i <= high; i++) {
- if (cpumask_test_cpu(i, &mask)) {
- ccall_info.processors_in[i] = 0;
- ccall_info.processors_out[i] = 0;
- sun4d_send_ipi(i, IRQ_CROSS_CALL);
- }
- }
- }
-
- {
- register int i;
-
- i = 0;
- do {
- if (!cpumask_test_cpu(i, &mask))
- continue;
- while (!ccall_info.processors_in[i])
- barrier();
- } while (++i <= high);
-
- i = 0;
- do {
- if (!cpumask_test_cpu(i, &mask))
- continue;
- while (!ccall_info.processors_out[i])
- barrier();
- } while (++i <= high);
- }
-
- spin_unlock_irqrestore(&cross_call_lock, flags);
- }
-}
-
-/* Running cross calls. */
-void smp4d_cross_call_irq(void)
-{
- int i = hard_smp_processor_id();
-
- ccall_info.processors_in[i] = 1;
- ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
- ccall_info.arg4, ccall_info.arg5);
- ccall_info.processors_out[i] = 1;
-}
-
-void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
-{
- struct pt_regs *old_regs;
- int cpu = hard_smp_processor_id();
- struct clock_event_device *ce;
- static int cpu_tick[NR_CPUS];
- static char led_mask[] = { 0xe, 0xd, 0xb, 0x7, 0xb, 0xd };
-
- old_regs = set_irq_regs(regs);
- bw_get_prof_limit(cpu);
- bw_clear_intr_mask(0, 1); /* INTR_TABLE[0] & 1 is Profile IRQ */
-
- cpu_tick[cpu]++;
- if (!(cpu_tick[cpu] & 15)) {
- if (cpu_tick[cpu] == 0x60)
- cpu_tick[cpu] = 0;
- cpu_leds[cpu] = led_mask[cpu_tick[cpu] >> 4];
- show_leds(cpu);
- }
-
- ce = &per_cpu(sparc32_clockevent, cpu);
-
- irq_enter();
- ce->event_handler(ce);
- irq_exit();
-
- set_irq_regs(old_regs);
-}
-
-static const struct sparc32_ipi_ops sun4d_ipi_ops = {
- .cross_call = sun4d_cross_call,
- .resched = sun4d_ipi_resched,
- .single = sun4d_ipi_single,
- .mask_one = sun4d_ipi_mask_one,
-};
-
-void __init sun4d_init_smp(void)
-{
- int i;
-
- sparc32_ipi_ops = &sun4d_ipi_ops;
-
- for (i = 0; i < NR_CPUS; i++) {
- ccall_info.processors_in[i] = 1;
- ccall_info.processors_out[i] = 1;
- }
-}
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
deleted file mode 100644
index 228a6527082d..000000000000
--- a/arch/sparc/kernel/sun4m_smp.c
+++ /dev/null
@@ -1,273 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * sun4m SMP support.
- *
- * Copyright (C) 1996 David S. Miller ([email protected])
- */
-
-#include <linux/clockchips.h>
-#include <linux/interrupt.h>
-#include <linux/profile.h>
-#include <linux/delay.h>
-#include <linux/sched/mm.h>
-#include <linux/cpu.h>
-
-#include <asm/cacheflush.h>
-#include <asm/switch_to.h>
-#include <asm/tlbflush.h>
-#include <asm/timer.h>
-#include <asm/oplib.h>
-
-#include "irq.h"
-#include "kernel.h"
-
-#define IRQ_IPI_SINGLE 12
-#define IRQ_IPI_MASK 13
-#define IRQ_IPI_RESCHED 14
-#define IRQ_CROSS_CALL 15
-
-static inline unsigned long
-swap_ulong(volatile unsigned long *ptr, unsigned long val)
-{
- __asm__ __volatile__("swap [%1], %0\n\t" :
- "=&r" (val), "=&r" (ptr) :
- "0" (val), "1" (ptr));
- return val;
-}
-
-void sun4m_cpu_pre_starting(void *arg)
-{
-}
-
-void sun4m_cpu_pre_online(void *arg)
-{
- int cpuid = hard_smp_processor_id();
-
- /* Allow master to continue. The master will then give us the
- * go-ahead by setting the smp_commenced_mask and will wait without
- * timeouts until our setup is completed fully (signified by
- * our bit being set in the cpu_online_mask).
- */
- swap_ulong(&cpu_callin_map[cpuid], 1);
-
- /* XXX: What's up with all the flushes? */
- local_ops->cache_all();
- local_ops->tlb_all();
-
- /* Fix idle thread fields. */
- __asm__ __volatile__("ld [%0], %%g6\n\t"
- : : "r" (&current_set[cpuid])
- : "memory" /* paranoid */);
-
- /* Attach to the address space of init_task. */
- mmgrab(&init_mm);
- current->active_mm = &init_mm;
-
- while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
- mb();
-}
-
-/*
- * Cycle through the processors asking the PROM to start each one.
- */
-void __init smp4m_boot_cpus(void)
-{
- sun4m_unmask_profile_irq();
- local_ops->cache_all();
-}
-
-int smp4m_boot_one_cpu(int i, struct task_struct *idle)
-{
- unsigned long *entry = &sun4m_cpu_startup;
- int timeout;
- int cpu_node;
-
- cpu_find_by_mid(i, &cpu_node);
- current_set[i] = task_thread_info(idle);
-
- /* See trampoline.S for details... */
- entry += ((i - 1) * 3);
-
- /*
- * Initialize the contexts table
- * Since the call to prom_startcpu() trashes the structure,
- * we need to re-initialize it for each cpu
- */
- smp_penguin_ctable.which_io = 0;
- smp_penguin_ctable.phys_addr = (unsigned int) srmmu_ctx_table_phys;
- smp_penguin_ctable.reg_size = 0;
-
- /* whirrr, whirrr, whirrrrrrrrr... */
- printk(KERN_INFO "Starting CPU %d at %p\n", i, entry);
- local_ops->cache_all();
- prom_startcpu(cpu_node, &smp_penguin_ctable, 0, (char *)entry);
-
- /* wheee... it's going... */
- for (timeout = 0; timeout < 10000; timeout++) {
- if (cpu_callin_map[i])
- break;
- udelay(200);
- }
-
- if (!(cpu_callin_map[i])) {
- printk(KERN_ERR "Processor %d is stuck.\n", i);
- return -ENODEV;
- }
-
- local_ops->cache_all();
- return 0;
-}
-
-void __init smp4m_smp_done(void)
-{
- int i, first;
- int *prev;
-
- /* setup cpu list for irq rotation */
- first = 0;
- prev = &first;
- for_each_online_cpu(i) {
- *prev = i;
- prev = &cpu_data(i).next;
- }
- *prev = first;
- local_ops->cache_all();
-
- /* Ok, they are spinning and ready to go. */
-}
-
-static void sun4m_send_ipi(int cpu, int level)
-{
- sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set);
-}
-
-static void sun4m_ipi_resched(int cpu)
-{
- sun4m_send_ipi(cpu, IRQ_IPI_RESCHED);
-}
-
-static void sun4m_ipi_single(int cpu)
-{
- sun4m_send_ipi(cpu, IRQ_IPI_SINGLE);
-}
-
-static void sun4m_ipi_mask_one(int cpu)
-{
- sun4m_send_ipi(cpu, IRQ_IPI_MASK);
-}
-
-static struct smp_funcall {
- smpfunc_t func;
- unsigned long arg1;
- unsigned long arg2;
- unsigned long arg3;
- unsigned long arg4;
- unsigned long arg5;
- unsigned long processors_in[SUN4M_NCPUS]; /* Set when ipi entered. */
- unsigned long processors_out[SUN4M_NCPUS]; /* Set when ipi exited. */
-} ccall_info;
-
-static DEFINE_SPINLOCK(cross_call_lock);
-
-/* Cross calls must be serialized, at least currently. */
-static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
- unsigned long arg2, unsigned long arg3,
- unsigned long arg4)
-{
- register int ncpus = SUN4M_NCPUS;
- unsigned long flags;
-
- spin_lock_irqsave(&cross_call_lock, flags);
-
- /* Init function glue. */
- ccall_info.func = func;
- ccall_info.arg1 = arg1;
- ccall_info.arg2 = arg2;
- ccall_info.arg3 = arg3;
- ccall_info.arg4 = arg4;
- ccall_info.arg5 = 0;
-
- /* Init receive/complete mapping, plus fire the IPI's off. */
- {
- register int i;
-
- cpumask_clear_cpu(smp_processor_id(), &mask);
- cpumask_and(&mask, cpu_online_mask, &mask);
- for (i = 0; i < ncpus; i++) {
- if (cpumask_test_cpu(i, &mask)) {
- ccall_info.processors_in[i] = 0;
- ccall_info.processors_out[i] = 0;
- sun4m_send_ipi(i, IRQ_CROSS_CALL);
- } else {
- ccall_info.processors_in[i] = 1;
- ccall_info.processors_out[i] = 1;
- }
- }
- }
-
- {
- register int i;
-
- i = 0;
- do {
- if (!cpumask_test_cpu(i, &mask))
- continue;
- while (!ccall_info.processors_in[i])
- barrier();
- } while (++i < ncpus);
-
- i = 0;
- do {
- if (!cpumask_test_cpu(i, &mask))
- continue;
- while (!ccall_info.processors_out[i])
- barrier();
- } while (++i < ncpus);
- }
- spin_unlock_irqrestore(&cross_call_lock, flags);
-}
-
-/* Running cross calls. */
-void smp4m_cross_call_irq(void)
-{
- int i = smp_processor_id();
-
- ccall_info.processors_in[i] = 1;
- ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
- ccall_info.arg4, ccall_info.arg5);
- ccall_info.processors_out[i] = 1;
-}
-
-void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
-{
- struct pt_regs *old_regs;
- struct clock_event_device *ce;
- int cpu = smp_processor_id();
-
- old_regs = set_irq_regs(regs);
-
- ce = &per_cpu(sparc32_clockevent, cpu);
-
- if (clockevent_state_periodic(ce))
- sun4m_clear_profile_irq(cpu);
- else
- sparc_config.load_profile_irq(cpu, 0); /* Is this needless? */
-
- irq_enter();
- ce->event_handler(ce);
- irq_exit();
-
- set_irq_regs(old_regs);
-}
-
-static const struct sparc32_ipi_ops sun4m_ipi_ops = {
- .cross_call = sun4m_cross_call,
- .resched = sun4m_ipi_resched,
- .single = sun4m_ipi_single,
- .mask_one = sun4m_ipi_mask_one,
-};
-
-void __init sun4m_init_smp(void)
-{
- sparc32_ipi_ops = &sun4m_ipi_ops;
-}
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index a03caa5f6628..d82cec45023a 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1818,14 +1818,8 @@ void __init load_mmu(void)
&smp_cachetlb_ops;
#endif

- if (sparc_cpu_model != sun4d)
- ld_mmu_iommu();
+ ld_mmu_iommu();
#ifdef CONFIG_SMP
- if (sparc_cpu_model == sun4d)
- sun4d_init_smp();
- else if (sparc_cpu_model == sparc_leon)
- leon_init_smp();
- else
- sun4m_init_smp();
+ leon_init_smp();
#endif
}
--
2.27.0

2020-12-18 20:48:05

by Jan Engelhardt

[permalink] [raw]
Subject: Re: [PATCH v1 01/13] sparc32: Drop sun4m/sun4d support from head_32.S


On Friday 2020-12-18 19:43, Sam Ravnborg wrote:
> notsup:
>- .asciz "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n"
>- .align 4
>-
>-sun4e_notsup:
>- .asciz "Sparc-Linux sun4e support does not exist\n\n"
>+ .asciz "Sparc-Linux sun4* or MMU-less not supported\n\n"
> .align 4

The asterisk may lead to a moment of bewilderment; sun4u/sun4v are still
supported.

2020-12-18 20:58:52

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v1 02/13] sparc32: Drop floppy support

On Fri, Dec 18, 2020 at 7:43 PM Sam Ravnborg <[email protected]> wrote:
>
> LEON do not have floppy support so we can drop it
>
> Signed-off-by: Sam Ravnborg <[email protected]>
> Cc: "David S. Miller" <[email protected]>
> Cc: Sam Ravnborg <[email protected]>
> Cc: Mike Rapoport <[email protected]>
> Cc: Andrew Morton <[email protected]>
> Cc: Denis Efremov <[email protected]>
> Cc: Willy Tarreau <[email protected]>
> Cc: Christian Brauner <[email protected]>
> Cc: [email protected]
> Cc: Arnd Bergmann <[email protected]>
> Cc: Andreas Larsson <[email protected]>
> ---
> arch/sparc/Kconfig | 2 +-
> arch/sparc/include/asm/floppy.h | 786 ++++++++++++++++++++++++++++-
> arch/sparc/include/asm/floppy_32.h | 393 ---------------
> arch/sparc/include/asm/floppy_64.h | 779 ----------------------------

Rather than renaming the floppy_64.h to floppy.h, it might be easier to just
remove the #else from floppy.h, similar to what asm/adi.h does.

This might be helpful in the (unlikely) case that someone has patches for
this file and wants to rebase them.

Arnd

2020-12-18 21:18:12

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH v1 02/13] sparc32: Drop floppy support

On Fri, Dec 18, 2020 at 09:57:47PM +0100, Arnd Bergmann wrote:
> On Fri, Dec 18, 2020 at 7:43 PM Sam Ravnborg <[email protected]> wrote:
> >
> > LEON do not have floppy support so we can drop it
> >
> > Signed-off-by: Sam Ravnborg <[email protected]>
> > Cc: "David S. Miller" <[email protected]>
> > Cc: Sam Ravnborg <[email protected]>
> > Cc: Mike Rapoport <[email protected]>
> > Cc: Andrew Morton <[email protected]>
> > Cc: Denis Efremov <[email protected]>
> > Cc: Willy Tarreau <[email protected]>
> > Cc: Christian Brauner <[email protected]>
> > Cc: [email protected]
> > Cc: Arnd Bergmann <[email protected]>
> > Cc: Andreas Larsson <[email protected]>
> > ---
> > arch/sparc/Kconfig | 2 +-
> > arch/sparc/include/asm/floppy.h | 786 ++++++++++++++++++++++++++++-
> > arch/sparc/include/asm/floppy_32.h | 393 ---------------
> > arch/sparc/include/asm/floppy_64.h | 779 ----------------------------
>
> Rather than renaming the floppy_64.h to floppy.h, it might be easier to just
> remove the #else from floppy.h, similar to what asm/adi.h does.
That is what I had first but then thought it pointless with a wrapper
file. I will revert back to use floppy_64.h for now - we can always
consolidate header files later.

Sam

2020-12-18 21:21:19

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH v1 01/13] sparc32: Drop sun4m/sun4d support from head_32.S

Hi Jan,

On Fri, Dec 18, 2020 at 07:52:08PM +0100, Jan Engelhardt wrote:
>
> On Friday 2020-12-18 19:43, Sam Ravnborg wrote:
> > notsup:
> >- .asciz "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n"
> >- .align 4
> >-
> >-sun4e_notsup:
> >- .asciz "Sparc-Linux sun4e support does not exist\n\n"
> >+ .asciz "Sparc-Linux sun4* or MMU-less not supported\n\n"
> > .align 4
>
> The asterisk may lead to a moment of bewilderment; sun4u/sun4v are still
> supported.
Noted, I will come up with something better.

Sam

2020-12-18 21:44:05

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [RFC PATCH 0/13] sparc32: sunset sun4m and sun4d

On Fri, Dec 18, 2020 at 7:43 PM Sam Ravnborg <[email protected]> wrote:
>
> The sun4m and sun4d based SPARC machines was very popular in the
> 90'ties and was then replaced by the more powerful sparc64
> class of machines.
> Today there is only Gentoo that to my best knowledge supports
> sparc32 and people have moved on to more capable HW.
>
> Cobham Gaisler have variants of the LEON processer that
> runs sparc32 - and they are in production today.
>
> With this patchset I propose to sunset sun4m and sun4d and move
> focus to a more streamlined support for LEON.
>
> One downside is that qemu supports sun4m - and we may loose
> some testing possibilities when sun4m is dropped. qemu supports
> LEON to some degree - I have not yet tried it out.
>
> Andreas from Gaisler have indicated that they may be more active
> upstream on sparc32 - and this will only be easier with a kernel
> where the legacy stuff is dropped.
>
> I decided to divide up the patches to make it possible to review
> the set as some of the patches touches assembler and these parts
> could use some extra eyes if we move forward with this.
>
> For now it builds with the configurations I have tried.

Thank you for doing this, it looks like a very nice cleanup.

> Looking forward for feedback if sunsetting is a good idea or not.

I have no insight on whether there are any users left that would miss
it, but I'm fairly sure that there are lots of people that would rather
see it gone.

> Note: I dunno why git does not see floppy_64.h=>floppy.h as a rename??

It doesn't do that if the old name existed already.

Arnd

2020-12-18 22:29:28

by Kjetil Oftedal

[permalink] [raw]
Subject: Re: [RFC PATCH 0/13] sparc32: sunset sun4m and sun4d

On 18/12/2020, Sam Ravnborg <[email protected]> wrote:
> The sun4m and sun4d based SPARC machines was very popular in the
> 90'ties and was then replaced by the more powerful sparc64
> class of machines.
> Today there is only Gentoo that to my best knowledge supports
> sparc32 and people have moved on to more capable HW.
>
> Cobham Gaisler have variants of the LEON processer that
> runs sparc32 - and they are in production today.
>
> With this patchset I propose to sunset sun4m and sun4d and move
> focus to a more streamlined support for LEON.
>
> One downside is that qemu supports sun4m - and we may loose
> some testing possibilities when sun4m is dropped. qemu supports
> LEON to some degree - I have not yet tried it out.
>
> Andreas from Gaisler have indicated that they may be more active
> upstream on sparc32 - and this will only be easier with a kernel
> where the legacy stuff is dropped.
>

This makes me a bit sad. But I guess I haven't had any time to put
into the sparc32 port
for many years, so I guess it is time to let go.

But I do believe that by doing this we should make sure we are not
putting ourselves
in a position where the sparc kernel-developers don't have access to
any real sparc32
hardware.

SUN machines were at least plentiful. The LEON-family of processors
being targeted
towards the rad-hardened market are not so much available.

Maybe Gaisler can contribute some systems, or make some available remotely?

Best regards,
Kjetil Oftedal

2020-12-19 21:43:50

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [RFC PATCH 0/13] sparc32: sunset sun4m and sun4d

Hi all,

On Fri, Dec 18, 2020 at 07:43:34PM +0100, Sam Ravnborg wrote:
> The sun4m and sun4d based SPARC machines was very popular in the
> 90'ties and was then replaced by the more powerful sparc64
> class of machines.

I have received a couple of mails in private.
One said it was better to sunset now when it is actually working,
so there is a working state to return to.
Another said that it would be a shame to sunset sun4m and sun4d because
there are so many machines around, and netbsd is also active on the
sparc32 area.


The second mail also re-reminded me of an interesting project
implementing SPARC V8 and the sun4m platform in VHDL.
See https://temlib.org - the author posted a new blog post a
few months ago.

temlib is, to my best knowledge, an impressive one-man project.
And this is not enough to keep sun4m around as this would
require real users that cannot just stay at their current kernel
but who need to follow upstream.

Please keep the inputs coming independent if you are pro or not
for the sunset of sun4m and sun4d.

Sam

Subject: Re: [RFC PATCH 0/13] sparc32: sunset sun4m and sun4d

On 12/19/20 10:40 PM, Sam Ravnborg wrote:
> Please keep the inputs coming independent if you are pro or not
> for the sunset of sun4m and sun4d.

I would personally be in favor of keeping it and I should finally get
my SPARCstation 5 up and running again.

Adrian

--
.''`. John Paul Adrian Glaubitz
: :' : Debian Developer - [email protected]
`. `' Freie Universitaet Berlin - [email protected]
`- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913

2020-12-20 07:46:37

by Romain Dolbeau

[permalink] [raw]
Subject: Re: [RFC PATCH 0/13] sparc32: sunset sun4m and sun4d

Le sam. 19 déc. 2020 à 22:41, Sam Ravnborg <[email protected]> a écrit :
> Another said that it would be a shame to sunset sun4m and sun4d because
> there are so many machines around, and netbsd is also active on the
> sparc32 area.

Yes, those were plentiful back in the day and there's still quite a few around.

> The second mail also re-reminded me of an interesting project
> implementing SPARC V8 and the sun4m platform in VHDL.

There's also new hardware being developed for SBus systems :-)
<https://github.com/rdolbeau/SBusFPGA>
(disclaimer: work-in-progress and shameless self-promotion here!).

If there's still a distribution willing to build for Sparc v8, then I
believe the kernel
should try to keep support of the relevant machine architectures if at all
possible...

Cordially,

--
Romain Dolbeau

2020-12-20 08:56:32

by Julian Calaby

[permalink] [raw]
Subject: Re: [RFC PATCH 0/13] sparc32: sunset sun4m and sun4d

Hi Romain, Sam,

On Sun, Dec 20, 2020 at 6:46 PM Romain Dolbeau <[email protected]> wrote:
>
> Le sam. 19 déc. 2020 à 22:41, Sam Ravnborg <[email protected]> a écrit :
> > Another said that it would be a shame to sunset sun4m and sun4d because
> > there are so many machines around, and netbsd is also active on the
> > sparc32 area.
>
> Yes, those were plentiful back in the day and there's still quite a few around.

I have three: two SparcStation 10s and a SparcStation LX.

If I want to run them, assuming the hardware still works, I need to
netboot them as I cannot find working, compatible HDDs for them as
everything has switched to SATA or SAS.

Then there's the issue of finding a monitor as they're not
electrically compatible with VGA and I'm pretty sure none of the VGA
compatible monitors I have or can lay hands on works with their
specific sync frequencies.

Ultimately it's one of those things where there's enough "stuff" in
the way that booting one up for fun is simply impractical and they're
old and slow enough that they're not useful for anything else.

Then we get to the not-so-significant issue of software...

> > The second mail also re-reminded me of an interesting project
> > implementing SPARC V8 and the sun4m platform in VHDL.
>
> There's also new hardware being developed for SBus systems :-)
> <https://github.com/rdolbeau/SBusFPGA>
> (disclaimer: work-in-progress and shameless self-promotion here!).

Interesting project!

Amusingly enough you're not the first to hook an FPGA up to sBus. I
had a card that was some form of high-speed sampling thing which was
effectively some electrically isolated front-end hooked to a Xylinx
FPGA. I ended up trashing it as it had no markings and I couldn't find
out anything about it.

> If there's still a distribution willing to build for Sparc v8, then I
> believe the kernel
> should try to keep support of the relevant machine architectures if at all
> possible...

And here's where the problem lies. The last (official) version of
Debian to support Sparc32 was Etch and I believe it was one of the
last ones to drop support.

I believe that Gentoo is architecture-neutral enough that it'd work,
but I believe that you'll have to compile everything - there'll be no
pre-built anything for sparc32 - and as it's fairly slow hardware by
today's standards, that's going to take a long time, however you could
probably use distcc and cross-compilers to speed it up.

Long painful story short, it's difficult to get the hardware running,
there's practically no Linux distros that support it, and the kernel
code has probably bitrotted due to lack of testing.

As much as it pains me to say this, I think this code's time has come
and it's time to get rid of it.

If there were more people using it or more testing, or more distros
supporting it - not just (theoretically?) working on it - then I'd be
fighting to keep it.

But there isn't.

I think it's time for it to go.

Thanks,

--
Julian Calaby

Email: [email protected]
Profile: http://www.google.com/profiles/julian.calaby/

On Sun, Dec 20, 2020 at 6:46 PM Romain Dolbeau <[email protected]> wrote:
>
> Le sam. 19 déc. 2020 à 22:41, Sam Ravnborg <[email protected]> a écrit :
> > Another said that it would be a shame to sunset sun4m and sun4d because
> > there are so many machines around, and netbsd is also active on the
> > sparc32 area.
>
> Yes, those were plentiful back in the day and there's still quite a few around.
>
> > The second mail also re-reminded me of an interesting project
> > implementing SPARC V8 and the sun4m platform in VHDL.
>
> There's also new hardware being developed for SBus systems :-)
> <https://github.com/rdolbeau/SBusFPGA>
> (disclaimer: work-in-progress and shameless self-promotion here!).
>
> If there's still a distribution willing to build for Sparc v8, then I
> believe the kernel
> should try to keep support of the relevant machine architectures if at all
> possible...
>
> Cordially,
>
> --
> Romain Dolbeau



--
Julian Calaby

Email: [email protected]
Profile: http://www.google.com/profiles/julian.calaby/

2020-12-20 09:30:22

by Romain Dolbeau

[permalink] [raw]
Subject: Re: [RFC PATCH 0/13] sparc32: sunset sun4m and sun4d

Le dim. 20 déc. 2020 à 09:54, Julian Calaby <[email protected]> a écrit :
> If I want to run them, assuming the hardware still works, I need to
> netboot them as I cannot find working, compatible HDDs for them as
> everything has switched to SATA or SAS.

SCSI2SD (<http://www.codesrc.com/mediawiki/index.php/SCSI2SD>)
are a bit expensive, but solve that problem (I own both a V5 and a V6,
both work well in my SPARCstations, tried sun4c and sun4m).
As it takes micro-sd cards, it's quite easy to keep multiple OSes
on hand.

> Then there's the issue of finding a monitor as they're not
> electrically compatible with VGA

Huh? There is Sun's 13W3-to-vga adapters and cables, and many
monitors will sync to Sun's frequency (though not the most recent
LCDs whose analog circuitry is pathetic compared to old-school
CRTs). Some framebuffers will output 1280x1024 (rarer than for
1152x900), and some can be coerced to do almost anything with
some Forth knowledge (see e.g.
<https://github.com/rdolbeau/SunTurboGX>, again blowing my
own horn here sorry...).

> (...) booting one up for fun is simply impractical

An SCSI2SD and either a null-modem serial cable or a
Sun keyboard/13w3 cable/17"LCD combo and you're good to
go. You might need another unix-like box to netboot the system.

> I believe that Gentoo is architecture-neutral enough that it'd work,
> but I believe that you'll have to compile everything - there'll be no
> pre-built anything for sparc32

Trying gentoo is on my todo list... has been for a long time :-(

> and as it's fairly slow hardware by
> today's standards, that's going to take a long time, however you could
> probably use distcc and cross-compilers to speed it up.

Isn't that what Qemu is for ? :-) I've managed to recompile LLVM
and clang in NetBSD 9 for my SS20, one by cross-compiling
(LLVM requires too much memory), the other in QEmu.
Unfortunately, Qemu doesn't yet support mt-tcg (multithreaded
emulation) for sparc so single-core only - still faster than the HW,
mostly because of incomparably faster I/O.

> If there were more people using it or more testing, or more distros
> supporting it - not just (theoretically?) working on it - then I'd be
> fighting to keep it.

I wish I had some arguments for that point... I will just re-mention Qemu,
as it makes testing quite easy and reasonably not-too-slow.

Cordially,

--
Romain Dolbeau

2020-12-20 09:56:02

by Julian Calaby

[permalink] [raw]
Subject: Re: [RFC PATCH 0/13] sparc32: sunset sun4m and sun4d

Hi Romain,

On Sun, Dec 20, 2020 at 8:26 PM Romain Dolbeau <[email protected]> wrote:
>
> Le dim. 20 déc. 2020 à 09:54, Julian Calaby <[email protected]> a écrit :
> > If I want to run them, assuming the hardware still works, I need to
> > netboot them as I cannot find working, compatible HDDs for them as
> > everything has switched to SATA or SAS.
>
> SCSI2SD (<http://www.codesrc.com/mediawiki/index.php/SCSI2SD>)
> are a bit expensive, but solve that problem (I own both a V5 and a V6,
> both work well in my SPARCstations, tried sun4c and sun4m).
> As it takes micro-sd cards, it's quite easy to keep multiple OSes
> on hand.

I'd forgotten about that. Fair point =)

> > Then there's the issue of finding a monitor as they're not
> > electrically compatible with VGA
>
> Huh? There is Sun's 13W3-to-vga adapters and cables, and many
> monitors will sync to Sun's frequency (though not the most recent
> LCDs whose analog circuitry is pathetic compared to old-school
> CRTs). Some framebuffers will output 1280x1024 (rarer than for
> 1152x900), and some can be coerced to do almost anything with
> some Forth knowledge (see e.g.
> <https://github.com/rdolbeau/SunTurboGX>, again blowing my
> own horn here sorry...).

Yeah, my issue is that I have no CRTs anymore - all my monitors are
LCDs and none of them sync to the frequencies SUNs use.

So yeah, you can make adapters (i have home-made adapters to convert
both ways) however out of the 4 monitors I own with VGA ports, none of
them sync to Sun frequencies.

> > (...) booting one up for fun is simply impractical
>
> An SCSI2SD and either a null-modem serial cable or a
> Sun keyboard/13w3 cable/17"LCD combo and you're good to
> go. You might need another unix-like box to netboot the system.

That's almost exactly what I was planning to do, but I'd still be
lacking a Linux distro to run.

> > I believe that Gentoo is architecture-neutral enough that it'd work,
> > but I believe that you'll have to compile everything - there'll be no
> > pre-built anything for sparc32
>
> Trying gentoo is on my todo list... has been for a long time :-(

Same.

IIRC there's some ancient versions that have the bits to netboot a
SparcStation so you can then do the necessary stuff to install the
minimal binaries and stuff, at which point you can do the various
configurations, pull in the latest portage tree and emerge world,
however the last time I tried this, the disk I was using - my last one
- failed somewhere in the middle of that process.

> > and as it's fairly slow hardware by
> > today's standards, that's going to take a long time, however you could
> > probably use distcc and cross-compilers to speed it up.
>
> Isn't that what Qemu is for ? :-) I've managed to recompile LLVM
> and clang in NetBSD 9 for my SS20, one by cross-compiling
> (LLVM requires too much memory), the other in QEmu.
> Unfortunately, Qemu doesn't yet support mt-tcg (multithreaded
> emulation) for sparc so single-core only - still faster than the HW,
> mostly because of incomparably faster I/O.

My distcc plan was to have it talk to a cross compiler on my x86
desktop. I never got to the point where it would have actually used
it.

> > If there were more people using it or more testing, or more distros
> > supporting it - not just (theoretically?) working on it - then I'd be
> > fighting to keep it.
>
> I wish I had some arguments for that point... I will just re-mention Qemu,
> as it makes testing quite easy and reasonably not-too-slow.

QEMU is somewhat slow and never _exactly_ the same as real hardware,
so I can see why distros might not use it as a build machine or
whatever. And if they do build for QEMU and it doesn't work on real
hardware, then we have a distro that's only for virtual hardware and
that seems pointless.

You're right that with the right bits and pieces resurrecting a
Sparc32 machine is relatively "easy", however there's still no modern
distros supporting this ancient hardware so the upstream kernel has
most likely bitrotted.

I still don't think it's worth saving.

Thanks,

--
Julian Calaby

Email: [email protected]
Profile: http://www.google.com/profiles/julian.calaby/

2020-12-20 14:26:53

by David Laight

[permalink] [raw]
Subject: RE: [RFC PATCH 0/13] sparc32: sunset sun4m and sun4d

From: Julian Calaby
> Sent: 20 December 2020 08:55
>
> On Sun, Dec 20, 2020 at 6:46 PM Romain Dolbeau <[email protected]> wrote:
> >
> > Le sam. 19 déc. 2020 à 22:41, Sam Ravnborg <[email protected]> a écrit :
> > > Another said that it would be a shame to sunset sun4m and sun4d because
> > > there are so many machines around, and netbsd is also active on the
> > > sparc32 area.

The advantage of netbsd is that the build gives you a kernel and userspace
from the same source tree and it is designed to cross build.
Even the compilers get built - so all you need is a native compiler
that will compile the (probably slightly older) version of gcc.
This used to be problematic because gcc sources tended to use gcc-only
features (which have been deprecated).

The userspace will also be a lot less bloated than a typical Linux,
but more complete than the 'busybox' tools often used on small/embedded
Linux systems.

> > Yes, those were plentiful back in the day and there's still quite a few around.
>
> I have three: two SparcStation 10s and a SparcStation LX.
>
> If I want to run them, assuming the hardware still works, I need to
> netboot them as I cannot find working, compatible HDDs for them as
> everything has switched to SATA or SAS.

I trashed the PSU on my sun3 trying to get netboot to work.
The main problem seemed to be that the switching fet wasn't
actually rated for 240v input! (needs to be a 400v device).

I never did get around to connecting an ATX psu up to the connector.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)