summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-03-24 03:10:57 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-03-24 03:10:57 +0000
commit93f107ba6cceee2c35d207349976936da48393bc (patch)
treec33ea3d9e7e92245d6593b694cb514c8db5ff05d
parentf79c44e04169d10b07b53d4a524c8c41ea5504d5 (diff)
Add code to support the SB1 core, including mmu routines, processor
detection. This also tweaks cpu_probe() to use bits 15:8 of PRId as a company ID, as per the mips32/mips64 specs, and use bits 7:0 as the processor ID within the company. Patch from Justin with mods and some additional bits by me.
-rw-r--r--arch/mips/Makefile4
-rw-r--r--arch/mips/config.in58
-rw-r--r--arch/mips/defconfig75
-rw-r--r--arch/mips/defconfig-atlas11
-rw-r--r--arch/mips/defconfig-ddb547611
-rw-r--r--arch/mips/defconfig-decstation75
-rw-r--r--arch/mips/defconfig-ev6412011
-rw-r--r--arch/mips/defconfig-ev9610011
-rw-r--r--arch/mips/defconfig-ip2275
-rw-r--r--arch/mips/defconfig-it817211
-rw-r--r--arch/mips/defconfig-malta11
-rw-r--r--arch/mips/defconfig-ocelot11
-rw-r--r--arch/mips/defconfig-rm20011
-rw-r--r--arch/mips/kernel/setup.c304
-rw-r--r--arch/mips/kernel/traps.c13
-rw-r--r--arch/mips/ld.script.in1
-rw-r--r--arch/mips/mm/extable.c3
-rw-r--r--arch/mips/mm/init.c7
-rw-r--r--arch/mips/mm/loadmmu.c10
-rw-r--r--arch/mips/mm/sb1.c436
-rw-r--r--include/asm-mips/addrspace.h2
-rw-r--r--include/asm-mips/atomic.h46
-rw-r--r--include/asm-mips/bootinfo.h15
-rw-r--r--include/asm-mips/cpu.h34
-rw-r--r--include/asm-mips/current.h19
-rw-r--r--include/asm-mips/pgtable.h20
-rw-r--r--include/linux/tty_ldisc.h2
27 files changed, 1057 insertions, 230 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 867a70cab..52f136ef1 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -78,6 +78,9 @@ endif
ifdef CONFIG_CPU_RM7000
GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap
endif
+ifdef CONFIG_CPU_SB1
+GCCFLAGS += -mcpu=sb1 -mips2 -Wa,--trap
+endif
ifdef CONFIG_MIPS_FPU_EMULATOR
CORE_FILES +=arch/mips/math-emu/fpu_emulator.o
@@ -88,6 +91,7 @@ GCCFLAGS += -pipe
CFLAGS := -I $(TOPDIR)/include/asm/gcc $(CFLAGS) $(GCCFLAGS)
AFLAGS += $(GCCFLAGS)
+ASFLAGS += $(GCCFLAGS)
#
# Board-dependent options and extra files
diff --git a/arch/mips/config.in b/arch/mips/config.in
index 801b8c4c4..512789df6 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -200,6 +200,7 @@ choice 'CPU type' \
RM7000 CONFIG_CPU_RM7000 \
R52xx CONFIG_CPU_NEVADA \
R10000 CONFIG_CPU_R10000 \
+ SB1 CONFIG_CPU_SB1 \
MIPS32 CONFIG_CPU_MIPS32" R4x00
bool 'Override CPU Options' CONFIG_CPU_ADVANCED
@@ -341,53 +342,36 @@ if [ "$CONFIG_NET" = "y" ]; then
bool 'Network device support' CONFIG_NETDEVICES
if [ "$CONFIG_NETDEVICES" = "y" ]; then
-
- if [ "$CONFIG_SGI_IP22" != "y" -a \
- "$CONFIG_DECSTATION" != "y" -a \
- "$CONFIG_BAGET_MIPS" != "y" ]; then
-
- source drivers/net/Config.in
-
- if [ "$CONFIG_ATM" = "y" ]; then
- source drivers/atm/Config.in
- fi
- else
- tristate 'Dummy net driver support' CONFIG_DUMMY
- tristate 'SLIP (serial line) support' CONFIG_SLIP
- if [ "$CONFIG_SLIP" != "n" ]; then
- bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
- bool ' Keepalive and linefill' CONFIG_SLIP_SMART
- fi
- tristate 'PPP (point-to-point) support' CONFIG_PPP
- if [ ! "$CONFIG_PPP" = "n" ]; then
- comment 'CCP compressors for PPP are only built as modules.'
- fi
+ source drivers/net/Config.in
+ if [ "$CONFIG_ATM" = "y" ]; then
+ source drivers/atm/Config.in
fi
fi
endmenu
fi
-if [ "$CONFIG_ISA" = "y" -o "$CONFIG_PCI" = "y" ]; then
- mainmenu_option next_comment
- comment 'ISDN subsystem'
+source net/ax25/Config.in
- if [ "$CONFIG_NET" != "n" ]; then
- tristate 'ISDN support' CONFIG_ISDN
- if [ "$CONFIG_ISDN" != "n" ]; then
- source drivers/isdn/Config.in
- fi
+source net/irda/Config.in
+
+mainmenu_option next_comment
+comment 'ISDN subsystem'
+if [ "$CONFIG_NET" != "n" ]; then
+ tristate 'ISDN support' CONFIG_ISDN
+ if [ "$CONFIG_ISDN" != "n" ]; then
+ source drivers/isdn/Config.in
fi
- endmenu
+fi
+endmenu
- mainmenu_option next_comment
- comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+mainmenu_option next_comment
+comment 'Old CD-ROM drivers (not SCSI, not IDE)'
- bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
- if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
- source drivers/cdrom/Config.in
- fi
- endmenu
+bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+ source drivers/cdrom/Config.in
fi
+endmenu
if [ "$CONFIG_DECSTATION" != "y" -a \
"$CONFIG_SGI_IP22" != "y" ]; then
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index f6b4c9ca1..404d3ed4c 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -61,6 +61,7 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
# CONFIG_CPU_MIPS32 is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
@@ -231,9 +232,81 @@ CONFIG_SGIWD93_SCSI=y
# Network device support
#
CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
-# CONFIG_SLIP is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_SGISEEQ=y
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
#
# SGI Character devices
diff --git a/arch/mips/defconfig-atlas b/arch/mips/defconfig-atlas
index 277942218..bb8ef9a98 100644
--- a/arch/mips/defconfig-atlas
+++ b/arch/mips/defconfig-atlas
@@ -56,6 +56,7 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
# CONFIG_CPU_MIPS32 is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
@@ -311,6 +312,16 @@ CONFIG_NET_ETHERNET=y
# CONFIG_WAN is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
diff --git a/arch/mips/defconfig-ddb5476 b/arch/mips/defconfig-ddb5476
index 6cb031d5e..43a80745f 100644
--- a/arch/mips/defconfig-ddb5476
+++ b/arch/mips/defconfig-ddb5476
@@ -58,6 +58,7 @@ CONFIG_CPU_R5432=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
# CONFIG_CPU_MIPS32 is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
@@ -346,6 +347,16 @@ CONFIG_NE2K_PCI=y
# CONFIG_WAN is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
diff --git a/arch/mips/defconfig-decstation b/arch/mips/defconfig-decstation
index ffe757f27..f4e1e589a 100644
--- a/arch/mips/defconfig-decstation
+++ b/arch/mips/defconfig-decstation
@@ -57,6 +57,7 @@ CONFIG_CPU_R3000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
# CONFIG_CPU_MIPS32 is not set
# CONFIG_CPU_ADVANCED is not set
# CONFIG_CPU_HAS_LLSC is not set
@@ -224,9 +225,81 @@ CONFIG_SCSI_DECNCR=y
# Network device support
#
CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
-# CONFIG_SLIP is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_DECLANCE=y
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
#
# DECStation Character devices
diff --git a/arch/mips/defconfig-ev64120 b/arch/mips/defconfig-ev64120
index 6a2a709a8..e55bd11c5 100644
--- a/arch/mips/defconfig-ev64120
+++ b/arch/mips/defconfig-ev64120
@@ -63,6 +63,7 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
# CONFIG_CPU_MIPS32 is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
@@ -285,6 +286,16 @@ CONFIG_PPP_ASYNC=y
# CONFIG_WAN is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
diff --git a/arch/mips/defconfig-ev96100 b/arch/mips/defconfig-ev96100
index e27dd4b01..1f9a9a790 100644
--- a/arch/mips/defconfig-ev96100
+++ b/arch/mips/defconfig-ev96100
@@ -59,6 +59,7 @@ CONFIG_MODULES=y
CONFIG_CPU_RM7000=y
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
# CONFIG_CPU_MIPS32 is not set
CONFIG_CPU_ADVANCED=y
CONFIG_CPU_HAS_LLSC=y
@@ -276,6 +277,16 @@ CONFIG_TULIP=y
# CONFIG_WAN is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22
index f6b4c9ca1..404d3ed4c 100644
--- a/arch/mips/defconfig-ip22
+++ b/arch/mips/defconfig-ip22
@@ -61,6 +61,7 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
# CONFIG_CPU_MIPS32 is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
@@ -231,9 +232,81 @@ CONFIG_SGIWD93_SCSI=y
# Network device support
#
CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
-# CONFIG_SLIP is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_SGISEEQ=y
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
#
# SGI Character devices
diff --git a/arch/mips/defconfig-it8172 b/arch/mips/defconfig-it8172
index ff6b40996..c5ef3ca22 100644
--- a/arch/mips/defconfig-it8172
+++ b/arch/mips/defconfig-it8172
@@ -64,6 +64,7 @@ CONFIG_MODULES=y
# CONFIG_CPU_RM7000 is not set
CONFIG_CPU_NEVADA=y
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
# CONFIG_CPU_MIPS32 is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
@@ -406,6 +407,16 @@ CONFIG_8139TOO=y
# CONFIG_WAN is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
diff --git a/arch/mips/defconfig-malta b/arch/mips/defconfig-malta
index 770f2fc48..fa56febad 100644
--- a/arch/mips/defconfig-malta
+++ b/arch/mips/defconfig-malta
@@ -57,6 +57,7 @@ CONFIG_SWAP_IO_SPACE=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
CONFIG_CPU_MIPS32=y
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
@@ -335,6 +336,16 @@ CONFIG_PCNET32=y
# CONFIG_WAN is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
diff --git a/arch/mips/defconfig-ocelot b/arch/mips/defconfig-ocelot
index f468b324e..10d09bfad 100644
--- a/arch/mips/defconfig-ocelot
+++ b/arch/mips/defconfig-ocelot
@@ -57,6 +57,7 @@ CONFIG_SWAP_IO_SPACE=y
CONFIG_CPU_RM7000=y
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
# CONFIG_CPU_MIPS32 is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
@@ -273,6 +274,16 @@ CONFIG_EEPRO100=y
# CONFIG_WAN is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
diff --git a/arch/mips/defconfig-rm200 b/arch/mips/defconfig-rm200
index 3f3e8dfdf..14ab286f1 100644
--- a/arch/mips/defconfig-rm200
+++ b/arch/mips/defconfig-rm200
@@ -60,6 +60,7 @@ CONFIG_CPU_R5000=y
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_SB1 is not set
# CONFIG_CPU_MIPS32 is not set
# CONFIG_CPU_ADVANCED is not set
CONFIG_CPU_HAS_LLSC=y
@@ -200,6 +201,16 @@ CONFIG_INET=y
# CONFIG_NETDEVICES is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 4f12b01f5..52bf04548 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -46,7 +46,8 @@
#include <asm/sgialib.h>
#endif
-struct mips_cpuinfo boot_cpu_data = { NULL, NULL, 0 };
+
+struct mips_cpuinfo boot_cpu_data = { 0, NULL, NULL, 0 };
/*
* Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
@@ -169,152 +170,183 @@ int *cpuoptions = &mips_cpu.options;
static inline void cpu_probe(void)
{
+
+#ifdef CONFIG_CPU_MIPS32
unsigned long config1;
+#endif
mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID);
- switch (mips_cpu.processor_id & 0xff00) {
- case PRID_IMP_R2000:
- mips_cpu.cputype = CPU_R2000;
- mips_cpu.isa_level = MIPS_CPU_ISA_I;
- mips_cpu.options = MIPS_CPU_TLB;
- mips_cpu.tlbsize = 64;
- break;
- case PRID_IMP_R3000:
- if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A)
- if (cpu_has_confreg())
- mips_cpu.cputype = CPU_R3081E;
+ switch (mips_cpu.processor_id & 0xff0000) {
+ case PRID_COMP_LEGACY:
+ switch (mips_cpu.processor_id & 0xff00) {
+ case PRID_IMP_R2000:
+ mips_cpu.cputype = CPU_R2000;
+ mips_cpu.isa_level = MIPS_CPU_ISA_I;
+ mips_cpu.options = MIPS_CPU_TLB;
+ mips_cpu.tlbsize = 64;
+ break;
+ case PRID_IMP_R3000:
+ if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A)
+ if (cpu_has_confreg())
+ mips_cpu.cputype = CPU_R3081E;
+ else
+ mips_cpu.cputype = CPU_R3000A;
else
- mips_cpu.cputype = CPU_R3000A;
- else
- mips_cpu.cputype = CPU_R3000;
- mips_cpu.isa_level = MIPS_CPU_ISA_I;
- mips_cpu.options = MIPS_CPU_TLB;
- mips_cpu.tlbsize = 64;
- break;
- case PRID_IMP_R4000:
- if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400)
- mips_cpu.cputype = CPU_R4400SC;
- else
- mips_cpu.cputype = CPU_R4000SC;
- mips_cpu.isa_level = MIPS_CPU_ISA_III;
- mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
- MIPS_CPU_WATCH | MIPS_CPU_VCE;
- mips_cpu.tlbsize = 48;
- break;
- case PRID_IMP_R4600:
- mips_cpu.cputype = CPU_R4600;
- mips_cpu.isa_level = MIPS_CPU_ISA_III;
- mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
- mips_cpu.tlbsize = 48;
- break;
+ mips_cpu.cputype = CPU_R3000;
+ mips_cpu.isa_level = MIPS_CPU_ISA_I;
+ mips_cpu.options = MIPS_CPU_TLB;
+ mips_cpu.tlbsize = 64;
+ break;
+ case PRID_IMP_R4000:
+ if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400)
+ mips_cpu.cputype = CPU_R4400SC;
+ else
+ mips_cpu.cputype = CPU_R4000SC;
+ mips_cpu.isa_level = MIPS_CPU_ISA_III;
+ mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_WATCH | MIPS_CPU_VCE;
+ mips_cpu.tlbsize = 48;
+ break;
+ case PRID_IMP_R4600:
+ mips_cpu.cputype = CPU_R4600;
+ mips_cpu.isa_level = MIPS_CPU_ISA_III;
+ mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
+ mips_cpu.tlbsize = 48;
+ break;
/*
* This processor doesn't have an MMU, so it's not "real easy" to
* run Linux on it. It is left purely for documentation.
- *
- case PRID_IMP_R4650:
- mips_cpu.cputype = CPU_R4650;
- mips_cpu.isa_level = MIPS_CPU_ISA_III;
- mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
- mips_cpu.tlbsize = 48;
- break;
- */
- case PRID_IMP_R3912:
- mips_cpu.cputype = CPU_R3912;
- mips_cpu.isa_level = MIPS_CPU_ISA_I;
- mips_cpu.options = MIPS_CPU_TLB;
- mips_cpu.tlbsize = 32;
- break;
- case PRID_IMP_R4700:
- mips_cpu.cputype = CPU_R4700;
- mips_cpu.isa_level = MIPS_CPU_ISA_III;
- mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
- mips_cpu.tlbsize = 48;
- break;
- case PRID_IMP_R5000:
- mips_cpu.cputype = CPU_R5000;
- mips_cpu.isa_level = MIPS_CPU_ISA_IV;
- mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
- mips_cpu.tlbsize = 48;
- break;
- case PRID_IMP_R5432:
- mips_cpu.cputype = CPU_R5432;
- mips_cpu.isa_level = MIPS_CPU_ISA_IV;
- mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
- mips_cpu.tlbsize = 48;
- break;
- case PRID_IMP_NEVADA:
- mips_cpu.cputype = CPU_NEVADA;
- mips_cpu.isa_level = MIPS_CPU_ISA_IV;
- mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
- MIPS_CPU_DIVEC;
- mips_cpu.tlbsize = 48;
- mips_cpu.icache.ways = 2;
- mips_cpu.dcache.ways = 2;
- break;
- case PRID_IMP_R6000:
- mips_cpu.cputype = CPU_R6000;
- mips_cpu.isa_level = MIPS_CPU_ISA_II;
- mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
- mips_cpu.tlbsize = 32;
- break;
- case PRID_IMP_R6000A:
- mips_cpu.cputype = CPU_R6000A;
- mips_cpu.isa_level = MIPS_CPU_ISA_II;
- mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
- mips_cpu.tlbsize = 32;
- break;
- case PRID_IMP_RM7000:
- mips_cpu.cputype = CPU_RM7000;
- mips_cpu.isa_level = MIPS_CPU_ISA_IV;
- mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
- break;
- case PRID_IMP_R8000:
- mips_cpu.cputype = CPU_R8000;
- mips_cpu.isa_level = MIPS_CPU_ISA_IV;
- mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
- MIPS_CPU_FPU | MIPS_CPU_32FPR;
- mips_cpu.tlbsize = 384; /* has wierd TLB: 3-way x 128 */
- break;
- case PRID_IMP_R10000:
- mips_cpu.cputype = CPU_R10000;
- mips_cpu.isa_level = MIPS_CPU_ISA_IV;
- mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
- MIPS_CPU_FPU | MIPS_CPU_32FPR |
- MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
- mips_cpu.tlbsize = 64;
+ * case PRID_IMP_R4650:
+ mips_cpu.cputype = CPU_R4650;
+ mips_cpu.isa_level = MIPS_CPU_ISA_III;
+ mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
+ mips_cpu.tlbsize = 48;
+ break;
+*/
+ case PRID_IMP_R3912:
+ mips_cpu.cputype = CPU_R3912;
+ mips_cpu.isa_level = MIPS_CPU_ISA_I;
+ mips_cpu.options = MIPS_CPU_TLB;
+ mips_cpu.tlbsize = 32;
+ break;
+ case PRID_IMP_R4700:
+ mips_cpu.cputype = CPU_R4700;
+ mips_cpu.isa_level = MIPS_CPU_ISA_III;
+ mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+ mips_cpu.tlbsize = 48;
+ break;
+ case PRID_IMP_R5000:
+ mips_cpu.cputype = CPU_R5000;
+ mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+ mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+ mips_cpu.tlbsize = 48;
+ break;
+ case PRID_IMP_R5432:
+ mips_cpu.cputype = CPU_R5432;
+ mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+ mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+ mips_cpu.tlbsize = 48;
+ break;
+ case PRID_IMP_NEVADA:
+ mips_cpu.cputype = CPU_NEVADA;
+ mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+ mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_DIVEC;
+ mips_cpu.tlbsize = 48;
+ mips_cpu.icache.ways = 2;
+ mips_cpu.dcache.ways = 2;
+ break;
+ case PRID_IMP_R6000:
+ mips_cpu.cputype = CPU_R6000;
+ mips_cpu.isa_level = MIPS_CPU_ISA_II;
+ mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
+ mips_cpu.tlbsize = 32;
+ break;
+ case PRID_IMP_R6000A:
+ mips_cpu.cputype = CPU_R6000A;
+ mips_cpu.isa_level = MIPS_CPU_ISA_II;
+ mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
+ mips_cpu.tlbsize = 32;
+ break;
+ case PRID_IMP_RM7000:
+ mips_cpu.cputype = CPU_RM7000;
+ mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+ mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+ break;
+ case PRID_IMP_R8000:
+ mips_cpu.cputype = CPU_R8000;
+ mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+ mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+ MIPS_CPU_FPU | MIPS_CPU_32FPR;
+ mips_cpu.tlbsize = 384; /* has wierd TLB: 3-way x 128 */
+ break;
+ case PRID_IMP_R10000:
+ mips_cpu.cputype = CPU_R10000;
+ mips_cpu.cputype = MIPS_CPU_ISA_IV;
+ mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+ MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
+ mips_cpu.tlbsize = 64;
+ break;
+ default:
+ mips_cpu.cputype = CPU_UNKNOWN;
+ break;
+ }
break;
#ifdef CONFIG_CPU_MIPS32
- case PRID_IMP_4KC:
- mips_cpu.cputype = CPU_4KC;
- mips_cpu.isa_level = MIPS_CPU_ISA_M32;
- mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
- MIPS_CPU_4KTLB | MIPS_CPU_COUNTER |
- MIPS_CPU_DIVEC | MIPS_CPU_WATCH;
- config1 = read_mips32_cp0_config1();
- if (config1 & (1 << 3))
- mips_cpu.options |= MIPS_CPU_WATCH;
- if (config1 & (1 << 2))
- mips_cpu.options |= MIPS_CPU_MIPS16;
- if (config1 & 1)
- mips_cpu.options |= MIPS_CPU_FPU;
- mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
- break;
- case PRID_IMP_5KC:
- mips_cpu.cputype = CPU_5KC;
- mips_cpu.isa_level = MIPS_CPU_ISA_M64;
- mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
- MIPS_CPU_4KTLB | MIPS_CPU_COUNTER |
- MIPS_CPU_DIVEC | MIPS_CPU_WATCH;
- config1 = read_mips32_cp0_config1();
- if (config1 & (1 << 3))
- mips_cpu.options |= MIPS_CPU_WATCH;
- if (config1 & (1 << 2))
- mips_cpu.options |= MIPS_CPU_MIPS16;
- if (config1 & 1)
- mips_cpu.options |= MIPS_CPU_FPU;
- mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
+ case PRID_COMP_MIPS:
+ switch (mips_cpu.processor_id & 0xff00) {
+ case PRID_IMP_4KC:
+ mips_cpu.cputype = CPU_4KC;
+ /* Why do we set all these options by default, THEN query them?? */
+ mips_cpu.cputype = MIPS_CPU_ISA_M32;
+ mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER |
+ MIPS_CPU_DIVEC | MIPS_CPU_WATCH;
+ config1 = read_mips32_cp0_config1();
+ if (config1 & (1 << 3))
+ mips_cpu.options |= MIPS_CPU_WATCH;
+ if (config1 & (1 << 2))
+ mips_cpu.options |= MIPS_CPU_MIPS16;
+ if (config1 & 1)
+ mips_cpu.options |= MIPS_CPU_FPU;
+ mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
+ break;
+ case PRID_IMP_5KC:
+ mips_cpu.cputype = CPU_5KC;
+ mips_cpu.cputype = MIPS_CPU_ISA_M64;
+ /* See comment above about querying options */
+ mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER |
+ MIPS_CPU_DIVEC | MIPS_CPU_WATCH;
+ config1 = read_mips32_cp0_config1();
+ if (config1 & (1 << 3))
+ mips_cpu.options |= MIPS_CPU_WATCH;
+ if (config1 & (1 << 2))
+ mips_cpu.options |= MIPS_CPU_MIPS16;
+ if (config1 & 1)
+ mips_cpu.options |= MIPS_CPU_FPU;
+ break;
+ mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
+ default:
+ mips_cpu.cputype = CPU_UNKNOWN;
+ break;
+ }
break;
#endif
+ case PRID_COMP_SIBYTE:
+ switch (mips_cpu.processor_id & 0xff00) {
+ case PRID_IMP_SB1:
+ mips_cpu.cputype = CPU_SB1;
+ mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+ MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | MIPS_CPU_FPU |
+ MIPS_CPU_VCE;
+ break;
+ default:
+ mips_cpu.cputype = CPU_UNKNOWN;
+ break;
+ }
+ break;
default:
mips_cpu.cputype = CPU_UNKNOWN;
}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 363dfd778..e2c3663cb 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -791,7 +791,7 @@ void __init trap_init(void)
memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80);
memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
-
+ flush_icache_range(KSEG0 + 0x80, KSEG0 + 0x200);
/*
* Setup default vectors
*/
@@ -885,10 +885,21 @@ void __init trap_init(void)
*/
panic("CPU too expensive - making holiday in the ANDES!");
break;
+ case CPU_SB1:
+ /* XXX - This should be folded in to the "cleaner" handling, above */
+ memcpy((void *)KSEG0, &except_vec0_r4000, 0x80);
+ memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80);
+ save_fp_context = _save_fp_context;
+ restore_fp_context = _restore_fp_context;
+ /* Enable timer interrupt and scd mapped interrupt in status register */
+ clear_cp0_status(0xf000);
+ set_cp0_status(0xc00);
+ break;
case CPU_R6000:
case CPU_R6000A:
save_fp_context = _save_fp_context;
restore_fp_context = _restore_fp_context;
+
/*
* The R6000 is the only R-series CPU that features a machine
* check exception (similar to the R4000 cache error) and
diff --git a/arch/mips/ld.script.in b/arch/mips/ld.script.in
index 94b465b33..787c96d7a 100644
--- a/arch/mips/ld.script.in
+++ b/arch/mips/ld.script.in
@@ -91,6 +91,7 @@ SECTIONS
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata : { *(.sdata) }
+ . = ALIGN(4);
_edata = .;
PROVIDE (edata = .);
diff --git a/arch/mips/mm/extable.c b/arch/mips/mm/extable.c
index 72d4c9040..e563e8267 100644
--- a/arch/mips/mm/extable.c
+++ b/arch/mips/mm/extable.c
@@ -36,13 +36,14 @@ unsigned long
search_exception_table(unsigned long addr)
{
unsigned long ret = 0;
- unsigned long flags;
#ifndef CONFIG_MODULES
/* There is only the kernel to search. */
ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
return ret;
#else
+ unsigned long flags;
+
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index bcb25559c..7fa5c9582 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -130,9 +130,10 @@ static inline unsigned long setup_zero_pages(void)
{
unsigned long order, size;
struct page *page;
-
- if(mips_cpu.options & MIPS_CPU_VCE) order = 3;
- else order = 0;
+ if(mips_cpu.options & MIPS_CPU_VCE)
+ order = 3;
+ else
+ order = 0;
empty_zero_page = __get_free_pages(GFP_KERNEL, order);
if (!empty_zero_page)
diff --git a/arch/mips/mm/loadmmu.c b/arch/mips/mm/loadmmu.c
index 5bdcb38ab..69740ad78 100644
--- a/arch/mips/mm/loadmmu.c
+++ b/arch/mips/mm/loadmmu.c
@@ -45,6 +45,7 @@ extern void ld_mmu_r6000(void);
extern void ld_mmu_rm7k(void);
extern void ld_mmu_tfp(void);
extern void ld_mmu_andes(void);
+extern void ld_mmu_sb1(void);
extern void ld_mmu_mips32(void);
void __init loadmmu(void)
@@ -85,14 +86,19 @@ void __init loadmmu(void)
ld_mmu_r2300();
break;
#endif
-
+
#ifdef CONFIG_CPU_R10000
case CPU_R10000:
printk("Loading R10000 MMU routines.\n");
ld_mmu_andes();
break;
#endif
-
+#ifdef CONFIG_CPU_SB1
+ case CPU_SB1:
+ printk("Loading SB1 MMU routines.\n");
+ ld_mmu_sb1();
+ break;
+#endif
default:
panic("Yeee, unsupported mmu/cache architecture.");
}
diff --git a/arch/mips/mm/sb1.c b/arch/mips/mm/sb1.c
new file mode 100644
index 000000000..a5df1956f
--- /dev/null
+++ b/arch/mips/mm/sb1.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2000 Sibyte
+ *
+ * Written by Justin Carlson (carlson@sibyte.com)
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+/*
+ * In this entire file, I'm not sure what the role of the L2 on the sb1250
+ * is. Since it is coherent to the system, we should never need to flush
+ * it...right?...right??? -JDC
+ */
+
+#include <asm/mmu_context.h>
+
+/* These are probed at ld_mmu time */
+static unsigned int icache_size;
+static unsigned int dcache_size;
+
+static unsigned int icache_line_size;
+static unsigned int dcache_line_size;
+
+static unsigned int icache_assoc;
+static unsigned int dcache_assoc;
+
+static unsigned int icache_sets;
+static unsigned int dcache_sets;
+static unsigned int tlb_entries;
+
+void pgd_init(unsigned long page)
+{
+ unsigned long *p = (unsigned long *) page;
+ int i;
+
+ for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+ p[i + 0] = (unsigned long) invalid_pte_table;
+ p[i + 1] = (unsigned long) invalid_pte_table;
+ p[i + 2] = (unsigned long) invalid_pte_table;
+ p[i + 3] = (unsigned long) invalid_pte_table;
+ p[i + 4] = (unsigned long) invalid_pte_table;
+ p[i + 5] = (unsigned long) invalid_pte_table;
+ p[i + 6] = (unsigned long) invalid_pte_table;
+ p[i + 7] = (unsigned long) invalid_pte_table;
+ }
+}
+
+void flush_tlb_all(void)
+{
+ unsigned long flags;
+ unsigned long old_ctx;
+ int entry;
+
+ __save_and_cli(flags);
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = (get_entryhi() & 0xff);
+ set_entrylo0(0);
+ set_entrylo1(0);
+ for (entry = 0; entry < tlb_entries; entry++) {
+ set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry);
+ set_index(entry);
+ tlb_write_indexed();
+ }
+ set_entryhi(old_ctx);
+ __restore_flags(flags);
+}
+
+
+
+/* These are the functions hooked by the memory management function pointers */
+static void sb1_clear_page(void *page)
+{
+ /* JDCXXX - This should be bottlenecked by the write buffer, but these
+ things tend to be mildly unpredictable...should check this on the
+ performance model */
+
+ /* We prefetch 4 lines ahead. We're also "cheating" slightly here...
+ since we know we're on an SB1, we force the assembler to take
+ 64-bit operands to speed things up */
+ __asm__ __volatile__(
+ ".set push \n"
+ ".set noreorder \n"
+ ".set noat \n"
+ ".set mips4 \n"
+ " addiu $1, %0, %2 \n" /* Calculate the end of the page to clear */
+ " pref 5, 0(%0) \n" /* Prefetch the first 4 lines */
+ " pref 5, 32(%0) \n"
+ " pref 5, 64(%0) \n"
+ " pref 5, 96(%0) \n"
+ "1: sd $0, 0(%0) \n" /* Throw out a cacheline of 0's */
+ " sd $0, 8(%0) \n"
+ " sd $0, 16(%0) \n"
+ " sd $0, 24(%0) \n"
+ " pref 5,128(%0) \n" /* Prefetch 4 lines ahead */
+ " bne $1, %0, 1b \n"
+ " addiu %0, %0, 32 \n" /* Next cacheline (This instruction better be short piped!) */
+ ".set pop \n"
+ :"=r" (page)
+ :"0" (page),
+ "I" (PAGE_SIZE-32)
+ :"$1","memory");
+
+}
+
+static void sb1_copy_page(void *to, void *from)
+{
+
+ /* This should be optimized in assembly...can't use ld/sd, though,
+ * because the top 32 bits could be nuked if we took an interrupt
+ * during the routine. And this is not a good place to be cli()'ing
+ */
+
+ /* The pref's used here are using "streaming" hints, which cause the
+ * copied data to be kicked out of the cache sooner. A page copy often
+ * ends up copying a lot more data than is commonly used, so this seems
+ * to make sense in terms of reducing cache pollution, but I've no real
+ * performance data to back this up
+ */
+
+ __asm__ __volatile__(
+ ".set push \n"
+ ".set noreorder \n"
+ ".set noat \n"
+ ".set mips4 \n"
+ " addiu $1, %0, %4 \n" /* Calculate the end of the page to copy */
+ " pref 4, 0(%0) \n" /* Prefetch the first 3 lines to be read and copied */
+ " pref 5, 0(%1) \n"
+ " pref 4, 32(%0) \n"
+ " pref 5, 32(%1) \n"
+ " pref 4, 64(%0) \n"
+ " pref 5, 64(%1) \n"
+ "1: lw $2, 0(%0) \n" /* Block copy a cacheline */
+ " lw $3, 4(%0) \n"
+ " lw $4, 8(%0) \n"
+ " lw $5, 12(%0) \n"
+ " lw $6, 16(%0) \n"
+ " lw $7, 20(%0) \n"
+ " lw $8, 24(%0) \n"
+ " lw $9, 28(%0) \n"
+ " pref 4, 96(%0) \n" /* Prefetch ahead */
+ " pref 5, 96(%1) \n"
+ " sw $2, 0(%1) \n"
+ " sw $3, 4(%1) \n"
+ " sw $4, 8(%1) \n"
+ " sw $5, 12(%1) \n"
+ " sw $6, 16(%1) \n"
+ " sw $7, 20(%1) \n"
+ " sw $8, 24(%1) \n"
+ " sw $9, 28(%1) \n"
+ " addiu %1, %1, 32 \n" /* Next cacheline */
+ " nop \n" /* Force next add to short pipe */
+ " nop \n" /* Force next add to short pipe */
+ " bne $1, %0, 1b \n"
+ " addiu %0, %0, 32 \n" /* Next cacheline */
+ ".set pop \n"
+ :"=r" (to),
+ "=r" (from)
+ :
+ "0" (from),
+ "1" (to),
+ "I" (PAGE_SIZE-32)
+ :"$1","$2","$3","$4","$5","$6","$7","$8","$9","memory");
+/*
+ unsigned long *src = from;
+ unsigned long *dest = to;
+ unsigned long *target = (unsigned long *) (((unsigned long)src) + PAGE_SIZE);
+ while (src != target) {
+ *dest++ = *src++;
+ }
+*/
+}
+
+/*
+ * The dcache is fully coherent to the system, with one
+ * big caveat: the instruction stream. In other words,
+ * if we miss in the icache, and have dirty data in the
+ * L1 dcache, then we'll go out to memory (or the L2) and
+ * get the not-as-recent data.
+ *
+ * So the only time we have to flush the dcache is when
+ * we're flushing the icache. Since the L2 is fully
+ * coherent to everything, including I/O, we never have
+ * to flush it
+ */
+
+static void sb1_flush_cache_all(void)
+{
+
+ /*
+ * Haven't worried too much about speed here; given that we're flushing
+ * the icache, the time to invalidate is dwarfed by the time it's going
+ * to take to refill it. Register usage:
+ *
+ * $1 - moving cache index
+ * $2 - set count
+ */
+ if (icache_sets) {
+ __asm__ __volatile__ (
+ ".set push \n"
+ ".set noreorder \n"
+ ".set noat \n"
+ ".set mips4 \n"
+ " move $1, %2 \n" /* Start at index 0 */
+ "1: cache 0, 0($1) \n" /* Invalidate this index */
+ " addiu %1, %1, -1 \n" /* Decrement loop count */
+ " bnez %1, 1b \n" /* loop test */
+ " addu $1, $1, %0 \n" /* Next address JDCXXX - Should be short piped */
+ ".set pop \n"
+ ::"r" (icache_line_size),
+ "r" (icache_sets * icache_assoc),
+ "r" (KSEG0)
+ :"$1");
+ }
+ if (dcache_sets) {
+ __asm__ __volatile__ (
+ ".set push \n"
+ ".set noreorder \n"
+ ".set noat \n"
+ ".set mips4 \n"
+ " move $1, %2 \n" /* Start at index 0 */
+ "1: cache 0x1, 0($1) \n" /* WB/Invalidate this index */
+ " addiu %1, %1, -1 \n" /* Decrement loop count */
+ " bnez %1, 1b \n" /* loop test */
+ " addu $1, $1, %0 \n" /* Next address JDCXXX - Should be short piped */
+ ".set pop \n"
+ ::"r" (dcache_line_size),
+ "r" (dcache_sets * dcache_assoc),
+ "r" (KSEG0)
+ :"$1");
+ }
+}
+
+/*
+ * When flushing a range in the icache, we have to first writeback
+ * the dcache for the same range, so new ifetches will see any
+ * data that was dirty in the dcache
+ */
+
+static void sb1_flush_icache_range(unsigned long start, unsigned long end)
+{
+
+ /* JDCXXX - Implement me! */
+ sb1_flush_cache_all();
+}
+
+static void sb1_flush_cache_mm(struct mm_struct *mm)
+{
+ /* Don't need to do this, as the dcache is physically tagged */
+}
+
+static void sb1_flush_cache_range(struct mm_struct *mm,
+ unsigned long start,
+ unsigned long end)
+{
+ /* Don't need to do this, as the dcache is physically tagged */
+}
+
+
+static void sb1_flush_cache_sigtramp(unsigned long page)
+{
+ /* JDCXXX - Implement me! */
+ sb1_flush_cache_all();
+}
+
+
+/*
+ * This only needs to make sure stores done up to this
+ * point are visible to other agents outside the CPU. Given
+ * the coherent nature of the ZBus, all that's required here is
+ * a sync to make sure the data gets out to the caches and is
+ * visible to an arbitrary A Phase from an external agent
+ *
+ * Actually, I'm not even sure that's necessary; the semantics
+ * of this function aren't clear. If it's supposed to serve as
+ * a memory barrier, this is needed. If it's only meant to
+ * prevent data from being invisible to non-cpu memory accessors
+ * for some indefinite period of time (e.g. in a non-coherent
+ * dcache) then this function would be a complete nop.
+ */
+static void sb1_flush_page_to_ram(struct page *page)
+{
+ __asm__ __volatile__(
+ " sync \n" /* Short pipe */
+ :::"memory");
+}
+
+
+/* Cribbed from the r2300 code */
+static void sb1_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long page)
+{
+ sb1_flush_cache_all();
+#if 0
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long physpage;
+
+ /* No icache flush needed without context; */
+ if (mm->context == 0)
+ return;
+
+ /* No icache flush needed if the page isn't executable */
+ if (!(vma->vm_flags & VM_EXEC))
+ return;
+
+ physpage = (unsigned long) page_address(page);
+ if (physpage)
+ sb1_flush_icache_range(physpage, physpage + PAGE_SIZE);
+#endif
+}
+
+
+/*
+ * Cache set values (from the mips64 spec)
+ * 0 - 64
+ * 1 - 128
+ * 2 - 256
+ * 3 - 512
+ * 4 - 1024
+ * 5 - 2048
+ * 6 - 4096
+ * 7 - Reserved
+ */
+static unsigned int decode_cache_sets(unsigned int config_field)
+{
+ if (config_field == 7) {
+ /* JDCXXX - Find a graceful way to abort. */
+ return 0;
+ }
+
+ return (1<<(config_field + 6));
+}
+
+/*
+ * Cache line size values (from the mips64 spec)
+ * 0 - No cache present.
+ * 1 - 4 bytes
+ * 2 - 8 bytes
+ * 3 - 16 bytes
+ * 4 - 32 bytes
+ * 5 - 64 bytes
+ * 6 - 128 bytes
+ * 7 - Reserved
+ */
+static unsigned int decode_cache_line_size(unsigned int config_field)
+{
+ if (config_field == 0) {
+ return 0;
+ } else if (config_field == 7) {
+ /* JDCXXX - Find a graceful way to abort. */
+ return 0;
+ }
+ return (1<<(config_field + 1));
+}
+
+/*
+ * Relevant bits of the config1 register format (from the MIPS32/MIPS64 specs)
+ *
+ * 24:22 Icache sets per way
+ * 21:19 Icache line size
+ * 18:16 Icache Associativity
+ * 15:13 Dcache sets per way
+ * 12:10 Dcache line size
+ * 9:7 Dcache Associativity
+ */
+
+
+static void probe_cache_sizes(void)
+{
+ u32 config1;
+
+ __asm__ __volatile__(
+ ".set push \n"
+ ".set mips64 \n"
+ " mfc0 %0, $16, 1 \n" /* Get config1 register */
+ ".set pop \n"
+ :"=r" (config1));
+ icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7);
+ dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7);
+ icache_sets = decode_cache_sets((config1 >> 22) & 0x7);
+ dcache_sets = decode_cache_sets((config1 >> 13) & 0x7);
+ icache_assoc = ((config1 >> 16) & 0x7) + 1;
+ dcache_assoc = ((config1 >> 7) & 0x7) + 1;
+ icache_size = icache_line_size * icache_sets * icache_assoc;
+ dcache_size = dcache_line_size * dcache_sets * dcache_assoc;
+ tlb_entries = ((config1 >> 25) & 0x3f) + 1;
+}
+
+
+/* This is called from loadmmu.c. We have to set up all the
+ memory management function pointers, as well as initialize
+ the caches and tlbs */
+void ld_mmu_sb1(void)
+{
+ probe_cache_sizes();
+
+ _clear_page = sb1_clear_page;
+ _copy_page = sb1_copy_page;
+
+ _flush_cache_all = sb1_flush_cache_all;
+ _flush_cache_mm = sb1_flush_cache_mm;
+ _flush_cache_range = sb1_flush_cache_range;
+ _flush_cache_page = sb1_flush_cache_page;
+ _flush_cache_sigtramp = sb1_flush_cache_sigtramp;
+
+ _flush_page_to_ram = sb1_flush_page_to_ram;
+ _flush_icache_page = sb1_flush_cache_page;
+ _flush_icache_range = sb1_flush_icache_range;
+
+
+ /*
+ * JDCXXX I'm not sure whether these are necessary: is this the right
+ * place to initialize the tlb? If it is, why is it done
+ * at this level instead of as common code in loadmmu()?
+ */
+ flush_cache_all();
+ flush_tlb_all();
+
+ /* Turn on caching in kseg0 */
+ set_cp0_config(CONF_CM_CMASK, 0);
+}
diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h
index 45bd9ef3f..0d1bf3246 100644
--- a/include/asm-mips/addrspace.h
+++ b/include/asm-mips/addrspace.h
@@ -20,6 +20,8 @@
#define KSEG2 0xc0000000
#define KSEG3 0xe0000000
+#define K0BASE KSEG0
+
/*
* Returns the kernel segment base of a given address
*/
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 6bb29f1b7..12760cc3c 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -92,10 +92,10 @@ extern __inline__ void atomic_add(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
- "1:\tll\t%0, %1\t\t\t# atomic_add\n\t"
- "addu\t%0, %2\n\t"
- "sc\t%0, %1\n\t"
- "beqz\t%0, 1b"
+ "1: ll %0, %1 # atomic_add\n"
+ " addu %0, %2 \n"
+ " sc %0, %1 \n"
+ " beqz %0, 1b \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
}
@@ -105,10 +105,10 @@ extern __inline__ void atomic_sub(int i, atomic_t * v)
unsigned long temp;
__asm__ __volatile__(
- "1:\tll\t%0, %1\t\t\t# atomic_sub\n\t"
- "subu\t%0, %2\n\t"
- "sc\t%0, %1\n\t"
- "beqz\t%0, 1b"
+ "1: ll %0, %1 # atomic_sub\n"
+ " subu %0, %2 \n"
+ " sc %0, %1 \n"
+ " beqz %0, 1b \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));
}
@@ -121,13 +121,14 @@ extern __inline__ int atomic_add_return(int i, atomic_t * v)
unsigned long temp, result;
__asm__ __volatile__(
- ".set\tnoreorder\t\t\t# atomic_add_return\n"
- "1:\tll\t%1,%2\n\t"
- "addu\t%0,%1,%3\n\t"
- "sc\t%0,%2\n\t"
- "beqz\t%0,1b\n\t"
- "addu\t%0,%1,%3\n\t"
- ".set\treorder"
+ ".set push # atomic_add_return\n"
+ ".set noreorder \n"
+ "1: ll %1, %2 \n"
+ " addu %0, %1, %3 \n"
+ " sc %0, %2 \n"
+ " beqz %0, 1b \n"
+ " addu %0, %1, %3 \n"
+ ".set pop \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
@@ -140,13 +141,14 @@ extern __inline__ int atomic_sub_return(int i, atomic_t * v)
unsigned long temp, result;
__asm__ __volatile__(
- ".set\tnoreorder\t\t\t# atomic_sub_return\n"
- "1:\tll\t%1,%2\n\t"
- "subu\t%0,%1,%3\n\t"
- "sc\t%0,%2\n\t"
- "beqz\t%0,1b\n\t"
- "subu\t%0,%1,%3\n\t"
- ".set\treorder"
+ ".set push \n"
+ ".set noreorder # atomic_sub_return\n"
+ "1: ll %1, %2 \n"
+ " subu %0, %1, %3 \n"
+ " sc %0, %2 \n"
+ " beqz %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ ".set pop \r"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
: "memory");
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index 23710cbef..5d7b01020 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -28,10 +28,11 @@
#define MACH_GROUP_ITE 13 /* ITE Semi Eval Boards */
#define MACH_GROUP_PHILLIPS 14
#define MACH_GROUP_GLOBESPAN 15 /* Globespan PVR Referrence Board */
+#define MACH_GROUP_SIBYTE 16 /* Sibyte Eval Boards */
#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", "SNI", "ACN", \
"SGI", "Cobalt", "NEC DDB", "Baget", "Cosine", "Galileo", "Momentum", \
- "ITE", "Phillips", "Globepspan" }
+ "ITE", "Phillips", "Globepspan", "SiByte" }
/*
* Valid machtype values for group unknown (low order halfword of mips_machtype)
@@ -168,6 +169,13 @@
#define GROUP_PHILIPS_NAMES { "Nino" , "Velo" }
/*
+ * Valid machtype for group SIBYTE
+ */
+#define MACH_SWARM 0
+
+#define GROUP_SIBYTE_NAMES {"SWARM" }
+
+/*
* Valid cputype values
*/
#define CPU_UNKNOWN 0
@@ -204,14 +212,15 @@
#define CPU_5KC 31
#define CPU_R4310 32
#define CPU_R3912 33
-#define CPU_LAST 33
+#define CPU_SB1 34
+#define CPU_LAST 34
#define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \
"R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \
"R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000", \
"R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000", \
"R5000A", "R4640", "Nevada", "RM7000", "R5432", "MIPS 4Kc", \
- "MIPS 5Kc", "R4310", "R3912" }
+ "MIPS 5Kc", "R4310", "R3912", "SiByte SB1" }
#define COMMAND_LINE_SIZE 256
diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h
index 0d6db87bc..e5031ee38 100644
--- a/include/asm-mips/cpu.h
+++ b/include/asm-mips/cpu.h
@@ -8,11 +8,32 @@
#define _ASM_CPU_H
#include <asm/cache.h>
+/* Assigned Company values for bits 23:16 of the PRId Register
+ (CP0 register 15, select 0). As of the MIPS32 and MIPS64 specs from
+ MTI, the PRId register is defined in this (backwards compatible)
+ way:
+
+ +----------------+----------------+----------------+----------------+
+ | Company Options| Company ID | Processor ID | Revision |
+ +----------------+----------------+----------------+----------------+
+ 31 24 23 16 15 8 7
+
+ I don't have docs for all the previous processors, but my impression is
+ that bits 16-23 have been 0 for all MIPS processors before the MIPS32/64
+ spec.
+*/
+
+#define PRID_COMP_LEGACY 0x000000
+#define PRID_COMP_MIPS 0x010000
+/*
+ * Don't know who should be here...QED and Sandcraft, maybe?
+ */
+#define PRID_COMP_SIBYTE 0x040000
/*
* Assigned values for the product ID register. In order to detect a
* certain CPU type exactly eventually additional registers may need to
- * be examined.
+ * be examined. These are valid when 23:16 == PRID_COMP_LEGACY
*/
#define PRID_IMP_R2000 0x0100
#define PRID_IMP_R3000 0x0200 /* Same as R2000A */
@@ -40,6 +61,17 @@
#define PRID_IMP_UNKNOWN 0xff00
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
+ */
+
+#define PRID_IMP_SB1 0x0100
+
+/*
+ * Definitions for 7:0 on legacy processors
+ */
+
+
#define PRID_REV_R4400 0x0040
#define PRID_REV_R3000A 0x0030
#define PRID_REV_R3000 0x0020
diff --git a/include/asm-mips/current.h b/include/asm-mips/current.h
index 3015ce4bd..2c776757e 100644
--- a/include/asm-mips/current.h
+++ b/include/asm-mips/current.h
@@ -1,5 +1,4 @@
-/* $Id: current.h,v 1.5 1999/07/26 19:42:43 harald Exp $
- *
+/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
@@ -16,21 +15,5 @@
register struct task_struct *current asm("$28");
#endif /* _LANGUAGE_C */
-#ifdef _LANGUAGE_ASSEMBLY
-
-/*
- * Special variant for use by exception handlers when the stack pointer
- * is not loaded.
- */
-#define _GET_CURRENT(reg) \
- lui reg, %hi(kernelsp); \
- .set push; \
- .set reorder; \
- lw reg, %lo(kernelsp)(reg); \
- .set pop; \
- ori reg, 8191; \
- xori reg, 8191
-
-#endif
#endif /* _ASM_CURRENT_H */
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index 25666e99f..4018ba883 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -130,13 +130,25 @@ extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
#define _CACHE_CACHABLE_NONCOHERENT 0
#else
-
#define _PAGE_R4KBUG (1<<5) /* workaround for r4k bug */
#define _PAGE_GLOBAL (1<<6)
#define _PAGE_VALID (1<<7)
#define _PAGE_SILENT_READ (1<<7) /* synonym */
#define _PAGE_DIRTY (1<<8) /* The MIPS dirty bit */
#define _PAGE_SILENT_WRITE (1<<8)
+#define _CACHE_MASK (7<<9)
+
+#if defined(CONFIG_CPU_SB1)
+
+/* No penalty for being coherent on the SB1, so just
+ use it for "noncoherent" spaces, too. Shouldn't hurt. */
+
+#define _CACHE_UNCACHED (2<<9)
+#define _CACHE_CACHABLE_COW (5<<9)
+#define _CACHE_CACHABLE_NONCOHERENT (5<<9)
+
+#else
+
#define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */
#define _CACHE_CACHABLE_WA (1<<9) /* R4600 only */
#define _CACHE_UNCACHED (2<<9) /* R4[0246]00 */
@@ -145,9 +157,9 @@ extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
#define _CACHE_CACHABLE_COW (5<<9) /* R4[04]00 only */
#define _CACHE_CACHABLE_CUW (6<<9) /* R4[04]00 only */
#define _CACHE_CACHABLE_ACCELERATED (7<<9) /* R10000 only */
-#define _CACHE_MASK (7<<9)
#endif
+#endif
#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
@@ -157,8 +169,12 @@ extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
#ifdef CONFIG_MIPS_UNCACHED
#define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED
#else
+#ifdef CONFIG_CPU_SB1
+#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW
+#else
#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT
#endif
+#endif
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index 501ea0765..028ce04a2 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -35,7 +35,7 @@
* unsigned char * buf, size_t nr);
*
* This function is called when the user requests to read from
- * the tty. The line discpline will return whatever characters
+ * the tty. The line discipline will return whatever characters
* it has buffered up for the user. If this function is not
* defined, the user will receive an EIO error.
*