diff options
-rw-r--r-- | arch/mips/Makefile | 4 | ||||
-rw-r--r-- | arch/mips/config.in | 58 | ||||
-rw-r--r-- | arch/mips/defconfig | 75 | ||||
-rw-r--r-- | arch/mips/defconfig-atlas | 11 | ||||
-rw-r--r-- | arch/mips/defconfig-ddb5476 | 11 | ||||
-rw-r--r-- | arch/mips/defconfig-decstation | 75 | ||||
-rw-r--r-- | arch/mips/defconfig-ev64120 | 11 | ||||
-rw-r--r-- | arch/mips/defconfig-ev96100 | 11 | ||||
-rw-r--r-- | arch/mips/defconfig-ip22 | 75 | ||||
-rw-r--r-- | arch/mips/defconfig-it8172 | 11 | ||||
-rw-r--r-- | arch/mips/defconfig-malta | 11 | ||||
-rw-r--r-- | arch/mips/defconfig-ocelot | 11 | ||||
-rw-r--r-- | arch/mips/defconfig-rm200 | 11 | ||||
-rw-r--r-- | arch/mips/kernel/setup.c | 304 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 13 | ||||
-rw-r--r-- | arch/mips/ld.script.in | 1 | ||||
-rw-r--r-- | arch/mips/mm/extable.c | 3 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 7 | ||||
-rw-r--r-- | arch/mips/mm/loadmmu.c | 10 | ||||
-rw-r--r-- | arch/mips/mm/sb1.c | 436 | ||||
-rw-r--r-- | include/asm-mips/addrspace.h | 2 | ||||
-rw-r--r-- | include/asm-mips/atomic.h | 46 | ||||
-rw-r--r-- | include/asm-mips/bootinfo.h | 15 | ||||
-rw-r--r-- | include/asm-mips/cpu.h | 34 | ||||
-rw-r--r-- | include/asm-mips/current.h | 19 | ||||
-rw-r--r-- | include/asm-mips/pgtable.h | 20 | ||||
-rw-r--r-- | include/linux/tty_ldisc.h | 2 |
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. * |