diff options
90 files changed, 5835 insertions, 1416 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 0cb6f5ffeecd..033ffd0abe2c 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -336,6 +336,7 @@ config MIPS_SEAD3 | |||
336 | select BOOT_RAW | 336 | select BOOT_RAW |
337 | select CEVT_R4K | 337 | select CEVT_R4K |
338 | select CSRC_R4K | 338 | select CSRC_R4K |
339 | select CSRC_GIC | ||
339 | select CPU_MIPSR2_IRQ_VI | 340 | select CPU_MIPSR2_IRQ_VI |
340 | select CPU_MIPSR2_IRQ_EI | 341 | select CPU_MIPSR2_IRQ_EI |
341 | select DMA_NONCOHERENT | 342 | select DMA_NONCOHERENT |
@@ -352,6 +353,7 @@ config MIPS_SEAD3 | |||
352 | select SYS_SUPPORTS_BIG_ENDIAN | 353 | select SYS_SUPPORTS_BIG_ENDIAN |
353 | select SYS_SUPPORTS_LITTLE_ENDIAN | 354 | select SYS_SUPPORTS_LITTLE_ENDIAN |
354 | select SYS_SUPPORTS_SMARTMIPS | 355 | select SYS_SUPPORTS_SMARTMIPS |
356 | select SYS_SUPPORTS_MICROMIPS | ||
355 | select USB_ARCH_HAS_EHCI | 357 | select USB_ARCH_HAS_EHCI |
356 | select USB_EHCI_BIG_ENDIAN_DESC | 358 | select USB_EHCI_BIG_ENDIAN_DESC |
357 | select USB_EHCI_BIG_ENDIAN_MMIO | 359 | select USB_EHCI_BIG_ENDIAN_MMIO |
@@ -908,6 +910,9 @@ config CEVT_GT641XX | |||
908 | config CEVT_R4K | 910 | config CEVT_R4K |
909 | bool | 911 | bool |
910 | 912 | ||
913 | config CEVT_GIC | ||
914 | bool | ||
915 | |||
911 | config CEVT_SB1250 | 916 | config CEVT_SB1250 |
912 | bool | 917 | bool |
913 | 918 | ||
@@ -1824,6 +1829,15 @@ config FORCE_MAX_ZONEORDER | |||
1824 | The page size is not necessarily 4KB. Keep this in mind | 1829 | The page size is not necessarily 4KB. Keep this in mind |
1825 | when choosing a value for this option. | 1830 | when choosing a value for this option. |
1826 | 1831 | ||
1832 | config CEVT_GIC | ||
1833 | bool "Use GIC global counter for clock events" | ||
1834 | depends on IRQ_GIC && !(MIPS_SEAD3 || MIPS_MT_SMTC) | ||
1835 | help | ||
1836 | Use the GIC global counter for the clock events. The R4K clock | ||
1837 | event driver is always present, so if the platform ends up not | ||
1838 | detecting a GIC, it will fall back to the R4K timer for the | ||
1839 | generation of clock events. | ||
1840 | |||
1827 | config BOARD_SCACHE | 1841 | config BOARD_SCACHE |
1828 | bool | 1842 | bool |
1829 | 1843 | ||
@@ -2048,6 +2062,13 @@ config CPU_HAS_SMARTMIPS | |||
2048 | you don't know you probably don't have SmartMIPS and should say N | 2062 | you don't know you probably don't have SmartMIPS and should say N |
2049 | here. | 2063 | here. |
2050 | 2064 | ||
2065 | config CPU_MICROMIPS | ||
2066 | depends on SYS_SUPPORTS_MICROMIPS | ||
2067 | bool "Build kernel using microMIPS ISA" | ||
2068 | help | ||
2069 | When this option is enabled the kernel will be built using the | ||
2070 | microMIPS ISA | ||
2071 | |||
2051 | config CPU_HAS_WB | 2072 | config CPU_HAS_WB |
2052 | bool | 2073 | bool |
2053 | 2074 | ||
@@ -2110,6 +2131,9 @@ config SYS_SUPPORTS_HIGHMEM | |||
2110 | config SYS_SUPPORTS_SMARTMIPS | 2131 | config SYS_SUPPORTS_SMARTMIPS |
2111 | bool | 2132 | bool |
2112 | 2133 | ||
2134 | config SYS_SUPPORTS_MICROMIPS | ||
2135 | bool | ||
2136 | |||
2113 | config ARCH_FLATMEM_ENABLE | 2137 | config ARCH_FLATMEM_ENABLE |
2114 | def_bool y | 2138 | def_bool y |
2115 | depends on !NUMA && !CPU_LOONGSON2 | 2139 | depends on !NUMA && !CPU_LOONGSON2 |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 6f7978f95090..dd58a04ef4bc 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -114,6 +114,7 @@ cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*e | |||
114 | cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le)) | 114 | cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le)) |
115 | 115 | ||
116 | cflags-$(CONFIG_CPU_HAS_SMARTMIPS) += $(call cc-option,-msmartmips) | 116 | cflags-$(CONFIG_CPU_HAS_SMARTMIPS) += $(call cc-option,-msmartmips) |
117 | cflags-$(CONFIG_CPU_MICROMIPS) += $(call cc-option,-mmicromips -mno-jals) | ||
117 | 118 | ||
118 | cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \ | 119 | cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \ |
119 | -fno-omit-frame-pointer | 120 | -fno-omit-frame-pointer |
diff --git a/arch/mips/ar7/memory.c b/arch/mips/ar7/memory.c index 28abfeef09d6..92dfa481205b 100644 --- a/arch/mips/ar7/memory.c +++ b/arch/mips/ar7/memory.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <asm/sections.h> | 30 | #include <asm/sections.h> |
31 | 31 | ||
32 | #include <asm/mach-ar7/ar7.h> | 32 | #include <asm/mach-ar7/ar7.h> |
33 | #include <asm/mips-boards/prom.h> | ||
34 | 33 | ||
35 | static int __init memsize(void) | 34 | static int __init memsize(void) |
36 | { | 35 | { |
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index cd732e5b4fd5..ce1d3eeeb737 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig | |||
@@ -2,30 +2,21 @@ CONFIG_MIPS_MALTA=y | |||
2 | CONFIG_CPU_LITTLE_ENDIAN=y | 2 | CONFIG_CPU_LITTLE_ENDIAN=y |
3 | CONFIG_CPU_MIPS32_R2=y | 3 | CONFIG_CPU_MIPS32_R2=y |
4 | CONFIG_MIPS_MT_SMP=y | 4 | CONFIG_MIPS_MT_SMP=y |
5 | CONFIG_NO_HZ=y | ||
6 | CONFIG_HIGH_RES_TIMERS=y | ||
7 | CONFIG_HZ_100=y | 5 | CONFIG_HZ_100=y |
8 | CONFIG_EXPERIMENTAL=y | ||
9 | CONFIG_SYSVIPC=y | 6 | CONFIG_SYSVIPC=y |
7 | CONFIG_NO_HZ=y | ||
8 | CONFIG_HIGH_RES_TIMERS=y | ||
10 | CONFIG_LOG_BUF_SHIFT=15 | 9 | CONFIG_LOG_BUF_SHIFT=15 |
11 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
12 | CONFIG_RELAY=y | ||
13 | CONFIG_NAMESPACES=y | 10 | CONFIG_NAMESPACES=y |
14 | CONFIG_UTS_NS=y | 11 | CONFIG_RELAY=y |
15 | CONFIG_IPC_NS=y | ||
16 | CONFIG_PID_NS=y | ||
17 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
18 | CONFIG_EXPERT=y | 12 | CONFIG_EXPERT=y |
19 | # CONFIG_SYSCTL_SYSCALL is not set | ||
20 | # CONFIG_COMPAT_BRK is not set | 13 | # CONFIG_COMPAT_BRK is not set |
21 | CONFIG_SLAB=y | 14 | CONFIG_SLAB=y |
22 | CONFIG_MODULES=y | 15 | CONFIG_MODULES=y |
23 | CONFIG_MODULE_UNLOAD=y | 16 | CONFIG_MODULE_UNLOAD=y |
24 | CONFIG_MODVERSIONS=y | 17 | CONFIG_MODVERSIONS=y |
25 | CONFIG_MODULE_SRCVERSION_ALL=y | 18 | CONFIG_MODULE_SRCVERSION_ALL=y |
26 | # CONFIG_BLK_DEV_BSG is not set | ||
27 | CONFIG_PCI=y | 19 | CONFIG_PCI=y |
28 | CONFIG_PM=y | ||
29 | CONFIG_PACKET=y | 20 | CONFIG_PACKET=y |
30 | CONFIG_UNIX=y | 21 | CONFIG_UNIX=y |
31 | CONFIG_XFRM_USER=m | 22 | CONFIG_XFRM_USER=m |
@@ -41,8 +32,6 @@ CONFIG_IP_PNP=y | |||
41 | CONFIG_IP_PNP_DHCP=y | 32 | CONFIG_IP_PNP_DHCP=y |
42 | CONFIG_IP_PNP_BOOTP=y | 33 | CONFIG_IP_PNP_BOOTP=y |
43 | CONFIG_NET_IPIP=m | 34 | CONFIG_NET_IPIP=m |
44 | CONFIG_NET_IPGRE=m | ||
45 | CONFIG_NET_IPGRE_BROADCAST=y | ||
46 | CONFIG_IP_MROUTE=y | 35 | CONFIG_IP_MROUTE=y |
47 | CONFIG_IP_PIMSM_V1=y | 36 | CONFIG_IP_PIMSM_V1=y |
48 | CONFIG_IP_PIMSM_V2=y | 37 | CONFIG_IP_PIMSM_V2=y |
@@ -65,7 +54,6 @@ CONFIG_IPV6_MROUTE=y | |||
65 | CONFIG_IPV6_PIMSM_V2=y | 54 | CONFIG_IPV6_PIMSM_V2=y |
66 | CONFIG_NETWORK_SECMARK=y | 55 | CONFIG_NETWORK_SECMARK=y |
67 | CONFIG_NETFILTER=y | 56 | CONFIG_NETFILTER=y |
68 | CONFIG_NETFILTER_NETLINK_QUEUE=m | ||
69 | CONFIG_NF_CONNTRACK=m | 57 | CONFIG_NF_CONNTRACK=m |
70 | CONFIG_NF_CONNTRACK_SECMARK=y | 58 | CONFIG_NF_CONNTRACK_SECMARK=y |
71 | CONFIG_NF_CONNTRACK_EVENTS=y | 59 | CONFIG_NF_CONNTRACK_EVENTS=y |
@@ -136,23 +124,15 @@ CONFIG_IP_VS_DH=m | |||
136 | CONFIG_IP_VS_SH=m | 124 | CONFIG_IP_VS_SH=m |
137 | CONFIG_IP_VS_SED=m | 125 | CONFIG_IP_VS_SED=m |
138 | CONFIG_IP_VS_NQ=m | 126 | CONFIG_IP_VS_NQ=m |
139 | CONFIG_IP_VS_FTP=m | ||
140 | CONFIG_NF_CONNTRACK_IPV4=m | 127 | CONFIG_NF_CONNTRACK_IPV4=m |
141 | CONFIG_IP_NF_QUEUE=m | 128 | CONFIG_IP_NF_QUEUE=m |
142 | CONFIG_IP_NF_IPTABLES=m | 129 | CONFIG_IP_NF_IPTABLES=m |
143 | CONFIG_IP_NF_MATCH_ADDRTYPE=m | ||
144 | CONFIG_IP_NF_MATCH_AH=m | 130 | CONFIG_IP_NF_MATCH_AH=m |
145 | CONFIG_IP_NF_MATCH_ECN=m | 131 | CONFIG_IP_NF_MATCH_ECN=m |
146 | CONFIG_IP_NF_MATCH_TTL=m | 132 | CONFIG_IP_NF_MATCH_TTL=m |
147 | CONFIG_IP_NF_FILTER=m | 133 | CONFIG_IP_NF_FILTER=m |
148 | CONFIG_IP_NF_TARGET_REJECT=m | 134 | CONFIG_IP_NF_TARGET_REJECT=m |
149 | CONFIG_IP_NF_TARGET_LOG=m | ||
150 | CONFIG_IP_NF_TARGET_ULOG=m | 135 | CONFIG_IP_NF_TARGET_ULOG=m |
151 | CONFIG_NF_NAT=m | ||
152 | CONFIG_IP_NF_TARGET_MASQUERADE=m | ||
153 | CONFIG_IP_NF_TARGET_NETMAP=m | ||
154 | CONFIG_IP_NF_TARGET_REDIRECT=m | ||
155 | CONFIG_NF_NAT_SNMP_BASIC=m | ||
156 | CONFIG_IP_NF_MANGLE=m | 136 | CONFIG_IP_NF_MANGLE=m |
157 | CONFIG_IP_NF_TARGET_CLUSTERIP=m | 137 | CONFIG_IP_NF_TARGET_CLUSTERIP=m |
158 | CONFIG_IP_NF_TARGET_ECN=m | 138 | CONFIG_IP_NF_TARGET_ECN=m |
@@ -162,8 +142,6 @@ CONFIG_IP_NF_ARPTABLES=m | |||
162 | CONFIG_IP_NF_ARPFILTER=m | 142 | CONFIG_IP_NF_ARPFILTER=m |
163 | CONFIG_IP_NF_ARP_MANGLE=m | 143 | CONFIG_IP_NF_ARP_MANGLE=m |
164 | CONFIG_NF_CONNTRACK_IPV6=m | 144 | CONFIG_NF_CONNTRACK_IPV6=m |
165 | CONFIG_IP6_NF_QUEUE=m | ||
166 | CONFIG_IP6_NF_IPTABLES=m | ||
167 | CONFIG_IP6_NF_MATCH_AH=m | 145 | CONFIG_IP6_NF_MATCH_AH=m |
168 | CONFIG_IP6_NF_MATCH_EUI64=m | 146 | CONFIG_IP6_NF_MATCH_EUI64=m |
169 | CONFIG_IP6_NF_MATCH_FRAG=m | 147 | CONFIG_IP6_NF_MATCH_FRAG=m |
@@ -173,7 +151,6 @@ CONFIG_IP6_NF_MATCH_IPV6HEADER=m | |||
173 | CONFIG_IP6_NF_MATCH_MH=m | 151 | CONFIG_IP6_NF_MATCH_MH=m |
174 | CONFIG_IP6_NF_MATCH_RT=m | 152 | CONFIG_IP6_NF_MATCH_RT=m |
175 | CONFIG_IP6_NF_TARGET_HL=m | 153 | CONFIG_IP6_NF_TARGET_HL=m |
176 | CONFIG_IP6_NF_TARGET_LOG=m | ||
177 | CONFIG_IP6_NF_FILTER=m | 154 | CONFIG_IP6_NF_FILTER=m |
178 | CONFIG_IP6_NF_TARGET_REJECT=m | 155 | CONFIG_IP6_NF_TARGET_REJECT=m |
179 | CONFIG_IP6_NF_MANGLE=m | 156 | CONFIG_IP6_NF_MANGLE=m |
@@ -247,12 +224,10 @@ CONFIG_MAC80211=m | |||
247 | CONFIG_MAC80211_RC_PID=y | 224 | CONFIG_MAC80211_RC_PID=y |
248 | CONFIG_MAC80211_RC_DEFAULT_PID=y | 225 | CONFIG_MAC80211_RC_DEFAULT_PID=y |
249 | CONFIG_MAC80211_MESH=y | 226 | CONFIG_MAC80211_MESH=y |
250 | CONFIG_MAC80211_LEDS=y | ||
251 | CONFIG_RFKILL=m | 227 | CONFIG_RFKILL=m |
252 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 228 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
253 | CONFIG_CONNECTOR=m | 229 | CONFIG_CONNECTOR=m |
254 | CONFIG_MTD=y | 230 | CONFIG_MTD=y |
255 | CONFIG_MTD_PARTITIONS=y | ||
256 | CONFIG_MTD_CHAR=y | 231 | CONFIG_MTD_CHAR=y |
257 | CONFIG_MTD_BLOCK=y | 232 | CONFIG_MTD_BLOCK=y |
258 | CONFIG_MTD_OOPS=m | 233 | CONFIG_MTD_OOPS=m |
@@ -271,7 +246,6 @@ CONFIG_BLK_DEV_NBD=m | |||
271 | CONFIG_BLK_DEV_RAM=y | 246 | CONFIG_BLK_DEV_RAM=y |
272 | CONFIG_CDROM_PKTCDVD=m | 247 | CONFIG_CDROM_PKTCDVD=m |
273 | CONFIG_ATA_OVER_ETH=m | 248 | CONFIG_ATA_OVER_ETH=m |
274 | # CONFIG_MISC_DEVICES is not set | ||
275 | CONFIG_IDE=y | 249 | CONFIG_IDE=y |
276 | CONFIG_BLK_DEV_IDECD=y | 250 | CONFIG_BLK_DEV_IDECD=y |
277 | CONFIG_IDE_GENERIC=y | 251 | CONFIG_IDE_GENERIC=y |
@@ -317,13 +291,19 @@ CONFIG_DM_MIRROR=m | |||
317 | CONFIG_DM_ZERO=m | 291 | CONFIG_DM_ZERO=m |
318 | CONFIG_DM_MULTIPATH=m | 292 | CONFIG_DM_MULTIPATH=m |
319 | CONFIG_NETDEVICES=y | 293 | CONFIG_NETDEVICES=y |
320 | CONFIG_IFB=m | ||
321 | CONFIG_DUMMY=m | ||
322 | CONFIG_BONDING=m | 294 | CONFIG_BONDING=m |
323 | CONFIG_MACVLAN=m | 295 | CONFIG_DUMMY=m |
324 | CONFIG_EQUALIZER=m | 296 | CONFIG_EQUALIZER=m |
297 | CONFIG_IFB=m | ||
298 | CONFIG_MACVLAN=m | ||
325 | CONFIG_TUN=m | 299 | CONFIG_TUN=m |
326 | CONFIG_VETH=m | 300 | CONFIG_VETH=m |
301 | # CONFIG_NET_VENDOR_3COM is not set | ||
302 | CONFIG_PCNET32=y | ||
303 | CONFIG_CHELSIO_T3=m | ||
304 | CONFIG_AX88796=m | ||
305 | CONFIG_NETXEN_NIC=m | ||
306 | CONFIG_TC35815=m | ||
327 | CONFIG_MARVELL_PHY=m | 307 | CONFIG_MARVELL_PHY=m |
328 | CONFIG_DAVICOM_PHY=m | 308 | CONFIG_DAVICOM_PHY=m |
329 | CONFIG_QSEMI_PHY=m | 309 | CONFIG_QSEMI_PHY=m |
@@ -334,14 +314,6 @@ CONFIG_SMSC_PHY=m | |||
334 | CONFIG_BROADCOM_PHY=m | 314 | CONFIG_BROADCOM_PHY=m |
335 | CONFIG_ICPLUS_PHY=m | 315 | CONFIG_ICPLUS_PHY=m |
336 | CONFIG_REALTEK_PHY=m | 316 | CONFIG_REALTEK_PHY=m |
337 | CONFIG_MDIO_BITBANG=m | ||
338 | CONFIG_NET_ETHERNET=y | ||
339 | CONFIG_AX88796=m | ||
340 | CONFIG_NET_PCI=y | ||
341 | CONFIG_PCNET32=y | ||
342 | CONFIG_TC35815=m | ||
343 | CONFIG_CHELSIO_T3=m | ||
344 | CONFIG_NETXEN_NIC=m | ||
345 | CONFIG_ATMEL=m | 317 | CONFIG_ATMEL=m |
346 | CONFIG_PCI_ATMEL=m | 318 | CONFIG_PCI_ATMEL=m |
347 | CONFIG_PRISM54=m | 319 | CONFIG_PRISM54=m |
@@ -352,15 +324,7 @@ CONFIG_HOSTAP_PLX=m | |||
352 | CONFIG_HOSTAP_PCI=m | 324 | CONFIG_HOSTAP_PCI=m |
353 | CONFIG_IPW2100=m | 325 | CONFIG_IPW2100=m |
354 | CONFIG_IPW2100_MONITOR=y | 326 | CONFIG_IPW2100_MONITOR=y |
355 | CONFIG_IPW2200=m | ||
356 | CONFIG_IPW2200_MONITOR=y | ||
357 | CONFIG_IPW2200_PROMISCUOUS=y | ||
358 | CONFIG_IPW2200_QOS=y | ||
359 | CONFIG_LIBERTAS=m | 327 | CONFIG_LIBERTAS=m |
360 | CONFIG_HERMES=m | ||
361 | CONFIG_PLX_HERMES=m | ||
362 | CONFIG_TMD_HERMES=m | ||
363 | CONFIG_NORTEL_HERMES=m | ||
364 | # CONFIG_INPUT_KEYBOARD is not set | 328 | # CONFIG_INPUT_KEYBOARD is not set |
365 | # CONFIG_INPUT_MOUSE is not set | 329 | # CONFIG_INPUT_MOUSE is not set |
366 | # CONFIG_SERIO_I8042 is not set | 330 | # CONFIG_SERIO_I8042 is not set |
@@ -373,12 +337,6 @@ CONFIG_FB_CIRRUS=y | |||
373 | # CONFIG_VGA_CONSOLE is not set | 337 | # CONFIG_VGA_CONSOLE is not set |
374 | CONFIG_FRAMEBUFFER_CONSOLE=y | 338 | CONFIG_FRAMEBUFFER_CONSOLE=y |
375 | CONFIG_HID=m | 339 | CONFIG_HID=m |
376 | CONFIG_LEDS_CLASS=y | ||
377 | CONFIG_LEDS_TRIGGER_TIMER=m | ||
378 | CONFIG_LEDS_TRIGGER_IDE_DISK=y | ||
379 | CONFIG_LEDS_TRIGGER_HEARTBEAT=m | ||
380 | CONFIG_LEDS_TRIGGER_BACKLIGHT=m | ||
381 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=m | ||
382 | CONFIG_RTC_CLASS=y | 340 | CONFIG_RTC_CLASS=y |
383 | CONFIG_RTC_DRV_CMOS=y | 341 | CONFIG_RTC_DRV_CMOS=y |
384 | CONFIG_UIO=m | 342 | CONFIG_UIO=m |
@@ -398,7 +356,6 @@ CONFIG_XFS_QUOTA=y | |||
398 | CONFIG_XFS_POSIX_ACL=y | 356 | CONFIG_XFS_POSIX_ACL=y |
399 | CONFIG_QUOTA=y | 357 | CONFIG_QUOTA=y |
400 | CONFIG_QFMT_V2=y | 358 | CONFIG_QFMT_V2=y |
401 | CONFIG_AUTOFS_FS=y | ||
402 | CONFIG_FUSE_FS=m | 359 | CONFIG_FUSE_FS=m |
403 | CONFIG_ISO9660_FS=m | 360 | CONFIG_ISO9660_FS=m |
404 | CONFIG_JOLIET=y | 361 | CONFIG_JOLIET=y |
@@ -425,7 +382,6 @@ CONFIG_ROMFS_FS=m | |||
425 | CONFIG_SYSV_FS=m | 382 | CONFIG_SYSV_FS=m |
426 | CONFIG_UFS_FS=m | 383 | CONFIG_UFS_FS=m |
427 | CONFIG_NFS_FS=y | 384 | CONFIG_NFS_FS=y |
428 | CONFIG_NFS_V3=y | ||
429 | CONFIG_ROOT_NFS=y | 385 | CONFIG_ROOT_NFS=y |
430 | CONFIG_NFSD=y | 386 | CONFIG_NFSD=y |
431 | CONFIG_NFSD_V3=y | 387 | CONFIG_NFSD_V3=y |
@@ -466,7 +422,6 @@ CONFIG_NLS_ISO8859_14=m | |||
466 | CONFIG_NLS_ISO8859_15=m | 422 | CONFIG_NLS_ISO8859_15=m |
467 | CONFIG_NLS_KOI8_R=m | 423 | CONFIG_NLS_KOI8_R=m |
468 | CONFIG_NLS_KOI8_U=m | 424 | CONFIG_NLS_KOI8_U=m |
469 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
470 | CONFIG_CRYPTO_NULL=m | 425 | CONFIG_CRYPTO_NULL=m |
471 | CONFIG_CRYPTO_CRYPTD=m | 426 | CONFIG_CRYPTO_CRYPTD=m |
472 | CONFIG_CRYPTO_LRW=m | 427 | CONFIG_CRYPTO_LRW=m |
diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig new file mode 100644 index 000000000000..93057a760dfa --- /dev/null +++ b/arch/mips/configs/maltaaprp_defconfig | |||
@@ -0,0 +1,195 @@ | |||
1 | CONFIG_MIPS_MALTA=y | ||
2 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
3 | CONFIG_CPU_MIPS32_R2=y | ||
4 | CONFIG_MIPS_VPE_LOADER=y | ||
5 | CONFIG_MIPS_VPE_APSP_API=y | ||
6 | CONFIG_HZ_100=y | ||
7 | CONFIG_LOCALVERSION="aprp" | ||
8 | CONFIG_SYSVIPC=y | ||
9 | CONFIG_POSIX_MQUEUE=y | ||
10 | CONFIG_AUDIT=y | ||
11 | CONFIG_IKCONFIG=y | ||
12 | CONFIG_IKCONFIG_PROC=y | ||
13 | CONFIG_LOG_BUF_SHIFT=15 | ||
14 | CONFIG_SYSCTL_SYSCALL=y | ||
15 | CONFIG_EMBEDDED=y | ||
16 | CONFIG_SLAB=y | ||
17 | CONFIG_MODULES=y | ||
18 | CONFIG_MODULE_UNLOAD=y | ||
19 | CONFIG_MODVERSIONS=y | ||
20 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
21 | # CONFIG_BLK_DEV_BSG is not set | ||
22 | CONFIG_PCI=y | ||
23 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
24 | CONFIG_NET=y | ||
25 | CONFIG_PACKET=y | ||
26 | CONFIG_UNIX=y | ||
27 | CONFIG_XFRM_USER=m | ||
28 | CONFIG_NET_KEY=y | ||
29 | CONFIG_INET=y | ||
30 | CONFIG_IP_MULTICAST=y | ||
31 | CONFIG_IP_ADVANCED_ROUTER=y | ||
32 | CONFIG_IP_MULTIPLE_TABLES=y | ||
33 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
34 | CONFIG_IP_ROUTE_VERBOSE=y | ||
35 | CONFIG_IP_PNP=y | ||
36 | CONFIG_IP_PNP_DHCP=y | ||
37 | CONFIG_IP_PNP_BOOTP=y | ||
38 | CONFIG_NET_IPIP=m | ||
39 | CONFIG_IP_MROUTE=y | ||
40 | CONFIG_IP_PIMSM_V1=y | ||
41 | CONFIG_IP_PIMSM_V2=y | ||
42 | CONFIG_SYN_COOKIES=y | ||
43 | CONFIG_INET_AH=m | ||
44 | CONFIG_INET_ESP=m | ||
45 | CONFIG_INET_IPCOMP=m | ||
46 | # CONFIG_INET_LRO is not set | ||
47 | CONFIG_IPV6_PRIVACY=y | ||
48 | CONFIG_INET6_AH=m | ||
49 | CONFIG_INET6_ESP=m | ||
50 | CONFIG_INET6_IPCOMP=m | ||
51 | CONFIG_IPV6_TUNNEL=m | ||
52 | CONFIG_BRIDGE=m | ||
53 | CONFIG_VLAN_8021Q=m | ||
54 | CONFIG_ATALK=m | ||
55 | CONFIG_DEV_APPLETALK=m | ||
56 | CONFIG_IPDDP=m | ||
57 | CONFIG_IPDDP_ENCAP=y | ||
58 | CONFIG_IPDDP_DECAP=y | ||
59 | CONFIG_NET_SCHED=y | ||
60 | CONFIG_NET_SCH_CBQ=m | ||
61 | CONFIG_NET_SCH_HTB=m | ||
62 | CONFIG_NET_SCH_HFSC=m | ||
63 | CONFIG_NET_SCH_PRIO=m | ||
64 | CONFIG_NET_SCH_RED=m | ||
65 | CONFIG_NET_SCH_SFQ=m | ||
66 | CONFIG_NET_SCH_TEQL=m | ||
67 | CONFIG_NET_SCH_TBF=m | ||
68 | CONFIG_NET_SCH_GRED=m | ||
69 | CONFIG_NET_SCH_DSMARK=m | ||
70 | CONFIG_NET_SCH_NETEM=m | ||
71 | CONFIG_NET_SCH_INGRESS=m | ||
72 | CONFIG_NET_CLS_BASIC=m | ||
73 | CONFIG_NET_CLS_TCINDEX=m | ||
74 | CONFIG_NET_CLS_ROUTE4=m | ||
75 | CONFIG_NET_CLS_FW=m | ||
76 | CONFIG_NET_CLS_U32=m | ||
77 | CONFIG_NET_CLS_RSVP=m | ||
78 | CONFIG_NET_CLS_RSVP6=m | ||
79 | CONFIG_NET_CLS_ACT=y | ||
80 | CONFIG_NET_ACT_POLICE=y | ||
81 | CONFIG_NET_CLS_IND=y | ||
82 | # CONFIG_WIRELESS is not set | ||
83 | CONFIG_BLK_DEV_LOOP=y | ||
84 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
85 | CONFIG_IDE=y | ||
86 | # CONFIG_IDE_PROC_FS is not set | ||
87 | # CONFIG_IDEPCI_PCIBUS_ORDER is not set | ||
88 | CONFIG_BLK_DEV_GENERIC=y | ||
89 | CONFIG_BLK_DEV_PIIX=y | ||
90 | CONFIG_SCSI=y | ||
91 | CONFIG_BLK_DEV_SD=y | ||
92 | CONFIG_CHR_DEV_SG=y | ||
93 | # CONFIG_SCSI_LOWLEVEL is not set | ||
94 | CONFIG_NETDEVICES=y | ||
95 | # CONFIG_NET_VENDOR_3COM is not set | ||
96 | # CONFIG_NET_VENDOR_ADAPTEC is not set | ||
97 | # CONFIG_NET_VENDOR_ALTEON is not set | ||
98 | CONFIG_PCNET32=y | ||
99 | # CONFIG_NET_VENDOR_ATHEROS is not set | ||
100 | # CONFIG_NET_VENDOR_BROADCOM is not set | ||
101 | # CONFIG_NET_VENDOR_BROCADE is not set | ||
102 | # CONFIG_NET_VENDOR_CHELSIO is not set | ||
103 | # CONFIG_NET_VENDOR_CISCO is not set | ||
104 | # CONFIG_NET_VENDOR_DEC is not set | ||
105 | # CONFIG_NET_VENDOR_DLINK is not set | ||
106 | # CONFIG_NET_VENDOR_EMULEX is not set | ||
107 | # CONFIG_NET_VENDOR_EXAR is not set | ||
108 | # CONFIG_NET_VENDOR_HP is not set | ||
109 | # CONFIG_NET_VENDOR_INTEL is not set | ||
110 | # CONFIG_NET_VENDOR_MARVELL is not set | ||
111 | # CONFIG_NET_VENDOR_MELLANOX is not set | ||
112 | # CONFIG_NET_VENDOR_MICREL is not set | ||
113 | # CONFIG_NET_VENDOR_MYRI is not set | ||
114 | # CONFIG_NET_VENDOR_NATSEMI is not set | ||
115 | # CONFIG_NET_VENDOR_NVIDIA is not set | ||
116 | # CONFIG_NET_VENDOR_OKI is not set | ||
117 | # CONFIG_NET_PACKET_ENGINE is not set | ||
118 | # CONFIG_NET_VENDOR_QLOGIC is not set | ||
119 | # CONFIG_NET_VENDOR_REALTEK is not set | ||
120 | # CONFIG_NET_VENDOR_RDC is not set | ||
121 | # CONFIG_NET_VENDOR_SEEQ is not set | ||
122 | # CONFIG_NET_VENDOR_SILAN is not set | ||
123 | # CONFIG_NET_VENDOR_SIS is not set | ||
124 | # CONFIG_NET_VENDOR_SMSC is not set | ||
125 | # CONFIG_NET_VENDOR_STMICRO is not set | ||
126 | # CONFIG_NET_VENDOR_SUN is not set | ||
127 | # CONFIG_NET_VENDOR_TEHUTI is not set | ||
128 | # CONFIG_NET_VENDOR_TI is not set | ||
129 | # CONFIG_NET_VENDOR_TOSHIBA is not set | ||
130 | # CONFIG_NET_VENDOR_VIA is not set | ||
131 | # CONFIG_WLAN is not set | ||
132 | # CONFIG_VT is not set | ||
133 | CONFIG_LEGACY_PTY_COUNT=16 | ||
134 | CONFIG_SERIAL_8250=y | ||
135 | CONFIG_SERIAL_8250_CONSOLE=y | ||
136 | CONFIG_HW_RANDOM=y | ||
137 | # CONFIG_HWMON is not set | ||
138 | CONFIG_VIDEO_OUTPUT_CONTROL=m | ||
139 | CONFIG_FB=y | ||
140 | CONFIG_FIRMWARE_EDID=y | ||
141 | CONFIG_FB_MATROX=y | ||
142 | CONFIG_FB_MATROX_G=y | ||
143 | CONFIG_USB=y | ||
144 | CONFIG_USB_EHCI_HCD=y | ||
145 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | ||
146 | CONFIG_USB_UHCI_HCD=y | ||
147 | CONFIG_USB_STORAGE=y | ||
148 | CONFIG_NEW_LEDS=y | ||
149 | CONFIG_LEDS_CLASS=y | ||
150 | CONFIG_LEDS_TRIGGERS=y | ||
151 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
152 | CONFIG_LEDS_TRIGGER_IDE_DISK=y | ||
153 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
154 | CONFIG_LEDS_TRIGGER_BACKLIGHT=y | ||
155 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
156 | CONFIG_RTC_CLASS=y | ||
157 | CONFIG_RTC_DRV_CMOS=y | ||
158 | CONFIG_EXT2_FS=y | ||
159 | CONFIG_EXT3_FS=y | ||
160 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
161 | CONFIG_XFS_FS=y | ||
162 | CONFIG_XFS_QUOTA=y | ||
163 | CONFIG_XFS_POSIX_ACL=y | ||
164 | CONFIG_QUOTA=y | ||
165 | CONFIG_QFMT_V2=y | ||
166 | CONFIG_MSDOS_FS=m | ||
167 | CONFIG_VFAT_FS=m | ||
168 | CONFIG_PROC_KCORE=y | ||
169 | CONFIG_TMPFS=y | ||
170 | CONFIG_NFS_FS=y | ||
171 | CONFIG_ROOT_NFS=y | ||
172 | CONFIG_CIFS=m | ||
173 | CONFIG_CIFS_WEAK_PW_HASH=y | ||
174 | CONFIG_CIFS_XATTR=y | ||
175 | CONFIG_CIFS_POSIX=y | ||
176 | CONFIG_NLS_CODEPAGE_437=m | ||
177 | CONFIG_NLS_ISO8859_1=m | ||
178 | # CONFIG_FTRACE is not set | ||
179 | CONFIG_CRYPTO_NULL=m | ||
180 | CONFIG_CRYPTO_PCBC=m | ||
181 | CONFIG_CRYPTO_HMAC=y | ||
182 | CONFIG_CRYPTO_MICHAEL_MIC=m | ||
183 | CONFIG_CRYPTO_SHA512=m | ||
184 | CONFIG_CRYPTO_TGR192=m | ||
185 | CONFIG_CRYPTO_WP512=m | ||
186 | CONFIG_CRYPTO_ANUBIS=m | ||
187 | CONFIG_CRYPTO_BLOWFISH=m | ||
188 | CONFIG_CRYPTO_CAST5=m | ||
189 | CONFIG_CRYPTO_CAST6=m | ||
190 | CONFIG_CRYPTO_KHAZAD=m | ||
191 | CONFIG_CRYPTO_SERPENT=m | ||
192 | CONFIG_CRYPTO_TEA=m | ||
193 | CONFIG_CRYPTO_TWOFISH=m | ||
194 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
195 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/mips/configs/maltasmtc_defconfig b/arch/mips/configs/maltasmtc_defconfig new file mode 100644 index 000000000000..4e54b75d89be --- /dev/null +++ b/arch/mips/configs/maltasmtc_defconfig | |||
@@ -0,0 +1,196 @@ | |||
1 | CONFIG_MIPS_MALTA=y | ||
2 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
3 | CONFIG_CPU_MIPS32_R2=y | ||
4 | CONFIG_MIPS_MT_SMTC=y | ||
5 | # CONFIG_MIPS_MT_FPAFF is not set | ||
6 | CONFIG_NR_CPUS=9 | ||
7 | CONFIG_HZ_48=y | ||
8 | CONFIG_LOCALVERSION="smtc" | ||
9 | CONFIG_SYSVIPC=y | ||
10 | CONFIG_POSIX_MQUEUE=y | ||
11 | CONFIG_AUDIT=y | ||
12 | CONFIG_IKCONFIG=y | ||
13 | CONFIG_IKCONFIG_PROC=y | ||
14 | CONFIG_LOG_BUF_SHIFT=15 | ||
15 | CONFIG_SYSCTL_SYSCALL=y | ||
16 | CONFIG_EMBEDDED=y | ||
17 | CONFIG_SLAB=y | ||
18 | CONFIG_MODULES=y | ||
19 | CONFIG_MODULE_UNLOAD=y | ||
20 | CONFIG_MODVERSIONS=y | ||
21 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
22 | # CONFIG_BLK_DEV_BSG is not set | ||
23 | CONFIG_PCI=y | ||
24 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
25 | CONFIG_NET=y | ||
26 | CONFIG_PACKET=y | ||
27 | CONFIG_UNIX=y | ||
28 | CONFIG_XFRM_USER=m | ||
29 | CONFIG_NET_KEY=y | ||
30 | CONFIG_INET=y | ||
31 | CONFIG_IP_MULTICAST=y | ||
32 | CONFIG_IP_ADVANCED_ROUTER=y | ||
33 | CONFIG_IP_MULTIPLE_TABLES=y | ||
34 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
35 | CONFIG_IP_ROUTE_VERBOSE=y | ||
36 | CONFIG_IP_PNP=y | ||
37 | CONFIG_IP_PNP_DHCP=y | ||
38 | CONFIG_IP_PNP_BOOTP=y | ||
39 | CONFIG_NET_IPIP=m | ||
40 | CONFIG_IP_MROUTE=y | ||
41 | CONFIG_IP_PIMSM_V1=y | ||
42 | CONFIG_IP_PIMSM_V2=y | ||
43 | CONFIG_SYN_COOKIES=y | ||
44 | CONFIG_INET_AH=m | ||
45 | CONFIG_INET_ESP=m | ||
46 | CONFIG_INET_IPCOMP=m | ||
47 | # CONFIG_INET_LRO is not set | ||
48 | CONFIG_IPV6_PRIVACY=y | ||
49 | CONFIG_INET6_AH=m | ||
50 | CONFIG_INET6_ESP=m | ||
51 | CONFIG_INET6_IPCOMP=m | ||
52 | CONFIG_IPV6_TUNNEL=m | ||
53 | CONFIG_BRIDGE=m | ||
54 | CONFIG_VLAN_8021Q=m | ||
55 | CONFIG_ATALK=m | ||
56 | CONFIG_DEV_APPLETALK=m | ||
57 | CONFIG_IPDDP=m | ||
58 | CONFIG_IPDDP_ENCAP=y | ||
59 | CONFIG_IPDDP_DECAP=y | ||
60 | CONFIG_NET_SCHED=y | ||
61 | CONFIG_NET_SCH_CBQ=m | ||
62 | CONFIG_NET_SCH_HTB=m | ||
63 | CONFIG_NET_SCH_HFSC=m | ||
64 | CONFIG_NET_SCH_PRIO=m | ||
65 | CONFIG_NET_SCH_RED=m | ||
66 | CONFIG_NET_SCH_SFQ=m | ||
67 | CONFIG_NET_SCH_TEQL=m | ||
68 | CONFIG_NET_SCH_TBF=m | ||
69 | CONFIG_NET_SCH_GRED=m | ||
70 | CONFIG_NET_SCH_DSMARK=m | ||
71 | CONFIG_NET_SCH_NETEM=m | ||
72 | CONFIG_NET_SCH_INGRESS=m | ||
73 | CONFIG_NET_CLS_BASIC=m | ||
74 | CONFIG_NET_CLS_TCINDEX=m | ||
75 | CONFIG_NET_CLS_ROUTE4=m | ||
76 | CONFIG_NET_CLS_FW=m | ||
77 | CONFIG_NET_CLS_U32=m | ||
78 | CONFIG_NET_CLS_RSVP=m | ||
79 | CONFIG_NET_CLS_RSVP6=m | ||
80 | CONFIG_NET_CLS_ACT=y | ||
81 | CONFIG_NET_ACT_POLICE=y | ||
82 | CONFIG_NET_CLS_IND=y | ||
83 | # CONFIG_WIRELESS is not set | ||
84 | CONFIG_BLK_DEV_LOOP=y | ||
85 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
86 | CONFIG_IDE=y | ||
87 | # CONFIG_IDE_PROC_FS is not set | ||
88 | # CONFIG_IDEPCI_PCIBUS_ORDER is not set | ||
89 | CONFIG_BLK_DEV_GENERIC=y | ||
90 | CONFIG_BLK_DEV_PIIX=y | ||
91 | CONFIG_SCSI=y | ||
92 | CONFIG_BLK_DEV_SD=y | ||
93 | CONFIG_CHR_DEV_SG=y | ||
94 | # CONFIG_SCSI_LOWLEVEL is not set | ||
95 | CONFIG_NETDEVICES=y | ||
96 | # CONFIG_NET_VENDOR_3COM is not set | ||
97 | # CONFIG_NET_VENDOR_ADAPTEC is not set | ||
98 | # CONFIG_NET_VENDOR_ALTEON is not set | ||
99 | CONFIG_PCNET32=y | ||
100 | # CONFIG_NET_VENDOR_ATHEROS is not set | ||
101 | # CONFIG_NET_VENDOR_BROADCOM is not set | ||
102 | # CONFIG_NET_VENDOR_BROCADE is not set | ||
103 | # CONFIG_NET_VENDOR_CHELSIO is not set | ||
104 | # CONFIG_NET_VENDOR_CISCO is not set | ||
105 | # CONFIG_NET_VENDOR_DEC is not set | ||
106 | # CONFIG_NET_VENDOR_DLINK is not set | ||
107 | # CONFIG_NET_VENDOR_EMULEX is not set | ||
108 | # CONFIG_NET_VENDOR_EXAR is not set | ||
109 | # CONFIG_NET_VENDOR_HP is not set | ||
110 | # CONFIG_NET_VENDOR_INTEL is not set | ||
111 | # CONFIG_NET_VENDOR_MARVELL is not set | ||
112 | # CONFIG_NET_VENDOR_MELLANOX is not set | ||
113 | # CONFIG_NET_VENDOR_MICREL is not set | ||
114 | # CONFIG_NET_VENDOR_MYRI is not set | ||
115 | # CONFIG_NET_VENDOR_NATSEMI is not set | ||
116 | # CONFIG_NET_VENDOR_NVIDIA is not set | ||
117 | # CONFIG_NET_VENDOR_OKI is not set | ||
118 | # CONFIG_NET_PACKET_ENGINE is not set | ||
119 | # CONFIG_NET_VENDOR_QLOGIC is not set | ||
120 | # CONFIG_NET_VENDOR_REALTEK is not set | ||
121 | # CONFIG_NET_VENDOR_RDC is not set | ||
122 | # CONFIG_NET_VENDOR_SEEQ is not set | ||
123 | # CONFIG_NET_VENDOR_SILAN is not set | ||
124 | # CONFIG_NET_VENDOR_SIS is not set | ||
125 | # CONFIG_NET_VENDOR_SMSC is not set | ||
126 | # CONFIG_NET_VENDOR_STMICRO is not set | ||
127 | # CONFIG_NET_VENDOR_SUN is not set | ||
128 | # CONFIG_NET_VENDOR_TEHUTI is not set | ||
129 | # CONFIG_NET_VENDOR_TI is not set | ||
130 | # CONFIG_NET_VENDOR_TOSHIBA is not set | ||
131 | # CONFIG_NET_VENDOR_VIA is not set | ||
132 | # CONFIG_WLAN is not set | ||
133 | # CONFIG_VT is not set | ||
134 | CONFIG_LEGACY_PTY_COUNT=16 | ||
135 | CONFIG_SERIAL_8250=y | ||
136 | CONFIG_SERIAL_8250_CONSOLE=y | ||
137 | CONFIG_HW_RANDOM=y | ||
138 | # CONFIG_HWMON is not set | ||
139 | CONFIG_VIDEO_OUTPUT_CONTROL=m | ||
140 | CONFIG_FB=y | ||
141 | CONFIG_FIRMWARE_EDID=y | ||
142 | CONFIG_FB_MATROX=y | ||
143 | CONFIG_FB_MATROX_G=y | ||
144 | CONFIG_USB=y | ||
145 | CONFIG_USB_EHCI_HCD=y | ||
146 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | ||
147 | CONFIG_USB_UHCI_HCD=y | ||
148 | CONFIG_USB_STORAGE=y | ||
149 | CONFIG_NEW_LEDS=y | ||
150 | CONFIG_LEDS_CLASS=y | ||
151 | CONFIG_LEDS_TRIGGERS=y | ||
152 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
153 | CONFIG_LEDS_TRIGGER_IDE_DISK=y | ||
154 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
155 | CONFIG_LEDS_TRIGGER_BACKLIGHT=y | ||
156 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
157 | CONFIG_RTC_CLASS=y | ||
158 | CONFIG_RTC_DRV_CMOS=y | ||
159 | CONFIG_EXT2_FS=y | ||
160 | CONFIG_EXT3_FS=y | ||
161 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
162 | CONFIG_XFS_FS=y | ||
163 | CONFIG_XFS_QUOTA=y | ||
164 | CONFIG_XFS_POSIX_ACL=y | ||
165 | CONFIG_QUOTA=y | ||
166 | CONFIG_QFMT_V2=y | ||
167 | CONFIG_MSDOS_FS=m | ||
168 | CONFIG_VFAT_FS=m | ||
169 | CONFIG_PROC_KCORE=y | ||
170 | CONFIG_TMPFS=y | ||
171 | CONFIG_NFS_FS=y | ||
172 | CONFIG_ROOT_NFS=y | ||
173 | CONFIG_CIFS=m | ||
174 | CONFIG_CIFS_WEAK_PW_HASH=y | ||
175 | CONFIG_CIFS_XATTR=y | ||
176 | CONFIG_CIFS_POSIX=y | ||
177 | CONFIG_NLS_CODEPAGE_437=m | ||
178 | CONFIG_NLS_ISO8859_1=m | ||
179 | # CONFIG_FTRACE is not set | ||
180 | CONFIG_CRYPTO_NULL=m | ||
181 | CONFIG_CRYPTO_PCBC=m | ||
182 | CONFIG_CRYPTO_HMAC=y | ||
183 | CONFIG_CRYPTO_MICHAEL_MIC=m | ||
184 | CONFIG_CRYPTO_SHA512=m | ||
185 | CONFIG_CRYPTO_TGR192=m | ||
186 | CONFIG_CRYPTO_WP512=m | ||
187 | CONFIG_CRYPTO_ANUBIS=m | ||
188 | CONFIG_CRYPTO_BLOWFISH=m | ||
189 | CONFIG_CRYPTO_CAST5=m | ||
190 | CONFIG_CRYPTO_CAST6=m | ||
191 | CONFIG_CRYPTO_KHAZAD=m | ||
192 | CONFIG_CRYPTO_SERPENT=m | ||
193 | CONFIG_CRYPTO_TEA=m | ||
194 | CONFIG_CRYPTO_TWOFISH=m | ||
195 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
196 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig new file mode 100644 index 000000000000..8a666021b870 --- /dev/null +++ b/arch/mips/configs/maltasmvp_defconfig | |||
@@ -0,0 +1,199 @@ | |||
1 | CONFIG_MIPS_MALTA=y | ||
2 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
3 | CONFIG_CPU_MIPS32_R2=y | ||
4 | CONFIG_MIPS_MT_SMP=y | ||
5 | CONFIG_SCHED_SMT=y | ||
6 | CONFIG_MIPS_CMP=y | ||
7 | CONFIG_NR_CPUS=8 | ||
8 | CONFIG_HZ_100=y | ||
9 | CONFIG_LOCALVERSION="cmp" | ||
10 | CONFIG_SYSVIPC=y | ||
11 | CONFIG_POSIX_MQUEUE=y | ||
12 | CONFIG_AUDIT=y | ||
13 | CONFIG_NO_HZ=y | ||
14 | CONFIG_IKCONFIG=y | ||
15 | CONFIG_IKCONFIG_PROC=y | ||
16 | CONFIG_LOG_BUF_SHIFT=15 | ||
17 | CONFIG_SYSCTL_SYSCALL=y | ||
18 | CONFIG_EMBEDDED=y | ||
19 | CONFIG_SLAB=y | ||
20 | CONFIG_MODULES=y | ||
21 | CONFIG_MODULE_UNLOAD=y | ||
22 | CONFIG_MODVERSIONS=y | ||
23 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
24 | # CONFIG_BLK_DEV_BSG is not set | ||
25 | CONFIG_PCI=y | ||
26 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
27 | CONFIG_NET=y | ||
28 | CONFIG_PACKET=y | ||
29 | CONFIG_UNIX=y | ||
30 | CONFIG_XFRM_USER=m | ||
31 | CONFIG_NET_KEY=y | ||
32 | CONFIG_INET=y | ||
33 | CONFIG_IP_MULTICAST=y | ||
34 | CONFIG_IP_ADVANCED_ROUTER=y | ||
35 | CONFIG_IP_MULTIPLE_TABLES=y | ||
36 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
37 | CONFIG_IP_ROUTE_VERBOSE=y | ||
38 | CONFIG_IP_PNP=y | ||
39 | CONFIG_IP_PNP_DHCP=y | ||
40 | CONFIG_IP_PNP_BOOTP=y | ||
41 | CONFIG_NET_IPIP=m | ||
42 | CONFIG_IP_MROUTE=y | ||
43 | CONFIG_IP_PIMSM_V1=y | ||
44 | CONFIG_IP_PIMSM_V2=y | ||
45 | CONFIG_SYN_COOKIES=y | ||
46 | CONFIG_INET_AH=m | ||
47 | CONFIG_INET_ESP=m | ||
48 | CONFIG_INET_IPCOMP=m | ||
49 | # CONFIG_INET_LRO is not set | ||
50 | CONFIG_IPV6_PRIVACY=y | ||
51 | CONFIG_INET6_AH=m | ||
52 | CONFIG_INET6_ESP=m | ||
53 | CONFIG_INET6_IPCOMP=m | ||
54 | CONFIG_IPV6_TUNNEL=m | ||
55 | CONFIG_BRIDGE=m | ||
56 | CONFIG_VLAN_8021Q=m | ||
57 | CONFIG_ATALK=m | ||
58 | CONFIG_DEV_APPLETALK=m | ||
59 | CONFIG_IPDDP=m | ||
60 | CONFIG_IPDDP_ENCAP=y | ||
61 | CONFIG_IPDDP_DECAP=y | ||
62 | CONFIG_NET_SCHED=y | ||
63 | CONFIG_NET_SCH_CBQ=m | ||
64 | CONFIG_NET_SCH_HTB=m | ||
65 | CONFIG_NET_SCH_HFSC=m | ||
66 | CONFIG_NET_SCH_PRIO=m | ||
67 | CONFIG_NET_SCH_RED=m | ||
68 | CONFIG_NET_SCH_SFQ=m | ||
69 | CONFIG_NET_SCH_TEQL=m | ||
70 | CONFIG_NET_SCH_TBF=m | ||
71 | CONFIG_NET_SCH_GRED=m | ||
72 | CONFIG_NET_SCH_DSMARK=m | ||
73 | CONFIG_NET_SCH_NETEM=m | ||
74 | CONFIG_NET_SCH_INGRESS=m | ||
75 | CONFIG_NET_CLS_BASIC=m | ||
76 | CONFIG_NET_CLS_TCINDEX=m | ||
77 | CONFIG_NET_CLS_ROUTE4=m | ||
78 | CONFIG_NET_CLS_FW=m | ||
79 | CONFIG_NET_CLS_U32=m | ||
80 | CONFIG_NET_CLS_RSVP=m | ||
81 | CONFIG_NET_CLS_RSVP6=m | ||
82 | CONFIG_NET_CLS_ACT=y | ||
83 | CONFIG_NET_ACT_POLICE=y | ||
84 | CONFIG_NET_CLS_IND=y | ||
85 | # CONFIG_WIRELESS is not set | ||
86 | CONFIG_BLK_DEV_LOOP=y | ||
87 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
88 | CONFIG_IDE=y | ||
89 | # CONFIG_IDE_PROC_FS is not set | ||
90 | # CONFIG_IDEPCI_PCIBUS_ORDER is not set | ||
91 | CONFIG_BLK_DEV_GENERIC=y | ||
92 | CONFIG_BLK_DEV_PIIX=y | ||
93 | CONFIG_SCSI=y | ||
94 | CONFIG_BLK_DEV_SD=y | ||
95 | CONFIG_CHR_DEV_SG=y | ||
96 | # CONFIG_SCSI_LOWLEVEL is not set | ||
97 | CONFIG_NETDEVICES=y | ||
98 | # CONFIG_NET_VENDOR_3COM is not set | ||
99 | # CONFIG_NET_VENDOR_ADAPTEC is not set | ||
100 | # CONFIG_NET_VENDOR_ALTEON is not set | ||
101 | CONFIG_PCNET32=y | ||
102 | # CONFIG_NET_VENDOR_ATHEROS is not set | ||
103 | # CONFIG_NET_VENDOR_BROADCOM is not set | ||
104 | # CONFIG_NET_VENDOR_BROCADE is not set | ||
105 | # CONFIG_NET_VENDOR_CHELSIO is not set | ||
106 | # CONFIG_NET_VENDOR_CISCO is not set | ||
107 | # CONFIG_NET_VENDOR_DEC is not set | ||
108 | # CONFIG_NET_VENDOR_DLINK is not set | ||
109 | # CONFIG_NET_VENDOR_EMULEX is not set | ||
110 | # CONFIG_NET_VENDOR_EXAR is not set | ||
111 | # CONFIG_NET_VENDOR_HP is not set | ||
112 | # CONFIG_NET_VENDOR_INTEL is not set | ||
113 | # CONFIG_NET_VENDOR_MARVELL is not set | ||
114 | # CONFIG_NET_VENDOR_MELLANOX is not set | ||
115 | # CONFIG_NET_VENDOR_MICREL is not set | ||
116 | # CONFIG_NET_VENDOR_MYRI is not set | ||
117 | # CONFIG_NET_VENDOR_NATSEMI is not set | ||
118 | # CONFIG_NET_VENDOR_NVIDIA is not set | ||
119 | # CONFIG_NET_VENDOR_OKI is not set | ||
120 | # CONFIG_NET_PACKET_ENGINE is not set | ||
121 | # CONFIG_NET_VENDOR_QLOGIC is not set | ||
122 | # CONFIG_NET_VENDOR_REALTEK is not set | ||
123 | # CONFIG_NET_VENDOR_RDC is not set | ||
124 | # CONFIG_NET_VENDOR_SEEQ is not set | ||
125 | # CONFIG_NET_VENDOR_SILAN is not set | ||
126 | # CONFIG_NET_VENDOR_SIS is not set | ||
127 | # CONFIG_NET_VENDOR_SMSC is not set | ||
128 | # CONFIG_NET_VENDOR_STMICRO is not set | ||
129 | # CONFIG_NET_VENDOR_SUN is not set | ||
130 | # CONFIG_NET_VENDOR_TEHUTI is not set | ||
131 | # CONFIG_NET_VENDOR_TI is not set | ||
132 | # CONFIG_NET_VENDOR_TOSHIBA is not set | ||
133 | # CONFIG_NET_VENDOR_VIA is not set | ||
134 | # CONFIG_NET_VENDOR_WIZNET is not set | ||
135 | # CONFIG_WLAN is not set | ||
136 | # CONFIG_VT is not set | ||
137 | CONFIG_LEGACY_PTY_COUNT=4 | ||
138 | CONFIG_SERIAL_8250=y | ||
139 | CONFIG_SERIAL_8250_CONSOLE=y | ||
140 | CONFIG_HW_RANDOM=y | ||
141 | # CONFIG_HWMON is not set | ||
142 | CONFIG_VIDEO_OUTPUT_CONTROL=m | ||
143 | CONFIG_FB=y | ||
144 | CONFIG_FIRMWARE_EDID=y | ||
145 | CONFIG_FB_MATROX=y | ||
146 | CONFIG_FB_MATROX_G=y | ||
147 | CONFIG_USB=y | ||
148 | CONFIG_USB_EHCI_HCD=y | ||
149 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | ||
150 | CONFIG_USB_UHCI_HCD=y | ||
151 | CONFIG_USB_STORAGE=y | ||
152 | CONFIG_NEW_LEDS=y | ||
153 | CONFIG_LEDS_CLASS=y | ||
154 | CONFIG_LEDS_TRIGGERS=y | ||
155 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
156 | CONFIG_LEDS_TRIGGER_IDE_DISK=y | ||
157 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
158 | CONFIG_LEDS_TRIGGER_BACKLIGHT=y | ||
159 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
160 | CONFIG_RTC_CLASS=y | ||
161 | CONFIG_RTC_DRV_CMOS=y | ||
162 | CONFIG_EXT2_FS=y | ||
163 | CONFIG_EXT3_FS=y | ||
164 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
165 | CONFIG_XFS_FS=y | ||
166 | CONFIG_XFS_QUOTA=y | ||
167 | CONFIG_XFS_POSIX_ACL=y | ||
168 | CONFIG_QUOTA=y | ||
169 | CONFIG_QFMT_V2=y | ||
170 | CONFIG_MSDOS_FS=m | ||
171 | CONFIG_VFAT_FS=m | ||
172 | CONFIG_PROC_KCORE=y | ||
173 | CONFIG_TMPFS=y | ||
174 | CONFIG_NFS_FS=y | ||
175 | CONFIG_ROOT_NFS=y | ||
176 | CONFIG_CIFS=m | ||
177 | CONFIG_CIFS_WEAK_PW_HASH=y | ||
178 | CONFIG_CIFS_XATTR=y | ||
179 | CONFIG_CIFS_POSIX=y | ||
180 | CONFIG_NLS_CODEPAGE_437=m | ||
181 | CONFIG_NLS_ISO8859_1=m | ||
182 | # CONFIG_FTRACE is not set | ||
183 | CONFIG_CRYPTO_NULL=m | ||
184 | CONFIG_CRYPTO_PCBC=m | ||
185 | CONFIG_CRYPTO_HMAC=y | ||
186 | CONFIG_CRYPTO_MICHAEL_MIC=m | ||
187 | CONFIG_CRYPTO_SHA512=m | ||
188 | CONFIG_CRYPTO_TGR192=m | ||
189 | CONFIG_CRYPTO_WP512=m | ||
190 | CONFIG_CRYPTO_ANUBIS=m | ||
191 | CONFIG_CRYPTO_BLOWFISH=m | ||
192 | CONFIG_CRYPTO_CAST5=m | ||
193 | CONFIG_CRYPTO_CAST6=m | ||
194 | CONFIG_CRYPTO_KHAZAD=m | ||
195 | CONFIG_CRYPTO_SERPENT=m | ||
196 | CONFIG_CRYPTO_TEA=m | ||
197 | CONFIG_CRYPTO_TWOFISH=m | ||
198 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
199 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig new file mode 100644 index 000000000000..9868fc9c1133 --- /dev/null +++ b/arch/mips/configs/maltaup_defconfig | |||
@@ -0,0 +1,194 @@ | |||
1 | CONFIG_MIPS_MALTA=y | ||
2 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
3 | CONFIG_CPU_MIPS32_R2=y | ||
4 | CONFIG_HZ_100=y | ||
5 | CONFIG_LOCALVERSION="up" | ||
6 | CONFIG_SYSVIPC=y | ||
7 | CONFIG_POSIX_MQUEUE=y | ||
8 | CONFIG_AUDIT=y | ||
9 | CONFIG_NO_HZ=y | ||
10 | CONFIG_IKCONFIG=y | ||
11 | CONFIG_IKCONFIG_PROC=y | ||
12 | CONFIG_LOG_BUF_SHIFT=15 | ||
13 | CONFIG_SYSCTL_SYSCALL=y | ||
14 | CONFIG_EMBEDDED=y | ||
15 | CONFIG_SLAB=y | ||
16 | CONFIG_MODULES=y | ||
17 | CONFIG_MODULE_UNLOAD=y | ||
18 | CONFIG_MODVERSIONS=y | ||
19 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
20 | # CONFIG_BLK_DEV_BSG is not set | ||
21 | CONFIG_PCI=y | ||
22 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
23 | CONFIG_NET=y | ||
24 | CONFIG_PACKET=y | ||
25 | CONFIG_UNIX=y | ||
26 | CONFIG_XFRM_USER=m | ||
27 | CONFIG_NET_KEY=y | ||
28 | CONFIG_INET=y | ||
29 | CONFIG_IP_MULTICAST=y | ||
30 | CONFIG_IP_ADVANCED_ROUTER=y | ||
31 | CONFIG_IP_MULTIPLE_TABLES=y | ||
32 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
33 | CONFIG_IP_ROUTE_VERBOSE=y | ||
34 | CONFIG_IP_PNP=y | ||
35 | CONFIG_IP_PNP_DHCP=y | ||
36 | CONFIG_IP_PNP_BOOTP=y | ||
37 | CONFIG_NET_IPIP=m | ||
38 | CONFIG_IP_MROUTE=y | ||
39 | CONFIG_IP_PIMSM_V1=y | ||
40 | CONFIG_IP_PIMSM_V2=y | ||
41 | CONFIG_SYN_COOKIES=y | ||
42 | CONFIG_INET_AH=m | ||
43 | CONFIG_INET_ESP=m | ||
44 | CONFIG_INET_IPCOMP=m | ||
45 | # CONFIG_INET_LRO is not set | ||
46 | CONFIG_IPV6_PRIVACY=y | ||
47 | CONFIG_INET6_AH=m | ||
48 | CONFIG_INET6_ESP=m | ||
49 | CONFIG_INET6_IPCOMP=m | ||
50 | CONFIG_IPV6_TUNNEL=m | ||
51 | CONFIG_BRIDGE=m | ||
52 | CONFIG_VLAN_8021Q=m | ||
53 | CONFIG_ATALK=m | ||
54 | CONFIG_DEV_APPLETALK=m | ||
55 | CONFIG_IPDDP=m | ||
56 | CONFIG_IPDDP_ENCAP=y | ||
57 | CONFIG_IPDDP_DECAP=y | ||
58 | CONFIG_NET_SCHED=y | ||
59 | CONFIG_NET_SCH_CBQ=m | ||
60 | CONFIG_NET_SCH_HTB=m | ||
61 | CONFIG_NET_SCH_HFSC=m | ||
62 | CONFIG_NET_SCH_PRIO=m | ||
63 | CONFIG_NET_SCH_RED=m | ||
64 | CONFIG_NET_SCH_SFQ=m | ||
65 | CONFIG_NET_SCH_TEQL=m | ||
66 | CONFIG_NET_SCH_TBF=m | ||
67 | CONFIG_NET_SCH_GRED=m | ||
68 | CONFIG_NET_SCH_DSMARK=m | ||
69 | CONFIG_NET_SCH_NETEM=m | ||
70 | CONFIG_NET_SCH_INGRESS=m | ||
71 | CONFIG_NET_CLS_BASIC=m | ||
72 | CONFIG_NET_CLS_TCINDEX=m | ||
73 | CONFIG_NET_CLS_ROUTE4=m | ||
74 | CONFIG_NET_CLS_FW=m | ||
75 | CONFIG_NET_CLS_U32=m | ||
76 | CONFIG_NET_CLS_RSVP=m | ||
77 | CONFIG_NET_CLS_RSVP6=m | ||
78 | CONFIG_NET_CLS_ACT=y | ||
79 | CONFIG_NET_ACT_POLICE=y | ||
80 | CONFIG_NET_CLS_IND=y | ||
81 | # CONFIG_WIRELESS is not set | ||
82 | CONFIG_BLK_DEV_LOOP=y | ||
83 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
84 | CONFIG_IDE=y | ||
85 | # CONFIG_IDE_PROC_FS is not set | ||
86 | # CONFIG_IDEPCI_PCIBUS_ORDER is not set | ||
87 | CONFIG_BLK_DEV_GENERIC=y | ||
88 | CONFIG_BLK_DEV_PIIX=y | ||
89 | CONFIG_SCSI=y | ||
90 | CONFIG_BLK_DEV_SD=y | ||
91 | CONFIG_CHR_DEV_SG=y | ||
92 | # CONFIG_SCSI_LOWLEVEL is not set | ||
93 | CONFIG_NETDEVICES=y | ||
94 | # CONFIG_NET_VENDOR_3COM is not set | ||
95 | # CONFIG_NET_VENDOR_ADAPTEC is not set | ||
96 | # CONFIG_NET_VENDOR_ALTEON is not set | ||
97 | CONFIG_PCNET32=y | ||
98 | # CONFIG_NET_VENDOR_ATHEROS is not set | ||
99 | # CONFIG_NET_VENDOR_BROADCOM is not set | ||
100 | # CONFIG_NET_VENDOR_BROCADE is not set | ||
101 | # CONFIG_NET_VENDOR_CHELSIO is not set | ||
102 | # CONFIG_NET_VENDOR_CISCO is not set | ||
103 | # CONFIG_NET_VENDOR_DEC is not set | ||
104 | # CONFIG_NET_VENDOR_DLINK is not set | ||
105 | # CONFIG_NET_VENDOR_EMULEX is not set | ||
106 | # CONFIG_NET_VENDOR_EXAR is not set | ||
107 | # CONFIG_NET_VENDOR_HP is not set | ||
108 | # CONFIG_NET_VENDOR_INTEL is not set | ||
109 | # CONFIG_NET_VENDOR_MARVELL is not set | ||
110 | # CONFIG_NET_VENDOR_MELLANOX is not set | ||
111 | # CONFIG_NET_VENDOR_MICREL is not set | ||
112 | # CONFIG_NET_VENDOR_MYRI is not set | ||
113 | # CONFIG_NET_VENDOR_NATSEMI is not set | ||
114 | # CONFIG_NET_VENDOR_NVIDIA is not set | ||
115 | # CONFIG_NET_VENDOR_OKI is not set | ||
116 | # CONFIG_NET_PACKET_ENGINE is not set | ||
117 | # CONFIG_NET_VENDOR_QLOGIC is not set | ||
118 | # CONFIG_NET_VENDOR_REALTEK is not set | ||
119 | # CONFIG_NET_VENDOR_RDC is not set | ||
120 | # CONFIG_NET_VENDOR_SEEQ is not set | ||
121 | # CONFIG_NET_VENDOR_SILAN is not set | ||
122 | # CONFIG_NET_VENDOR_SIS is not set | ||
123 | # CONFIG_NET_VENDOR_SMSC is not set | ||
124 | # CONFIG_NET_VENDOR_STMICRO is not set | ||
125 | # CONFIG_NET_VENDOR_SUN is not set | ||
126 | # CONFIG_NET_VENDOR_TEHUTI is not set | ||
127 | # CONFIG_NET_VENDOR_TI is not set | ||
128 | # CONFIG_NET_VENDOR_TOSHIBA is not set | ||
129 | # CONFIG_NET_VENDOR_VIA is not set | ||
130 | # CONFIG_WLAN is not set | ||
131 | # CONFIG_VT is not set | ||
132 | CONFIG_LEGACY_PTY_COUNT=16 | ||
133 | CONFIG_SERIAL_8250=y | ||
134 | CONFIG_SERIAL_8250_CONSOLE=y | ||
135 | CONFIG_HW_RANDOM=y | ||
136 | # CONFIG_HWMON is not set | ||
137 | CONFIG_VIDEO_OUTPUT_CONTROL=m | ||
138 | CONFIG_FB=y | ||
139 | CONFIG_FIRMWARE_EDID=y | ||
140 | CONFIG_FB_MATROX=y | ||
141 | CONFIG_FB_MATROX_G=y | ||
142 | CONFIG_USB=y | ||
143 | CONFIG_USB_EHCI_HCD=y | ||
144 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | ||
145 | CONFIG_USB_UHCI_HCD=y | ||
146 | CONFIG_USB_STORAGE=y | ||
147 | CONFIG_NEW_LEDS=y | ||
148 | CONFIG_LEDS_CLASS=y | ||
149 | CONFIG_LEDS_TRIGGERS=y | ||
150 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
151 | CONFIG_LEDS_TRIGGER_IDE_DISK=y | ||
152 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
153 | CONFIG_LEDS_TRIGGER_BACKLIGHT=y | ||
154 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
155 | CONFIG_RTC_CLASS=y | ||
156 | CONFIG_RTC_DRV_CMOS=y | ||
157 | CONFIG_EXT2_FS=y | ||
158 | CONFIG_EXT3_FS=y | ||
159 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
160 | CONFIG_XFS_FS=y | ||
161 | CONFIG_XFS_QUOTA=y | ||
162 | CONFIG_XFS_POSIX_ACL=y | ||
163 | CONFIG_QUOTA=y | ||
164 | CONFIG_QFMT_V2=y | ||
165 | CONFIG_MSDOS_FS=m | ||
166 | CONFIG_VFAT_FS=m | ||
167 | CONFIG_PROC_KCORE=y | ||
168 | CONFIG_TMPFS=y | ||
169 | CONFIG_NFS_FS=y | ||
170 | CONFIG_ROOT_NFS=y | ||
171 | CONFIG_CIFS=m | ||
172 | CONFIG_CIFS_WEAK_PW_HASH=y | ||
173 | CONFIG_CIFS_XATTR=y | ||
174 | CONFIG_CIFS_POSIX=y | ||
175 | CONFIG_NLS_CODEPAGE_437=m | ||
176 | CONFIG_NLS_ISO8859_1=m | ||
177 | # CONFIG_FTRACE is not set | ||
178 | CONFIG_CRYPTO_NULL=m | ||
179 | CONFIG_CRYPTO_PCBC=m | ||
180 | CONFIG_CRYPTO_HMAC=y | ||
181 | CONFIG_CRYPTO_MICHAEL_MIC=m | ||
182 | CONFIG_CRYPTO_SHA512=m | ||
183 | CONFIG_CRYPTO_TGR192=m | ||
184 | CONFIG_CRYPTO_WP512=m | ||
185 | CONFIG_CRYPTO_ANUBIS=m | ||
186 | CONFIG_CRYPTO_BLOWFISH=m | ||
187 | CONFIG_CRYPTO_CAST5=m | ||
188 | CONFIG_CRYPTO_CAST6=m | ||
189 | CONFIG_CRYPTO_KHAZAD=m | ||
190 | CONFIG_CRYPTO_SERPENT=m | ||
191 | CONFIG_CRYPTO_TEA=m | ||
192 | CONFIG_CRYPTO_TWOFISH=m | ||
193 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
194 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig index e3eec68d9132..0abe681c11a0 100644 --- a/arch/mips/configs/sead3_defconfig +++ b/arch/mips/configs/sead3_defconfig | |||
@@ -2,7 +2,6 @@ CONFIG_MIPS_SEAD3=y | |||
2 | CONFIG_CPU_LITTLE_ENDIAN=y | 2 | CONFIG_CPU_LITTLE_ENDIAN=y |
3 | CONFIG_CPU_MIPS32_R2=y | 3 | CONFIG_CPU_MIPS32_R2=y |
4 | CONFIG_HZ_100=y | 4 | CONFIG_HZ_100=y |
5 | CONFIG_EXPERIMENTAL=y | ||
6 | CONFIG_SYSVIPC=y | 5 | CONFIG_SYSVIPC=y |
7 | CONFIG_POSIX_MQUEUE=y | 6 | CONFIG_POSIX_MQUEUE=y |
8 | CONFIG_NO_HZ=y | 7 | CONFIG_NO_HZ=y |
@@ -115,10 +114,8 @@ CONFIG_NLS_ISO8859_1=y | |||
115 | CONFIG_NLS_ISO8859_15=y | 114 | CONFIG_NLS_ISO8859_15=y |
116 | CONFIG_NLS_UTF8=y | 115 | CONFIG_NLS_UTF8=y |
117 | # CONFIG_FTRACE is not set | 116 | # CONFIG_FTRACE is not set |
118 | CONFIG_CRYPTO=y | ||
119 | CONFIG_CRYPTO_CBC=y | 117 | CONFIG_CRYPTO_CBC=y |
120 | CONFIG_CRYPTO_ECB=y | 118 | CONFIG_CRYPTO_ECB=y |
121 | CONFIG_CRYPTO_AES=y | ||
122 | CONFIG_CRYPTO_ARC4=y | 119 | CONFIG_CRYPTO_ARC4=y |
123 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 120 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
124 | # CONFIG_CRYPTO_HW is not set | 121 | # CONFIG_CRYPTO_HW is not set |
diff --git a/arch/mips/configs/sead3micro_defconfig b/arch/mips/configs/sead3micro_defconfig new file mode 100644 index 000000000000..2a0da5bf4b64 --- /dev/null +++ b/arch/mips/configs/sead3micro_defconfig | |||
@@ -0,0 +1,122 @@ | |||
1 | CONFIG_MIPS_SEAD3=y | ||
2 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
3 | CONFIG_CPU_MIPS32_R2=y | ||
4 | CONFIG_CPU_MICROMIPS=y | ||
5 | CONFIG_HZ_100=y | ||
6 | CONFIG_SYSVIPC=y | ||
7 | CONFIG_POSIX_MQUEUE=y | ||
8 | CONFIG_NO_HZ=y | ||
9 | CONFIG_HIGH_RES_TIMERS=y | ||
10 | CONFIG_IKCONFIG=y | ||
11 | CONFIG_IKCONFIG_PROC=y | ||
12 | CONFIG_LOG_BUF_SHIFT=15 | ||
13 | CONFIG_EMBEDDED=y | ||
14 | CONFIG_SLAB=y | ||
15 | CONFIG_PROFILING=y | ||
16 | CONFIG_OPROFILE=y | ||
17 | CONFIG_MODULES=y | ||
18 | # CONFIG_BLK_DEV_BSG is not set | ||
19 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
20 | CONFIG_NET=y | ||
21 | CONFIG_PACKET=y | ||
22 | CONFIG_UNIX=y | ||
23 | CONFIG_INET=y | ||
24 | CONFIG_IP_PNP=y | ||
25 | CONFIG_IP_PNP_DHCP=y | ||
26 | CONFIG_IP_PNP_BOOTP=y | ||
27 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
28 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
29 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
30 | # CONFIG_INET_LRO is not set | ||
31 | # CONFIG_INET_DIAG is not set | ||
32 | # CONFIG_IPV6 is not set | ||
33 | # CONFIG_WIRELESS is not set | ||
34 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
35 | CONFIG_MTD=y | ||
36 | CONFIG_MTD_CHAR=y | ||
37 | CONFIG_MTD_BLOCK=y | ||
38 | CONFIG_MTD_CFI=y | ||
39 | CONFIG_MTD_CFI_INTELEXT=y | ||
40 | CONFIG_MTD_PHYSMAP=y | ||
41 | CONFIG_MTD_UBI=y | ||
42 | CONFIG_MTD_UBI_GLUEBI=y | ||
43 | CONFIG_BLK_DEV_LOOP=y | ||
44 | CONFIG_BLK_DEV_CRYPTOLOOP=m | ||
45 | CONFIG_SCSI=y | ||
46 | # CONFIG_SCSI_PROC_FS is not set | ||
47 | CONFIG_BLK_DEV_SD=y | ||
48 | CONFIG_CHR_DEV_SG=y | ||
49 | # CONFIG_SCSI_LOWLEVEL is not set | ||
50 | CONFIG_NETDEVICES=y | ||
51 | CONFIG_SMSC911X=y | ||
52 | # CONFIG_NET_VENDOR_WIZNET is not set | ||
53 | CONFIG_MARVELL_PHY=y | ||
54 | CONFIG_DAVICOM_PHY=y | ||
55 | CONFIG_QSEMI_PHY=y | ||
56 | CONFIG_LXT_PHY=y | ||
57 | CONFIG_CICADA_PHY=y | ||
58 | CONFIG_VITESSE_PHY=y | ||
59 | CONFIG_SMSC_PHY=y | ||
60 | CONFIG_BROADCOM_PHY=y | ||
61 | CONFIG_ICPLUS_PHY=y | ||
62 | # CONFIG_WLAN is not set | ||
63 | # CONFIG_INPUT_MOUSEDEV is not set | ||
64 | # CONFIG_INPUT_KEYBOARD is not set | ||
65 | # CONFIG_INPUT_MOUSE is not set | ||
66 | # CONFIG_SERIO is not set | ||
67 | # CONFIG_CONSOLE_TRANSLATIONS is not set | ||
68 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
69 | CONFIG_LEGACY_PTY_COUNT=32 | ||
70 | CONFIG_SERIAL_8250=y | ||
71 | CONFIG_SERIAL_8250_CONSOLE=y | ||
72 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
73 | CONFIG_SERIAL_8250_RUNTIME_UARTS=2 | ||
74 | # CONFIG_HW_RANDOM is not set | ||
75 | CONFIG_I2C=y | ||
76 | # CONFIG_I2C_COMPAT is not set | ||
77 | CONFIG_I2C_CHARDEV=y | ||
78 | # CONFIG_I2C_HELPER_AUTO is not set | ||
79 | CONFIG_SPI=y | ||
80 | CONFIG_SENSORS_ADT7475=y | ||
81 | CONFIG_BACKLIGHT_LCD_SUPPORT=y | ||
82 | CONFIG_LCD_CLASS_DEVICE=y | ||
83 | CONFIG_BACKLIGHT_CLASS_DEVICE=y | ||
84 | # CONFIG_VGA_CONSOLE is not set | ||
85 | CONFIG_USB=y | ||
86 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y | ||
87 | CONFIG_USB_EHCI_HCD=y | ||
88 | CONFIG_USB_EHCI_ROOT_HUB_TT=y | ||
89 | CONFIG_USB_STORAGE=y | ||
90 | CONFIG_MMC=y | ||
91 | CONFIG_MMC_DEBUG=y | ||
92 | CONFIG_MMC_SPI=y | ||
93 | CONFIG_NEW_LEDS=y | ||
94 | CONFIG_LEDS_CLASS=y | ||
95 | CONFIG_LEDS_TRIGGERS=y | ||
96 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
97 | CONFIG_RTC_CLASS=y | ||
98 | CONFIG_RTC_DRV_M41T80=y | ||
99 | CONFIG_EXT3_FS=y | ||
100 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
101 | CONFIG_XFS_FS=y | ||
102 | CONFIG_XFS_QUOTA=y | ||
103 | CONFIG_XFS_POSIX_ACL=y | ||
104 | CONFIG_QUOTA=y | ||
105 | # CONFIG_PRINT_QUOTA_WARNING is not set | ||
106 | CONFIG_MSDOS_FS=m | ||
107 | CONFIG_VFAT_FS=m | ||
108 | CONFIG_TMPFS=y | ||
109 | CONFIG_JFFS2_FS=y | ||
110 | CONFIG_NFS_FS=y | ||
111 | CONFIG_ROOT_NFS=y | ||
112 | CONFIG_NLS_CODEPAGE_437=y | ||
113 | CONFIG_NLS_ASCII=y | ||
114 | CONFIG_NLS_ISO8859_1=y | ||
115 | CONFIG_NLS_ISO8859_15=y | ||
116 | CONFIG_NLS_UTF8=y | ||
117 | # CONFIG_FTRACE is not set | ||
118 | CONFIG_CRYPTO_CBC=y | ||
119 | CONFIG_CRYPTO_ECB=y | ||
120 | CONFIG_CRYPTO_ARC4=y | ||
121 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
122 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/mips/fw/lib/Makefile b/arch/mips/fw/lib/Makefile index 84befc968fc4..529150516777 100644 --- a/arch/mips/fw/lib/Makefile +++ b/arch/mips/fw/lib/Makefile | |||
@@ -2,4 +2,6 @@ | |||
2 | # Makefile for generic prom monitor library routines under Linux. | 2 | # Makefile for generic prom monitor library routines under Linux. |
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y += cmdline.o | ||
6 | |||
5 | lib-$(CONFIG_64BIT) += call_o32.o | 7 | lib-$(CONFIG_64BIT) += call_o32.o |
diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c new file mode 100644 index 000000000000..ffd0345780ae --- /dev/null +++ b/arch/mips/fw/lib/cmdline.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
7 | */ | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/string.h> | ||
11 | |||
12 | #include <asm/addrspace.h> | ||
13 | #include <asm/fw/fw.h> | ||
14 | |||
15 | int fw_argc; | ||
16 | int *_fw_argv; | ||
17 | int *_fw_envp; | ||
18 | |||
19 | void __init fw_init_cmdline(void) | ||
20 | { | ||
21 | int i; | ||
22 | |||
23 | /* Validate command line parameters. */ | ||
24 | if ((fw_arg0 >= CKSEG0) || (fw_arg1 < CKSEG0)) { | ||
25 | fw_argc = 0; | ||
26 | _fw_argv = NULL; | ||
27 | } else { | ||
28 | fw_argc = (fw_arg0 & 0x0000ffff); | ||
29 | _fw_argv = (int *)fw_arg1; | ||
30 | } | ||
31 | |||
32 | /* Validate environment pointer. */ | ||
33 | if (fw_arg2 < CKSEG0) | ||
34 | _fw_envp = NULL; | ||
35 | else | ||
36 | _fw_envp = (int *)fw_arg2; | ||
37 | |||
38 | for (i = 1; i < fw_argc; i++) { | ||
39 | strlcat(arcs_cmdline, fw_argv(i), COMMAND_LINE_SIZE); | ||
40 | if (i < (fw_argc - 1)) | ||
41 | strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | char * __init fw_getcmdline(void) | ||
46 | { | ||
47 | return &(arcs_cmdline[0]); | ||
48 | } | ||
49 | |||
50 | char *fw_getenv(char *envname) | ||
51 | { | ||
52 | char *result = NULL; | ||
53 | |||
54 | if (_fw_envp != NULL) { | ||
55 | /* | ||
56 | * Return a pointer to the given environment variable. | ||
57 | * YAMON uses "name", "value" pairs, while U-Boot uses | ||
58 | * "name=value". | ||
59 | */ | ||
60 | int i, yamon, index = 0; | ||
61 | |||
62 | yamon = (strchr(fw_envp(index), '=') == NULL); | ||
63 | i = strlen(envname); | ||
64 | |||
65 | while (fw_envp(index)) { | ||
66 | if (strncmp(envname, fw_envp(index), i) == 0) { | ||
67 | if (yamon) { | ||
68 | result = fw_envp(index + 1); | ||
69 | break; | ||
70 | } else if (fw_envp(index)[i] == '=') { | ||
71 | result = (fw_envp(index + 1) + i); | ||
72 | break; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | /* Increment array index. */ | ||
77 | if (yamon) | ||
78 | index += 2; | ||
79 | else | ||
80 | index += 1; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | return result; | ||
85 | } | ||
86 | |||
87 | unsigned long fw_getenvl(char *envname) | ||
88 | { | ||
89 | unsigned long envl = 0UL; | ||
90 | char *str; | ||
91 | long val; | ||
92 | int tmp; | ||
93 | |||
94 | str = fw_getenv(envname); | ||
95 | if (str) { | ||
96 | tmp = kstrtol(str, 0, &val); | ||
97 | envl = (unsigned long)val; | ||
98 | } | ||
99 | |||
100 | return envl; | ||
101 | } | ||
diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h index 164a21e65b42..879691d194af 100644 --- a/arch/mips/include/asm/asm.h +++ b/arch/mips/include/asm/asm.h | |||
@@ -296,6 +296,7 @@ symbol = value | |||
296 | #define LONG_SUBU subu | 296 | #define LONG_SUBU subu |
297 | #define LONG_L lw | 297 | #define LONG_L lw |
298 | #define LONG_S sw | 298 | #define LONG_S sw |
299 | #define LONG_SP swp | ||
299 | #define LONG_SLL sll | 300 | #define LONG_SLL sll |
300 | #define LONG_SLLV sllv | 301 | #define LONG_SLLV sllv |
301 | #define LONG_SRL srl | 302 | #define LONG_SRL srl |
@@ -318,6 +319,7 @@ symbol = value | |||
318 | #define LONG_SUBU dsubu | 319 | #define LONG_SUBU dsubu |
319 | #define LONG_L ld | 320 | #define LONG_L ld |
320 | #define LONG_S sd | 321 | #define LONG_S sd |
322 | #define LONG_SP sdp | ||
321 | #define LONG_SLL dsll | 323 | #define LONG_SLL dsll |
322 | #define LONG_SLLV dsllv | 324 | #define LONG_SLLV dsllv |
323 | #define LONG_SRL dsrl | 325 | #define LONG_SRL dsrl |
diff --git a/arch/mips/include/asm/branch.h b/arch/mips/include/asm/branch.h index 888766ae1f85..e28a3e0eb3cb 100644 --- a/arch/mips/include/asm/branch.h +++ b/arch/mips/include/asm/branch.h | |||
@@ -11,6 +11,14 @@ | |||
11 | #include <asm/ptrace.h> | 11 | #include <asm/ptrace.h> |
12 | #include <asm/inst.h> | 12 | #include <asm/inst.h> |
13 | 13 | ||
14 | extern int __isa_exception_epc(struct pt_regs *regs); | ||
15 | extern int __compute_return_epc(struct pt_regs *regs); | ||
16 | extern int __compute_return_epc_for_insn(struct pt_regs *regs, | ||
17 | union mips_instruction insn); | ||
18 | extern int __microMIPS_compute_return_epc(struct pt_regs *regs); | ||
19 | extern int __MIPS16e_compute_return_epc(struct pt_regs *regs); | ||
20 | |||
21 | |||
14 | static inline int delay_slot(struct pt_regs *regs) | 22 | static inline int delay_slot(struct pt_regs *regs) |
15 | { | 23 | { |
16 | return regs->cp0_cause & CAUSEF_BD; | 24 | return regs->cp0_cause & CAUSEF_BD; |
@@ -18,20 +26,27 @@ static inline int delay_slot(struct pt_regs *regs) | |||
18 | 26 | ||
19 | static inline unsigned long exception_epc(struct pt_regs *regs) | 27 | static inline unsigned long exception_epc(struct pt_regs *regs) |
20 | { | 28 | { |
21 | if (!delay_slot(regs)) | 29 | if (likely(!delay_slot(regs))) |
22 | return regs->cp0_epc; | 30 | return regs->cp0_epc; |
23 | 31 | ||
32 | if (get_isa16_mode(regs->cp0_epc)) | ||
33 | return __isa_exception_epc(regs); | ||
34 | |||
24 | return regs->cp0_epc + 4; | 35 | return regs->cp0_epc + 4; |
25 | } | 36 | } |
26 | 37 | ||
27 | #define BRANCH_LIKELY_TAKEN 0x0001 | 38 | #define BRANCH_LIKELY_TAKEN 0x0001 |
28 | 39 | ||
29 | extern int __compute_return_epc(struct pt_regs *regs); | ||
30 | extern int __compute_return_epc_for_insn(struct pt_regs *regs, | ||
31 | union mips_instruction insn); | ||
32 | |||
33 | static inline int compute_return_epc(struct pt_regs *regs) | 40 | static inline int compute_return_epc(struct pt_regs *regs) |
34 | { | 41 | { |
42 | if (get_isa16_mode(regs->cp0_epc)) { | ||
43 | if (cpu_has_mmips) | ||
44 | return __microMIPS_compute_return_epc(regs); | ||
45 | if (cpu_has_mips16) | ||
46 | return __MIPS16e_compute_return_epc(regs); | ||
47 | return regs->cp0_epc; | ||
48 | } | ||
49 | |||
35 | if (!delay_slot(regs)) { | 50 | if (!delay_slot(regs)) { |
36 | regs->cp0_epc += 4; | 51 | regs->cp0_epc += 4; |
37 | return 0; | 52 | return 0; |
@@ -40,4 +55,19 @@ static inline int compute_return_epc(struct pt_regs *regs) | |||
40 | return __compute_return_epc(regs); | 55 | return __compute_return_epc(regs); |
41 | } | 56 | } |
42 | 57 | ||
58 | static inline int MIPS16e_compute_return_epc(struct pt_regs *regs, | ||
59 | union mips16e_instruction *inst) | ||
60 | { | ||
61 | if (likely(!delay_slot(regs))) { | ||
62 | if (inst->ri.opcode == MIPS16e_extend_op) { | ||
63 | regs->cp0_epc += 4; | ||
64 | return 0; | ||
65 | } | ||
66 | regs->cp0_epc += 2; | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | return __MIPS16e_compute_return_epc(regs); | ||
71 | } | ||
72 | |||
43 | #endif /* _ASM_BRANCH_H */ | 73 | #endif /* _ASM_BRANCH_H */ |
diff --git a/arch/mips/include/asm/dma-coherence.h b/arch/mips/include/asm/dma-coherence.h new file mode 100644 index 000000000000..242cbb3ca582 --- /dev/null +++ b/arch/mips/include/asm/dma-coherence.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> | ||
7 | * | ||
8 | */ | ||
9 | #ifndef __ASM_DMA_COHERENCE_H | ||
10 | #define __ASM_DMA_COHERENCE_H | ||
11 | |||
12 | extern int coherentio; | ||
13 | extern int hw_coherentio; | ||
14 | |||
15 | #endif | ||
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index f8fc74b6cb47..84238c574d5e 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _ASM_DMA_MAPPING_H | 2 | #define _ASM_DMA_MAPPING_H |
3 | 3 | ||
4 | #include <asm/scatterlist.h> | 4 | #include <asm/scatterlist.h> |
5 | #include <asm/dma-coherence.h> | ||
5 | #include <asm/cache.h> | 6 | #include <asm/cache.h> |
6 | #include <asm-generic/dma-coherent.h> | 7 | #include <asm-generic/dma-coherent.h> |
7 | 8 | ||
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h index 3b4092705567..2abb587d5ab4 100644 --- a/arch/mips/include/asm/fpu_emulator.h +++ b/arch/mips/include/asm/fpu_emulator.h | |||
@@ -54,6 +54,12 @@ do { \ | |||
54 | extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, | 54 | extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, |
55 | unsigned long cpc); | 55 | unsigned long cpc); |
56 | extern int do_dsemulret(struct pt_regs *xcp); | 56 | extern int do_dsemulret(struct pt_regs *xcp); |
57 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, | ||
58 | struct mips_fpu_struct *ctx, int has_fpu, | ||
59 | void *__user *fault_addr); | ||
60 | int process_fpemu_return(int sig, void __user *fault_addr); | ||
61 | int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, | ||
62 | unsigned long *contpc); | ||
57 | 63 | ||
58 | /* | 64 | /* |
59 | * Instruction inserted following the badinst to further tag the sequence | 65 | * Instruction inserted following the badinst to further tag the sequence |
diff --git a/arch/mips/include/asm/fw/fw.h b/arch/mips/include/asm/fw/fw.h new file mode 100644 index 000000000000..d6c50a7e9ede --- /dev/null +++ b/arch/mips/include/asm/fw/fw.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2012 MIPS Technologies, Inc. | ||
7 | */ | ||
8 | #ifndef __ASM_FW_H_ | ||
9 | #define __ASM_FW_H_ | ||
10 | |||
11 | #include <asm/bootinfo.h> /* For cleaner code... */ | ||
12 | |||
13 | enum fw_memtypes { | ||
14 | fw_dontuse, | ||
15 | fw_code, | ||
16 | fw_free, | ||
17 | }; | ||
18 | |||
19 | typedef struct { | ||
20 | unsigned long base; /* Within KSEG0 */ | ||
21 | unsigned int size; /* bytes */ | ||
22 | enum fw_memtypes type; /* fw_memtypes */ | ||
23 | } fw_memblock_t; | ||
24 | |||
25 | /* Maximum number of memory block descriptors. */ | ||
26 | #define FW_MAX_MEMBLOCKS 32 | ||
27 | |||
28 | extern int fw_argc; | ||
29 | extern int *_fw_argv; | ||
30 | extern int *_fw_envp; | ||
31 | |||
32 | /* | ||
33 | * Most firmware like YAMON, PMON, etc. pass arguments and environment | ||
34 | * variables as 32-bit pointers. These take care of sign extension. | ||
35 | */ | ||
36 | #define fw_argv(index) ((char *)(long)_fw_argv[(index)]) | ||
37 | #define fw_envp(index) ((char *)(long)_fw_envp[(index)]) | ||
38 | |||
39 | extern void fw_init_cmdline(void); | ||
40 | extern char *fw_getcmdline(void); | ||
41 | extern fw_memblock_t *fw_getmdesc(void); | ||
42 | extern void fw_meminit(void); | ||
43 | extern char *fw_getenv(char *name); | ||
44 | extern unsigned long fw_getenvl(char *name); | ||
45 | extern void fw_init_early_console(char port); | ||
46 | |||
47 | #endif /* __ASM_FW_H_ */ | ||
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index bdc9786ab5a7..7153b32de18e 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h | |||
@@ -202,7 +202,7 @@ | |||
202 | #define GIC_VPE_WD_COUNT0_OFS 0x0094 | 202 | #define GIC_VPE_WD_COUNT0_OFS 0x0094 |
203 | #define GIC_VPE_WD_INITIAL0_OFS 0x0098 | 203 | #define GIC_VPE_WD_INITIAL0_OFS 0x0098 |
204 | #define GIC_VPE_COMPARE_LO_OFS 0x00a0 | 204 | #define GIC_VPE_COMPARE_LO_OFS 0x00a0 |
205 | #define GIC_VPE_COMPARE_HI 0x00a4 | 205 | #define GIC_VPE_COMPARE_HI_OFS 0x00a4 |
206 | 206 | ||
207 | #define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 | 207 | #define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 |
208 | #define GIC_VPE_EIC_SS(intr) \ | 208 | #define GIC_VPE_EIC_SS(intr) \ |
@@ -359,7 +359,11 @@ struct gic_shared_intr_map { | |||
359 | /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ | 359 | /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ |
360 | #define GIC_PIN_TO_VEC_OFFSET (1) | 360 | #define GIC_PIN_TO_VEC_OFFSET (1) |
361 | 361 | ||
362 | extern int gic_present; | 362 | #include <linux/clocksource.h> |
363 | #include <linux/irq.h> | ||
364 | |||
365 | extern unsigned int gic_present; | ||
366 | extern unsigned int gic_frequency; | ||
363 | extern unsigned long _gic_base; | 367 | extern unsigned long _gic_base; |
364 | extern unsigned int gic_irq_base; | 368 | extern unsigned int gic_irq_base; |
365 | extern unsigned int gic_irq_flags[]; | 369 | extern unsigned int gic_irq_flags[]; |
@@ -368,18 +372,20 @@ extern struct gic_shared_intr_map gic_shared_intr_map[]; | |||
368 | extern void gic_init(unsigned long gic_base_addr, | 372 | extern void gic_init(unsigned long gic_base_addr, |
369 | unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, | 373 | unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, |
370 | unsigned int intrmap_size, unsigned int irqbase); | 374 | unsigned int intrmap_size, unsigned int irqbase); |
371 | |||
372 | extern void gic_clocksource_init(unsigned int); | 375 | extern void gic_clocksource_init(unsigned int); |
373 | extern unsigned int gic_get_int(void); | 376 | extern unsigned int gic_compare_int (void); |
377 | extern cycle_t gic_read_count(void); | ||
378 | extern cycle_t gic_read_compare(void); | ||
379 | extern void gic_write_compare(cycle_t cnt); | ||
374 | extern void gic_send_ipi(unsigned int intr); | 380 | extern void gic_send_ipi(unsigned int intr); |
375 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); | 381 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); |
376 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); | 382 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); |
377 | extern void gic_bind_eic_interrupt(int irq, int set); | 383 | extern void gic_bind_eic_interrupt(int irq, int set); |
378 | extern unsigned int gic_get_timer_pending(void); | 384 | extern unsigned int gic_get_timer_pending(void); |
385 | extern unsigned int gic_get_int(void); | ||
379 | extern void gic_enable_interrupt(int irq_vec); | 386 | extern void gic_enable_interrupt(int irq_vec); |
380 | extern void gic_disable_interrupt(int irq_vec); | 387 | extern void gic_disable_interrupt(int irq_vec); |
381 | extern void gic_irq_ack(struct irq_data *d); | 388 | extern void gic_irq_ack(struct irq_data *d); |
382 | extern void gic_finish_irq(struct irq_data *d); | 389 | extern void gic_finish_irq(struct irq_data *d); |
383 | extern void gic_platform_init(int irqs, struct irq_chip *irq_controller); | 390 | extern void gic_platform_init(int irqs, struct irq_chip *irq_controller); |
384 | |||
385 | #endif /* _ASM_GICREGS_H */ | 391 | #endif /* _ASM_GICREGS_H */ |
diff --git a/arch/mips/include/asm/inst.h b/arch/mips/include/asm/inst.h index f1eadf764071..22912f78401c 100644 --- a/arch/mips/include/asm/inst.h +++ b/arch/mips/include/asm/inst.h | |||
@@ -73,4 +73,16 @@ | |||
73 | 73 | ||
74 | typedef unsigned int mips_instruction; | 74 | typedef unsigned int mips_instruction; |
75 | 75 | ||
76 | /* microMIPS instruction decode structure. Do NOT export!!! */ | ||
77 | struct mm_decoded_insn { | ||
78 | mips_instruction insn; | ||
79 | mips_instruction next_insn; | ||
80 | int pc_inc; | ||
81 | int next_pc_inc; | ||
82 | int micro_mips_mode; | ||
83 | }; | ||
84 | |||
85 | /* Recode table from 16-bit register notation to 32-bit GPR. Do NOT export!!! */ | ||
86 | extern const int reg16to32[]; | ||
87 | |||
76 | #endif /* _ASM_INST_H */ | 88 | #endif /* _ASM_INST_H */ |
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 143875c6c95a..e68781e18387 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h | |||
@@ -336,7 +336,7 @@ enum emulation_result { | |||
336 | #define VPN2_MASK 0xffffe000 | 336 | #define VPN2_MASK 0xffffe000 |
337 | #define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && ((x).tlb_lo1 & MIPS3_PG_G)) | 337 | #define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && ((x).tlb_lo1 & MIPS3_PG_G)) |
338 | #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) | 338 | #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) |
339 | #define TLB_ASID(x) ((x).tlb_hi & ASID_MASK) | 339 | #define TLB_ASID(x) (ASID_MASK((x).tlb_hi)) |
340 | #define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) ? ((x).tlb_lo1 & MIPS3_PG_V) : ((x).tlb_lo0 & MIPS3_PG_V)) | 340 | #define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) ? ((x).tlb_lo1 & MIPS3_PG_V) : ((x).tlb_lo0 & MIPS3_PG_V)) |
341 | 341 | ||
342 | struct kvm_mips_tlb { | 342 | struct kvm_mips_tlb { |
diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h index 9c95177f7a7e..fe23034aaf72 100644 --- a/arch/mips/include/asm/mach-generic/dma-coherence.h +++ b/arch/mips/include/asm/mach-generic/dma-coherence.h | |||
@@ -61,9 +61,8 @@ static inline int plat_device_is_coherent(struct device *dev) | |||
61 | { | 61 | { |
62 | #ifdef CONFIG_DMA_COHERENT | 62 | #ifdef CONFIG_DMA_COHERENT |
63 | return 1; | 63 | return 1; |
64 | #endif | 64 | #else |
65 | #ifdef CONFIG_DMA_NONCOHERENT | 65 | return coherentio; |
66 | return 0; | ||
67 | #endif | 66 | #endif |
68 | } | 67 | } |
69 | 68 | ||
diff --git a/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h index 193c0912d38e..bfbd7035d4c5 100644 --- a/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h | |||
@@ -28,7 +28,11 @@ | |||
28 | /* #define cpu_has_prefetch ? */ | 28 | /* #define cpu_has_prefetch ? */ |
29 | #define cpu_has_mcheck 1 | 29 | #define cpu_has_mcheck 1 |
30 | /* #define cpu_has_ejtag ? */ | 30 | /* #define cpu_has_ejtag ? */ |
31 | #ifdef CONFIG_CPU_MICROMIPS | ||
32 | #define cpu_has_llsc 0 | ||
33 | #else | ||
31 | #define cpu_has_llsc 1 | 34 | #define cpu_has_llsc 1 |
35 | #endif | ||
32 | /* #define cpu_has_vtag_icache ? */ | 36 | /* #define cpu_has_vtag_icache ? */ |
33 | /* #define cpu_has_dc_aliases ? */ | 37 | /* #define cpu_has_dc_aliases ? */ |
34 | /* #define cpu_has_ic_fills_f_dc ? */ | 38 | /* #define cpu_has_ic_fills_f_dc ? */ |
diff --git a/arch/mips/include/asm/mips-boards/generic.h b/arch/mips/include/asm/mips-boards/generic.h index 44a09a64160a..bd9746fbe4af 100644 --- a/arch/mips/include/asm/mips-boards/generic.h +++ b/arch/mips/include/asm/mips-boards/generic.h | |||
@@ -83,4 +83,7 @@ extern void mips_pcibios_init(void); | |||
83 | #define mips_pcibios_init() do { } while (0) | 83 | #define mips_pcibios_init() do { } while (0) |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | extern void mips_scroll_message(void); | ||
87 | extern void mips_display_message(const char *str); | ||
88 | |||
86 | #endif /* __ASM_MIPS_BOARDS_GENERIC_H */ | 89 | #endif /* __ASM_MIPS_BOARDS_GENERIC_H */ |
diff --git a/arch/mips/include/asm/mips-boards/prom.h b/arch/mips/include/asm/mips-boards/prom.h deleted file mode 100644 index e7aed3e4ff58..000000000000 --- a/arch/mips/include/asm/mips-boards/prom.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * ######################################################################## | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | ||
20 | * ######################################################################## | ||
21 | * | ||
22 | * MIPS boards bootprom interface for the Linux kernel. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #ifndef _MIPS_PROM_H | ||
27 | #define _MIPS_PROM_H | ||
28 | |||
29 | extern char *prom_getcmdline(void); | ||
30 | extern char *prom_getenv(char *name); | ||
31 | extern void prom_init_cmdline(void); | ||
32 | extern void prom_meminit(void); | ||
33 | extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); | ||
34 | extern void mips_display_message(const char *str); | ||
35 | extern void mips_display_word(unsigned int num); | ||
36 | extern void mips_scroll_message(void); | ||
37 | extern int get_ethernet_addr(char *ethernet_addr); | ||
38 | |||
39 | /* Memory descriptor management. */ | ||
40 | #define PROM_MAX_PMEMBLOCKS 32 | ||
41 | struct prom_pmemblock { | ||
42 | unsigned long base; /* Within KSEG0. */ | ||
43 | unsigned int size; /* In bytes. */ | ||
44 | unsigned int type; /* free or prom memory */ | ||
45 | }; | ||
46 | |||
47 | #endif /* !(_MIPS_PROM_H) */ | ||
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 0da44d422f5b..87e6207b05e4 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -596,6 +596,7 @@ | |||
596 | #define MIPS_CONF3_RXI (_ULCAST_(1) << 12) | 596 | #define MIPS_CONF3_RXI (_ULCAST_(1) << 12) |
597 | #define MIPS_CONF3_ULRI (_ULCAST_(1) << 13) | 597 | #define MIPS_CONF3_ULRI (_ULCAST_(1) << 13) |
598 | #define MIPS_CONF3_ISA (_ULCAST_(3) << 14) | 598 | #define MIPS_CONF3_ISA (_ULCAST_(3) << 14) |
599 | #define MIPS_CONF3_ISA_OE (_ULCAST_(3) << 16) | ||
599 | #define MIPS_CONF3_VZ (_ULCAST_(1) << 23) | 600 | #define MIPS_CONF3_VZ (_ULCAST_(1) << 23) |
600 | 601 | ||
601 | #define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0) | 602 | #define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0) |
@@ -623,6 +624,24 @@ | |||
623 | #ifndef __ASSEMBLY__ | 624 | #ifndef __ASSEMBLY__ |
624 | 625 | ||
625 | /* | 626 | /* |
627 | * Macros for handling the ISA mode bit for microMIPS. | ||
628 | */ | ||
629 | #define get_isa16_mode(x) ((x) & 0x1) | ||
630 | #define msk_isa16_mode(x) ((x) & ~0x1) | ||
631 | #define set_isa16_mode(x) do { (x) |= 0x1; } while(0) | ||
632 | |||
633 | /* | ||
634 | * microMIPS instructions can be 16-bit or 32-bit in length. This | ||
635 | * returns a 1 if the instruction is 16-bit and a 0 if 32-bit. | ||
636 | */ | ||
637 | static inline int mm_insn_16bit(u16 insn) | ||
638 | { | ||
639 | u16 opcode = (insn >> 10) & 0x7; | ||
640 | |||
641 | return (opcode >= 1 && opcode <= 3) ? 1 : 0; | ||
642 | } | ||
643 | |||
644 | /* | ||
626 | * Functions to access the R10000 performance counters. These are basically | 645 | * Functions to access the R10000 performance counters. These are basically |
627 | * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit | 646 | * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit |
628 | * performance counter number encoded into bits 1 ... 5 of the instruction. | 647 | * performance counter number encoded into bits 1 ... 5 of the instruction. |
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 820116067c10..1554721e4808 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h | |||
@@ -67,45 +67,68 @@ extern unsigned long pgd_current[]; | |||
67 | TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) | 67 | TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) |
68 | #endif | 68 | #endif |
69 | #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ | 69 | #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ |
70 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | ||
71 | 70 | ||
72 | #define ASID_INC 0x40 | 71 | #define ASID_INC(asid) \ |
73 | #define ASID_MASK 0xfc0 | 72 | ({ \ |
74 | 73 | unsigned long __asid = asid; \ | |
75 | #elif defined(CONFIG_CPU_R8000) | 74 | __asm__("1:\taddiu\t%0,1\t\t\t\t# patched\n\t" \ |
76 | 75 | ".section\t__asid_inc,\"a\"\n\t" \ | |
77 | #define ASID_INC 0x10 | 76 | ".word\t1b\n\t" \ |
78 | #define ASID_MASK 0xff0 | 77 | ".previous" \ |
79 | 78 | :"=r" (__asid) \ | |
80 | #elif defined(CONFIG_MIPS_MT_SMTC) | 79 | :"0" (__asid)); \ |
81 | 80 | __asid; \ | |
82 | #define ASID_INC 0x1 | 81 | }) |
83 | extern unsigned long smtc_asid_mask; | 82 | #define ASID_MASK(asid) \ |
84 | #define ASID_MASK (smtc_asid_mask) | 83 | ({ \ |
85 | #define HW_ASID_MASK 0xff | 84 | unsigned long __asid = asid; \ |
86 | /* End SMTC/34K debug hack */ | 85 | __asm__("1:\tandi\t%0,%1,0xfc0\t\t\t# patched\n\t" \ |
87 | #else /* FIXME: not correct for R6000 */ | 86 | ".section\t__asid_mask,\"a\"\n\t" \ |
88 | 87 | ".word\t1b\n\t" \ | |
89 | #define ASID_INC 0x1 | 88 | ".previous" \ |
90 | #define ASID_MASK 0xff | 89 | :"=r" (__asid) \ |
90 | :"r" (__asid)); \ | ||
91 | __asid; \ | ||
92 | }) | ||
93 | #define ASID_VERSION_MASK \ | ||
94 | ({ \ | ||
95 | unsigned long __asid; \ | ||
96 | __asm__("1:\taddiu\t%0,$0,0xff00\t\t\t\t# patched\n\t" \ | ||
97 | ".section\t__asid_version_mask,\"a\"\n\t" \ | ||
98 | ".word\t1b\n\t" \ | ||
99 | ".previous" \ | ||
100 | :"=r" (__asid)); \ | ||
101 | __asid; \ | ||
102 | }) | ||
103 | #define ASID_FIRST_VERSION \ | ||
104 | ({ \ | ||
105 | unsigned long __asid = asid; \ | ||
106 | __asm__("1:\tli\t%0,0x100\t\t\t\t# patched\n\t" \ | ||
107 | ".section\t__asid_first_version,\"a\"\n\t" \ | ||
108 | ".word\t1b\n\t" \ | ||
109 | ".previous" \ | ||
110 | :"=r" (__asid)); \ | ||
111 | __asid; \ | ||
112 | }) | ||
113 | |||
114 | #define ASID_FIRST_VERSION_R3000 0x1000 | ||
115 | #define ASID_FIRST_VERSION_R4000 0x100 | ||
116 | #define ASID_FIRST_VERSION_R8000 0x1000 | ||
117 | #define ASID_FIRST_VERSION_RM9000 0x1000 | ||
91 | 118 | ||
119 | #ifdef CONFIG_MIPS_MT_SMTC | ||
120 | #define SMTC_HW_ASID_MASK 0xff | ||
121 | extern unsigned int smtc_asid_mask; | ||
92 | #endif | 122 | #endif |
93 | 123 | ||
94 | #define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) | 124 | #define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) |
95 | #define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) | 125 | #define cpu_asid(cpu, mm) ASID_MASK(cpu_context((cpu), (mm))) |
96 | #define asid_cache(cpu) (cpu_data[cpu].asid_cache) | 126 | #define asid_cache(cpu) (cpu_data[cpu].asid_cache) |
97 | 127 | ||
98 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | 128 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) |
99 | { | 129 | { |
100 | } | 130 | } |
101 | 131 | ||
102 | /* | ||
103 | * All unused by hardware upper bits will be considered | ||
104 | * as a software asid extension. | ||
105 | */ | ||
106 | #define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1))) | ||
107 | #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1) | ||
108 | |||
109 | #ifndef CONFIG_MIPS_MT_SMTC | 132 | #ifndef CONFIG_MIPS_MT_SMTC |
110 | /* Normal, classic MIPS get_new_mmu_context */ | 133 | /* Normal, classic MIPS get_new_mmu_context */ |
111 | static inline void | 134 | static inline void |
@@ -114,7 +137,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
114 | extern void kvm_local_flush_tlb_all(void); | 137 | extern void kvm_local_flush_tlb_all(void); |
115 | unsigned long asid = asid_cache(cpu); | 138 | unsigned long asid = asid_cache(cpu); |
116 | 139 | ||
117 | if (! ((asid += ASID_INC) & ASID_MASK) ) { | 140 | if (!ASID_MASK((asid = ASID_INC(asid)))) { |
118 | if (cpu_has_vtag_icache) | 141 | if (cpu_has_vtag_icache) |
119 | flush_icache_all(); | 142 | flush_icache_all(); |
120 | #ifdef CONFIG_VIRTUALIZATION | 143 | #ifdef CONFIG_VIRTUALIZATION |
@@ -177,7 +200,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
177 | * free up the ASID value for use and flush any old | 200 | * free up the ASID value for use and flush any old |
178 | * instances of it from the TLB. | 201 | * instances of it from the TLB. |
179 | */ | 202 | */ |
180 | oldasid = (read_c0_entryhi() & ASID_MASK); | 203 | oldasid = ASID_MASK(read_c0_entryhi()); |
181 | if(smtc_live_asid[mytlb][oldasid]) { | 204 | if(smtc_live_asid[mytlb][oldasid]) { |
182 | smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); | 205 | smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); |
183 | if(smtc_live_asid[mytlb][oldasid] == 0) | 206 | if(smtc_live_asid[mytlb][oldasid] == 0) |
@@ -188,7 +211,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
188 | * having ASID_MASK smaller than the hardware maximum, | 211 | * having ASID_MASK smaller than the hardware maximum, |
189 | * make sure no "soft" bits become "hard"... | 212 | * make sure no "soft" bits become "hard"... |
190 | */ | 213 | */ |
191 | write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | | 214 | write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) | |
192 | cpu_asid(cpu, next)); | 215 | cpu_asid(cpu, next)); |
193 | ehb(); /* Make sure it propagates to TCStatus */ | 216 | ehb(); /* Make sure it propagates to TCStatus */ |
194 | evpe(mtflags); | 217 | evpe(mtflags); |
@@ -241,15 +264,15 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) | |||
241 | #ifdef CONFIG_MIPS_MT_SMTC | 264 | #ifdef CONFIG_MIPS_MT_SMTC |
242 | /* See comments for similar code above */ | 265 | /* See comments for similar code above */ |
243 | mtflags = dvpe(); | 266 | mtflags = dvpe(); |
244 | oldasid = read_c0_entryhi() & ASID_MASK; | 267 | oldasid = ASID_MASK(read_c0_entryhi()); |
245 | if(smtc_live_asid[mytlb][oldasid]) { | 268 | if(smtc_live_asid[mytlb][oldasid]) { |
246 | smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); | 269 | smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); |
247 | if(smtc_live_asid[mytlb][oldasid] == 0) | 270 | if(smtc_live_asid[mytlb][oldasid] == 0) |
248 | smtc_flush_tlb_asid(oldasid); | 271 | smtc_flush_tlb_asid(oldasid); |
249 | } | 272 | } |
250 | /* See comments for similar code above */ | 273 | /* See comments for similar code above */ |
251 | write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | | 274 | write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) | |
252 | cpu_asid(cpu, next)); | 275 | cpu_asid(cpu, next)); |
253 | ehb(); /* Make sure it propagates to TCStatus */ | 276 | ehb(); /* Make sure it propagates to TCStatus */ |
254 | evpe(mtflags); | 277 | evpe(mtflags); |
255 | #else | 278 | #else |
@@ -286,14 +309,14 @@ drop_mmu_context(struct mm_struct *mm, unsigned cpu) | |||
286 | #ifdef CONFIG_MIPS_MT_SMTC | 309 | #ifdef CONFIG_MIPS_MT_SMTC |
287 | /* See comments for similar code above */ | 310 | /* See comments for similar code above */ |
288 | prevvpe = dvpe(); | 311 | prevvpe = dvpe(); |
289 | oldasid = (read_c0_entryhi() & ASID_MASK); | 312 | oldasid = ASID_MASK(read_c0_entryhi()); |
290 | if (smtc_live_asid[mytlb][oldasid]) { | 313 | if (smtc_live_asid[mytlb][oldasid]) { |
291 | smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); | 314 | smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); |
292 | if(smtc_live_asid[mytlb][oldasid] == 0) | 315 | if(smtc_live_asid[mytlb][oldasid] == 0) |
293 | smtc_flush_tlb_asid(oldasid); | 316 | smtc_flush_tlb_asid(oldasid); |
294 | } | 317 | } |
295 | /* See comments for similar code above */ | 318 | /* See comments for similar code above */ |
296 | write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | 319 | write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) |
297 | | cpu_asid(cpu, mm)); | 320 | | cpu_asid(cpu, mm)); |
298 | ehb(); /* Make sure it propagates to TCStatus */ | 321 | ehb(); /* Make sure it propagates to TCStatus */ |
299 | evpe(prevvpe); | 322 | evpe(prevvpe); |
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index c99384018161..a89d1b10d027 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h | |||
@@ -139,7 +139,7 @@ | |||
139 | 1: move ra, k0 | 139 | 1: move ra, k0 |
140 | li k0, 3 | 140 | li k0, 3 |
141 | mtc0 k0, $22 | 141 | mtc0 k0, $22 |
142 | #endif /* CONFIG_CPU_LOONGSON2F */ | 142 | #endif /* CONFIG_CPU_JUMP_WORKAROUNDS */ |
143 | #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) | 143 | #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) |
144 | lui k1, %hi(kernelsp) | 144 | lui k1, %hi(kernelsp) |
145 | #else | 145 | #else |
@@ -189,6 +189,7 @@ | |||
189 | LONG_S $0, PT_R0(sp) | 189 | LONG_S $0, PT_R0(sp) |
190 | mfc0 v1, CP0_STATUS | 190 | mfc0 v1, CP0_STATUS |
191 | LONG_S $2, PT_R2(sp) | 191 | LONG_S $2, PT_R2(sp) |
192 | LONG_S v1, PT_STATUS(sp) | ||
192 | #ifdef CONFIG_MIPS_MT_SMTC | 193 | #ifdef CONFIG_MIPS_MT_SMTC |
193 | /* | 194 | /* |
194 | * Ideally, these instructions would be shuffled in | 195 | * Ideally, these instructions would be shuffled in |
@@ -200,21 +201,20 @@ | |||
200 | LONG_S k0, PT_TCSTATUS(sp) | 201 | LONG_S k0, PT_TCSTATUS(sp) |
201 | #endif /* CONFIG_MIPS_MT_SMTC */ | 202 | #endif /* CONFIG_MIPS_MT_SMTC */ |
202 | LONG_S $4, PT_R4(sp) | 203 | LONG_S $4, PT_R4(sp) |
203 | LONG_S $5, PT_R5(sp) | ||
204 | LONG_S v1, PT_STATUS(sp) | ||
205 | mfc0 v1, CP0_CAUSE | 204 | mfc0 v1, CP0_CAUSE |
206 | LONG_S $6, PT_R6(sp) | 205 | LONG_S $5, PT_R5(sp) |
207 | LONG_S $7, PT_R7(sp) | ||
208 | LONG_S v1, PT_CAUSE(sp) | 206 | LONG_S v1, PT_CAUSE(sp) |
207 | LONG_S $6, PT_R6(sp) | ||
209 | MFC0 v1, CP0_EPC | 208 | MFC0 v1, CP0_EPC |
209 | LONG_S $7, PT_R7(sp) | ||
210 | #ifdef CONFIG_64BIT | 210 | #ifdef CONFIG_64BIT |
211 | LONG_S $8, PT_R8(sp) | 211 | LONG_S $8, PT_R8(sp) |
212 | LONG_S $9, PT_R9(sp) | 212 | LONG_S $9, PT_R9(sp) |
213 | #endif | 213 | #endif |
214 | LONG_S v1, PT_EPC(sp) | ||
214 | LONG_S $25, PT_R25(sp) | 215 | LONG_S $25, PT_R25(sp) |
215 | LONG_S $28, PT_R28(sp) | 216 | LONG_S $28, PT_R28(sp) |
216 | LONG_S $31, PT_R31(sp) | 217 | LONG_S $31, PT_R31(sp) |
217 | LONG_S v1, PT_EPC(sp) | ||
218 | ori $28, sp, _THREAD_MASK | 218 | ori $28, sp, _THREAD_MASK |
219 | xori $28, _THREAD_MASK | 219 | xori $28, _THREAD_MASK |
220 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | 220 | #ifdef CONFIG_CPU_CAVIUM_OCTEON |
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index debc8009bd58..2d7b9df4542d 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h | |||
@@ -52,13 +52,15 @@ extern int (*perf_irq)(void); | |||
52 | */ | 52 | */ |
53 | extern unsigned int __weak get_c0_compare_int(void); | 53 | extern unsigned int __weak get_c0_compare_int(void); |
54 | extern int r4k_clockevent_init(void); | 54 | extern int r4k_clockevent_init(void); |
55 | extern int smtc_clockevent_init(void); | ||
56 | extern int gic_clockevent_init(void); | ||
55 | 57 | ||
56 | static inline int mips_clockevent_init(void) | 58 | static inline int mips_clockevent_init(void) |
57 | { | 59 | { |
58 | #ifdef CONFIG_MIPS_MT_SMTC | 60 | #ifdef CONFIG_MIPS_MT_SMTC |
59 | extern int smtc_clockevent_init(void); | ||
60 | |||
61 | return smtc_clockevent_init(); | 61 | return smtc_clockevent_init(); |
62 | #elif defined(CONFIG_CEVT_GIC) | ||
63 | return (gic_clockevent_init() | r4k_clockevent_init()); | ||
62 | #elif defined(CONFIG_CEVT_R4K) | 64 | #elif defined(CONFIG_CEVT_R4K) |
63 | return r4k_clockevent_init(); | 65 | return r4k_clockevent_init(); |
64 | #else | 66 | #else |
@@ -69,9 +71,7 @@ static inline int mips_clockevent_init(void) | |||
69 | /* | 71 | /* |
70 | * Initialize the count register as a clocksource | 72 | * Initialize the count register as a clocksource |
71 | */ | 73 | */ |
72 | #ifdef CONFIG_CSRC_R4K | ||
73 | extern int init_r4k_clocksource(void); | 74 | extern int init_r4k_clocksource(void); |
74 | #endif | ||
75 | 75 | ||
76 | static inline int init_mips_clocksource(void) | 76 | static inline int init_mips_clocksource(void) |
77 | { | 77 | { |
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index b46caab453a5..f3fa3750f577 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h | |||
@@ -270,6 +270,7 @@ do { \ | |||
270 | __asm__ __volatile__( \ | 270 | __asm__ __volatile__( \ |
271 | "1: " insn " %1, %3 \n" \ | 271 | "1: " insn " %1, %3 \n" \ |
272 | "2: \n" \ | 272 | "2: \n" \ |
273 | " .insn \n" \ | ||
273 | " .section .fixup,\"ax\" \n" \ | 274 | " .section .fixup,\"ax\" \n" \ |
274 | "3: li %0, %4 \n" \ | 275 | "3: li %0, %4 \n" \ |
275 | " j 2b \n" \ | 276 | " j 2b \n" \ |
@@ -296,7 +297,9 @@ do { \ | |||
296 | __asm__ __volatile__( \ | 297 | __asm__ __volatile__( \ |
297 | "1: lw %1, (%3) \n" \ | 298 | "1: lw %1, (%3) \n" \ |
298 | "2: lw %D1, 4(%3) \n" \ | 299 | "2: lw %D1, 4(%3) \n" \ |
299 | "3: .section .fixup,\"ax\" \n" \ | 300 | "3: \n" \ |
301 | " .insn \n" \ | ||
302 | " .section .fixup,\"ax\" \n" \ | ||
300 | "4: li %0, %4 \n" \ | 303 | "4: li %0, %4 \n" \ |
301 | " move %1, $0 \n" \ | 304 | " move %1, $0 \n" \ |
302 | " move %D1, $0 \n" \ | 305 | " move %D1, $0 \n" \ |
@@ -364,6 +367,7 @@ do { \ | |||
364 | __asm__ __volatile__( \ | 367 | __asm__ __volatile__( \ |
365 | "1: " insn " %z2, %3 # __put_user_asm\n" \ | 368 | "1: " insn " %z2, %3 # __put_user_asm\n" \ |
366 | "2: \n" \ | 369 | "2: \n" \ |
370 | " .insn \n" \ | ||
367 | " .section .fixup,\"ax\" \n" \ | 371 | " .section .fixup,\"ax\" \n" \ |
368 | "3: li %0, %4 \n" \ | 372 | "3: li %0, %4 \n" \ |
369 | " j 2b \n" \ | 373 | " j 2b \n" \ |
@@ -382,6 +386,7 @@ do { \ | |||
382 | "1: sw %2, (%3) # __put_user_asm_ll32 \n" \ | 386 | "1: sw %2, (%3) # __put_user_asm_ll32 \n" \ |
383 | "2: sw %D2, 4(%3) \n" \ | 387 | "2: sw %D2, 4(%3) \n" \ |
384 | "3: \n" \ | 388 | "3: \n" \ |
389 | " .insn \n" \ | ||
385 | " .section .fixup,\"ax\" \n" \ | 390 | " .section .fixup,\"ax\" \n" \ |
386 | "4: li %0, %4 \n" \ | 391 | "4: li %0, %4 \n" \ |
387 | " j 3b \n" \ | 392 | " j 3b \n" \ |
@@ -533,6 +538,7 @@ do { \ | |||
533 | __asm__ __volatile__( \ | 538 | __asm__ __volatile__( \ |
534 | "1: " insn " %1, %3 \n" \ | 539 | "1: " insn " %1, %3 \n" \ |
535 | "2: \n" \ | 540 | "2: \n" \ |
541 | " .insn \n" \ | ||
536 | " .section .fixup,\"ax\" \n" \ | 542 | " .section .fixup,\"ax\" \n" \ |
537 | "3: li %0, %4 \n" \ | 543 | "3: li %0, %4 \n" \ |
538 | " j 2b \n" \ | 544 | " j 2b \n" \ |
@@ -558,7 +564,9 @@ do { \ | |||
558 | "1: ulw %1, (%3) \n" \ | 564 | "1: ulw %1, (%3) \n" \ |
559 | "2: ulw %D1, 4(%3) \n" \ | 565 | "2: ulw %D1, 4(%3) \n" \ |
560 | " move %0, $0 \n" \ | 566 | " move %0, $0 \n" \ |
561 | "3: .section .fixup,\"ax\" \n" \ | 567 | "3: \n" \ |
568 | " .insn \n" \ | ||
569 | " .section .fixup,\"ax\" \n" \ | ||
562 | "4: li %0, %4 \n" \ | 570 | "4: li %0, %4 \n" \ |
563 | " move %1, $0 \n" \ | 571 | " move %1, $0 \n" \ |
564 | " move %D1, $0 \n" \ | 572 | " move %D1, $0 \n" \ |
@@ -625,6 +633,7 @@ do { \ | |||
625 | __asm__ __volatile__( \ | 633 | __asm__ __volatile__( \ |
626 | "1: " insn " %z2, %3 # __put_user_unaligned_asm\n" \ | 634 | "1: " insn " %z2, %3 # __put_user_unaligned_asm\n" \ |
627 | "2: \n" \ | 635 | "2: \n" \ |
636 | " .insn \n" \ | ||
628 | " .section .fixup,\"ax\" \n" \ | 637 | " .section .fixup,\"ax\" \n" \ |
629 | "3: li %0, %4 \n" \ | 638 | "3: li %0, %4 \n" \ |
630 | " j 2b \n" \ | 639 | " j 2b \n" \ |
@@ -643,6 +652,7 @@ do { \ | |||
643 | "1: sw %2, (%3) # __put_user_unaligned_asm_ll32 \n" \ | 652 | "1: sw %2, (%3) # __put_user_unaligned_asm_ll32 \n" \ |
644 | "2: sw %D2, 4(%3) \n" \ | 653 | "2: sw %D2, 4(%3) \n" \ |
645 | "3: \n" \ | 654 | "3: \n" \ |
655 | " .insn \n" \ | ||
646 | " .section .fixup,\"ax\" \n" \ | 656 | " .section .fixup,\"ax\" \n" \ |
647 | "4: li %0, %4 \n" \ | 657 | "4: li %0, %4 \n" \ |
648 | " j 3b \n" \ | 658 | " j 3b \n" \ |
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index 058e941626a6..370d967725c2 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer | 6 | * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer |
7 | * Copyright (C) 2005 Maciej W. Rozycki | 7 | * Copyright (C) 2005 Maciej W. Rozycki |
8 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | 8 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) |
9 | * Copyright (C) 2012 MIPS Technologies, Inc. | 9 | * Copyright (C) 2012, 2013 MIPS Technologies, Inc. All rights reserved. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
@@ -22,44 +22,75 @@ | |||
22 | #define UASM_EXPORT_SYMBOL(sym) | 22 | #define UASM_EXPORT_SYMBOL(sym) |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #define _UASM_ISA_CLASSIC 0 | ||
26 | #define _UASM_ISA_MICROMIPS 1 | ||
27 | |||
28 | #ifndef UASM_ISA | ||
29 | #ifdef CONFIG_CPU_MICROMIPS | ||
30 | #define UASM_ISA _UASM_ISA_MICROMIPS | ||
31 | #else | ||
32 | #define UASM_ISA _UASM_ISA_CLASSIC | ||
33 | #endif | ||
34 | #endif | ||
35 | |||
36 | #if (UASM_ISA == _UASM_ISA_CLASSIC) | ||
37 | #ifdef CONFIG_CPU_MICROMIPS | ||
38 | #define ISAOPC(op) CL_uasm_i##op | ||
39 | #define ISAFUNC(x) CL_##x | ||
40 | #else | ||
41 | #define ISAOPC(op) uasm_i##op | ||
42 | #define ISAFUNC(x) x | ||
43 | #endif | ||
44 | #elif (UASM_ISA == _UASM_ISA_MICROMIPS) | ||
45 | #ifdef CONFIG_CPU_MICROMIPS | ||
46 | #define ISAOPC(op) uasm_i##op | ||
47 | #define ISAFUNC(x) x | ||
48 | #else | ||
49 | #define ISAOPC(op) MM_uasm_i##op | ||
50 | #define ISAFUNC(x) MM_##x | ||
51 | #endif | ||
52 | #else | ||
53 | #error Unsupported micro-assembler ISA!!! | ||
54 | #endif | ||
55 | |||
25 | #define Ip_u1u2u3(op) \ | 56 | #define Ip_u1u2u3(op) \ |
26 | void __uasminit \ | 57 | void __uasminit \ |
27 | uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c) | 58 | ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c) |
28 | 59 | ||
29 | #define Ip_u2u1u3(op) \ | 60 | #define Ip_u2u1u3(op) \ |
30 | void __uasminit \ | 61 | void __uasminit \ |
31 | uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c) | 62 | ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c) |
32 | 63 | ||
33 | #define Ip_u3u1u2(op) \ | 64 | #define Ip_u3u1u2(op) \ |
34 | void __uasminit \ | 65 | void __uasminit \ |
35 | uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c) | 66 | ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c) |
36 | 67 | ||
37 | #define Ip_u1u2s3(op) \ | 68 | #define Ip_u1u2s3(op) \ |
38 | void __uasminit \ | 69 | void __uasminit \ |
39 | uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c) | 70 | ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, signed int c) |
40 | 71 | ||
41 | #define Ip_u2s3u1(op) \ | 72 | #define Ip_u2s3u1(op) \ |
42 | void __uasminit \ | 73 | void __uasminit \ |
43 | uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c) | 74 | ISAOPC(op)(u32 **buf, unsigned int a, signed int b, unsigned int c) |
44 | 75 | ||
45 | #define Ip_u2u1s3(op) \ | 76 | #define Ip_u2u1s3(op) \ |
46 | void __uasminit \ | 77 | void __uasminit \ |
47 | uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c) | 78 | ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, signed int c) |
48 | 79 | ||
49 | #define Ip_u2u1msbu3(op) \ | 80 | #define Ip_u2u1msbu3(op) \ |
50 | void __uasminit \ | 81 | void __uasminit \ |
51 | uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \ | 82 | ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \ |
52 | unsigned int d) | 83 | unsigned int d) |
53 | 84 | ||
54 | #define Ip_u1u2(op) \ | 85 | #define Ip_u1u2(op) \ |
55 | void __uasminit uasm_i##op(u32 **buf, unsigned int a, unsigned int b) | 86 | void __uasminit ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b) |
56 | 87 | ||
57 | #define Ip_u1s2(op) \ | 88 | #define Ip_u1s2(op) \ |
58 | void __uasminit uasm_i##op(u32 **buf, unsigned int a, signed int b) | 89 | void __uasminit ISAOPC(op)(u32 **buf, unsigned int a, signed int b) |
59 | 90 | ||
60 | #define Ip_u1(op) void __uasminit uasm_i##op(u32 **buf, unsigned int a) | 91 | #define Ip_u1(op) void __uasminit ISAOPC(op)(u32 **buf, unsigned int a) |
61 | 92 | ||
62 | #define Ip_0(op) void __uasminit uasm_i##op(u32 **buf) | 93 | #define Ip_0(op) void __uasminit ISAOPC(op)(u32 **buf) |
63 | 94 | ||
64 | Ip_u2u1s3(_addiu); | 95 | Ip_u2u1s3(_addiu); |
65 | Ip_u3u1u2(_addu); | 96 | Ip_u3u1u2(_addu); |
@@ -132,19 +163,20 @@ struct uasm_label { | |||
132 | int lab; | 163 | int lab; |
133 | }; | 164 | }; |
134 | 165 | ||
135 | void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid); | 166 | void __uasminit ISAFUNC(uasm_build_label)(struct uasm_label **lab, u32 *addr, |
167 | int lid); | ||
136 | #ifdef CONFIG_64BIT | 168 | #ifdef CONFIG_64BIT |
137 | int uasm_in_compat_space_p(long addr); | 169 | int ISAFUNC(uasm_in_compat_space_p)(long addr); |
138 | #endif | 170 | #endif |
139 | int uasm_rel_hi(long val); | 171 | int ISAFUNC(uasm_rel_hi)(long val); |
140 | int uasm_rel_lo(long val); | 172 | int ISAFUNC(uasm_rel_lo)(long val); |
141 | void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr); | 173 | void ISAFUNC(UASM_i_LA_mostly)(u32 **buf, unsigned int rs, long addr); |
142 | void UASM_i_LA(u32 **buf, unsigned int rs, long addr); | 174 | void ISAFUNC(UASM_i_LA)(u32 **buf, unsigned int rs, long addr); |
143 | 175 | ||
144 | #define UASM_L_LA(lb) \ | 176 | #define UASM_L_LA(lb) \ |
145 | static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \ | 177 | static inline void __uasminit ISAFUNC(uasm_l##lb)(struct uasm_label **lab, u32 *addr) \ |
146 | { \ | 178 | { \ |
147 | uasm_build_label(lab, addr, label##lb); \ | 179 | ISAFUNC(uasm_build_label)(lab, addr, label##lb); \ |
148 | } | 180 | } |
149 | 181 | ||
150 | /* convenience macros for instructions */ | 182 | /* convenience macros for instructions */ |
@@ -196,27 +228,27 @@ static inline void uasm_i_drotr_safe(u32 **p, unsigned int a1, | |||
196 | unsigned int a2, unsigned int a3) | 228 | unsigned int a2, unsigned int a3) |
197 | { | 229 | { |
198 | if (a3 < 32) | 230 | if (a3 < 32) |
199 | uasm_i_drotr(p, a1, a2, a3); | 231 | ISAOPC(_drotr)(p, a1, a2, a3); |
200 | else | 232 | else |
201 | uasm_i_drotr32(p, a1, a2, a3 - 32); | 233 | ISAOPC(_drotr32)(p, a1, a2, a3 - 32); |
202 | } | 234 | } |
203 | 235 | ||
204 | static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1, | 236 | static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1, |
205 | unsigned int a2, unsigned int a3) | 237 | unsigned int a2, unsigned int a3) |
206 | { | 238 | { |
207 | if (a3 < 32) | 239 | if (a3 < 32) |
208 | uasm_i_dsll(p, a1, a2, a3); | 240 | ISAOPC(_dsll)(p, a1, a2, a3); |
209 | else | 241 | else |
210 | uasm_i_dsll32(p, a1, a2, a3 - 32); | 242 | ISAOPC(_dsll32)(p, a1, a2, a3 - 32); |
211 | } | 243 | } |
212 | 244 | ||
213 | static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1, | 245 | static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1, |
214 | unsigned int a2, unsigned int a3) | 246 | unsigned int a2, unsigned int a3) |
215 | { | 247 | { |
216 | if (a3 < 32) | 248 | if (a3 < 32) |
217 | uasm_i_dsrl(p, a1, a2, a3); | 249 | ISAOPC(_dsrl)(p, a1, a2, a3); |
218 | else | 250 | else |
219 | uasm_i_dsrl32(p, a1, a2, a3 - 32); | 251 | ISAOPC(_dsrl32)(p, a1, a2, a3 - 32); |
220 | } | 252 | } |
221 | 253 | ||
222 | /* Handle relocations. */ | 254 | /* Handle relocations. */ |
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index 4d078815eaa5..0f4aec2ad1e6 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h | |||
@@ -7,6 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 1996, 2000 by Ralf Baechle | 8 | * Copyright (C) 1996, 2000 by Ralf Baechle |
9 | * Copyright (C) 2006 by Thiemo Seufer | 9 | * Copyright (C) 2006 by Thiemo Seufer |
10 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
10 | */ | 11 | */ |
11 | #ifndef _UAPI_ASM_INST_H | 12 | #ifndef _UAPI_ASM_INST_H |
12 | #define _UAPI_ASM_INST_H | 13 | #define _UAPI_ASM_INST_H |
@@ -193,6 +194,282 @@ enum lx_func { | |||
193 | }; | 194 | }; |
194 | 195 | ||
195 | /* | 196 | /* |
197 | * (microMIPS) Major opcodes. | ||
198 | */ | ||
199 | enum mm_major_op { | ||
200 | mm_pool32a_op, mm_pool16a_op, mm_lbu16_op, mm_move16_op, | ||
201 | mm_addi32_op, mm_lbu32_op, mm_sb32_op, mm_lb32_op, | ||
202 | mm_pool32b_op, mm_pool16b_op, mm_lhu16_op, mm_andi16_op, | ||
203 | mm_addiu32_op, mm_lhu32_op, mm_sh32_op, mm_lh32_op, | ||
204 | mm_pool32i_op, mm_pool16c_op, mm_lwsp16_op, mm_pool16d_op, | ||
205 | mm_ori32_op, mm_pool32f_op, mm_reserved1_op, mm_reserved2_op, | ||
206 | mm_pool32c_op, mm_lwgp16_op, mm_lw16_op, mm_pool16e_op, | ||
207 | mm_xori32_op, mm_jals32_op, mm_addiupc_op, mm_reserved3_op, | ||
208 | mm_reserved4_op, mm_pool16f_op, mm_sb16_op, mm_beqz16_op, | ||
209 | mm_slti32_op, mm_beq32_op, mm_swc132_op, mm_lwc132_op, | ||
210 | mm_reserved5_op, mm_reserved6_op, mm_sh16_op, mm_bnez16_op, | ||
211 | mm_sltiu32_op, mm_bne32_op, mm_sdc132_op, mm_ldc132_op, | ||
212 | mm_reserved7_op, mm_reserved8_op, mm_swsp16_op, mm_b16_op, | ||
213 | mm_andi32_op, mm_j32_op, mm_sd32_op, mm_ld32_op, | ||
214 | mm_reserved11_op, mm_reserved12_op, mm_sw16_op, mm_li16_op, | ||
215 | mm_jalx32_op, mm_jal32_op, mm_sw32_op, mm_lw32_op, | ||
216 | }; | ||
217 | |||
218 | /* | ||
219 | * (microMIPS) POOL32I minor opcodes. | ||
220 | */ | ||
221 | enum mm_32i_minor_op { | ||
222 | mm_bltz_op, mm_bltzal_op, mm_bgez_op, mm_bgezal_op, | ||
223 | mm_blez_op, mm_bnezc_op, mm_bgtz_op, mm_beqzc_op, | ||
224 | mm_tlti_op, mm_tgei_op, mm_tltiu_op, mm_tgeiu_op, | ||
225 | mm_tnei_op, mm_lui_op, mm_teqi_op, mm_reserved13_op, | ||
226 | mm_synci_op, mm_bltzals_op, mm_reserved14_op, mm_bgezals_op, | ||
227 | mm_bc2f_op, mm_bc2t_op, mm_reserved15_op, mm_reserved16_op, | ||
228 | mm_reserved17_op, mm_reserved18_op, mm_bposge64_op, mm_bposge32_op, | ||
229 | mm_bc1f_op, mm_bc1t_op, mm_reserved19_op, mm_reserved20_op, | ||
230 | mm_bc1any2f_op, mm_bc1any2t_op, mm_bc1any4f_op, mm_bc1any4t_op, | ||
231 | }; | ||
232 | |||
233 | /* | ||
234 | * (microMIPS) POOL32A minor opcodes. | ||
235 | */ | ||
236 | enum mm_32a_minor_op { | ||
237 | mm_sll32_op = 0x000, | ||
238 | mm_ins_op = 0x00c, | ||
239 | mm_ext_op = 0x02c, | ||
240 | mm_pool32axf_op = 0x03c, | ||
241 | mm_srl32_op = 0x040, | ||
242 | mm_sra_op = 0x080, | ||
243 | mm_rotr_op = 0x0c0, | ||
244 | mm_lwxs_op = 0x118, | ||
245 | mm_addu32_op = 0x150, | ||
246 | mm_subu32_op = 0x1d0, | ||
247 | mm_and_op = 0x250, | ||
248 | mm_or32_op = 0x290, | ||
249 | mm_xor32_op = 0x310, | ||
250 | }; | ||
251 | |||
252 | /* | ||
253 | * (microMIPS) POOL32B functions. | ||
254 | */ | ||
255 | enum mm_32b_func { | ||
256 | mm_lwc2_func = 0x0, | ||
257 | mm_lwp_func = 0x1, | ||
258 | mm_ldc2_func = 0x2, | ||
259 | mm_ldp_func = 0x4, | ||
260 | mm_lwm32_func = 0x5, | ||
261 | mm_cache_func = 0x6, | ||
262 | mm_ldm_func = 0x7, | ||
263 | mm_swc2_func = 0x8, | ||
264 | mm_swp_func = 0x9, | ||
265 | mm_sdc2_func = 0xa, | ||
266 | mm_sdp_func = 0xc, | ||
267 | mm_swm32_func = 0xd, | ||
268 | mm_sdm_func = 0xf, | ||
269 | }; | ||
270 | |||
271 | /* | ||
272 | * (microMIPS) POOL32C functions. | ||
273 | */ | ||
274 | enum mm_32c_func { | ||
275 | mm_pref_func = 0x2, | ||
276 | mm_ll_func = 0x3, | ||
277 | mm_swr_func = 0x9, | ||
278 | mm_sc_func = 0xb, | ||
279 | mm_lwu_func = 0xe, | ||
280 | }; | ||
281 | |||
282 | /* | ||
283 | * (microMIPS) POOL32AXF minor opcodes. | ||
284 | */ | ||
285 | enum mm_32axf_minor_op { | ||
286 | mm_mfc0_op = 0x003, | ||
287 | mm_mtc0_op = 0x00b, | ||
288 | mm_tlbp_op = 0x00d, | ||
289 | mm_jalr_op = 0x03c, | ||
290 | mm_tlbr_op = 0x04d, | ||
291 | mm_jalrhb_op = 0x07c, | ||
292 | mm_tlbwi_op = 0x08d, | ||
293 | mm_tlbwr_op = 0x0cd, | ||
294 | mm_jalrs_op = 0x13c, | ||
295 | mm_jalrshb_op = 0x17c, | ||
296 | mm_syscall_op = 0x22d, | ||
297 | mm_eret_op = 0x3cd, | ||
298 | }; | ||
299 | |||
300 | /* | ||
301 | * (microMIPS) POOL32F minor opcodes. | ||
302 | */ | ||
303 | enum mm_32f_minor_op { | ||
304 | mm_32f_00_op = 0x00, | ||
305 | mm_32f_01_op = 0x01, | ||
306 | mm_32f_02_op = 0x02, | ||
307 | mm_32f_10_op = 0x08, | ||
308 | mm_32f_11_op = 0x09, | ||
309 | mm_32f_12_op = 0x0a, | ||
310 | mm_32f_20_op = 0x10, | ||
311 | mm_32f_30_op = 0x18, | ||
312 | mm_32f_40_op = 0x20, | ||
313 | mm_32f_41_op = 0x21, | ||
314 | mm_32f_42_op = 0x22, | ||
315 | mm_32f_50_op = 0x28, | ||
316 | mm_32f_51_op = 0x29, | ||
317 | mm_32f_52_op = 0x2a, | ||
318 | mm_32f_60_op = 0x30, | ||
319 | mm_32f_70_op = 0x38, | ||
320 | mm_32f_73_op = 0x3b, | ||
321 | mm_32f_74_op = 0x3c, | ||
322 | }; | ||
323 | |||
324 | /* | ||
325 | * (microMIPS) POOL32F secondary minor opcodes. | ||
326 | */ | ||
327 | enum mm_32f_10_minor_op { | ||
328 | mm_lwxc1_op = 0x1, | ||
329 | mm_swxc1_op, | ||
330 | mm_ldxc1_op, | ||
331 | mm_sdxc1_op, | ||
332 | mm_luxc1_op, | ||
333 | mm_suxc1_op, | ||
334 | }; | ||
335 | |||
336 | enum mm_32f_func { | ||
337 | mm_lwxc1_func = 0x048, | ||
338 | mm_swxc1_func = 0x088, | ||
339 | mm_ldxc1_func = 0x0c8, | ||
340 | mm_sdxc1_func = 0x108, | ||
341 | }; | ||
342 | |||
343 | /* | ||
344 | * (microMIPS) POOL32F secondary minor opcodes. | ||
345 | */ | ||
346 | enum mm_32f_40_minor_op { | ||
347 | mm_fmovf_op, | ||
348 | mm_fmovt_op, | ||
349 | }; | ||
350 | |||
351 | /* | ||
352 | * (microMIPS) POOL32F secondary minor opcodes. | ||
353 | */ | ||
354 | enum mm_32f_60_minor_op { | ||
355 | mm_fadd_op, | ||
356 | mm_fsub_op, | ||
357 | mm_fmul_op, | ||
358 | mm_fdiv_op, | ||
359 | }; | ||
360 | |||
361 | /* | ||
362 | * (microMIPS) POOL32F secondary minor opcodes. | ||
363 | */ | ||
364 | enum mm_32f_70_minor_op { | ||
365 | mm_fmovn_op, | ||
366 | mm_fmovz_op, | ||
367 | }; | ||
368 | |||
369 | /* | ||
370 | * (microMIPS) POOL32FXF secondary minor opcodes for POOL32F. | ||
371 | */ | ||
372 | enum mm_32f_73_minor_op { | ||
373 | mm_fmov0_op = 0x01, | ||
374 | mm_fcvtl_op = 0x04, | ||
375 | mm_movf0_op = 0x05, | ||
376 | mm_frsqrt_op = 0x08, | ||
377 | mm_ffloorl_op = 0x0c, | ||
378 | mm_fabs0_op = 0x0d, | ||
379 | mm_fcvtw_op = 0x24, | ||
380 | mm_movt0_op = 0x25, | ||
381 | mm_fsqrt_op = 0x28, | ||
382 | mm_ffloorw_op = 0x2c, | ||
383 | mm_fneg0_op = 0x2d, | ||
384 | mm_cfc1_op = 0x40, | ||
385 | mm_frecip_op = 0x48, | ||
386 | mm_fceill_op = 0x4c, | ||
387 | mm_fcvtd0_op = 0x4d, | ||
388 | mm_ctc1_op = 0x60, | ||
389 | mm_fceilw_op = 0x6c, | ||
390 | mm_fcvts0_op = 0x6d, | ||
391 | mm_mfc1_op = 0x80, | ||
392 | mm_fmov1_op = 0x81, | ||
393 | mm_movf1_op = 0x85, | ||
394 | mm_ftruncl_op = 0x8c, | ||
395 | mm_fabs1_op = 0x8d, | ||
396 | mm_mtc1_op = 0xa0, | ||
397 | mm_movt1_op = 0xa5, | ||
398 | mm_ftruncw_op = 0xac, | ||
399 | mm_fneg1_op = 0xad, | ||
400 | mm_froundl_op = 0xcc, | ||
401 | mm_fcvtd1_op = 0xcd, | ||
402 | mm_froundw_op = 0xec, | ||
403 | mm_fcvts1_op = 0xed, | ||
404 | }; | ||
405 | |||
406 | /* | ||
407 | * (microMIPS) POOL16C minor opcodes. | ||
408 | */ | ||
409 | enum mm_16c_minor_op { | ||
410 | mm_lwm16_op = 0x04, | ||
411 | mm_swm16_op = 0x05, | ||
412 | mm_jr16_op = 0x18, | ||
413 | mm_jrc_op = 0x1a, | ||
414 | mm_jalr16_op = 0x1c, | ||
415 | mm_jalrs16_op = 0x1e, | ||
416 | }; | ||
417 | |||
418 | /* | ||
419 | * (microMIPS) POOL16D minor opcodes. | ||
420 | */ | ||
421 | enum mm_16d_minor_op { | ||
422 | mm_addius5_func, | ||
423 | mm_addiusp_func, | ||
424 | }; | ||
425 | |||
426 | /* | ||
427 | * (MIPS16e) opcodes. | ||
428 | */ | ||
429 | enum MIPS16e_ops { | ||
430 | MIPS16e_jal_op = 003, | ||
431 | MIPS16e_ld_op = 007, | ||
432 | MIPS16e_i8_op = 014, | ||
433 | MIPS16e_sd_op = 017, | ||
434 | MIPS16e_lb_op = 020, | ||
435 | MIPS16e_lh_op = 021, | ||
436 | MIPS16e_lwsp_op = 022, | ||
437 | MIPS16e_lw_op = 023, | ||
438 | MIPS16e_lbu_op = 024, | ||
439 | MIPS16e_lhu_op = 025, | ||
440 | MIPS16e_lwpc_op = 026, | ||
441 | MIPS16e_lwu_op = 027, | ||
442 | MIPS16e_sb_op = 030, | ||
443 | MIPS16e_sh_op = 031, | ||
444 | MIPS16e_swsp_op = 032, | ||
445 | MIPS16e_sw_op = 033, | ||
446 | MIPS16e_rr_op = 035, | ||
447 | MIPS16e_extend_op = 036, | ||
448 | MIPS16e_i64_op = 037, | ||
449 | }; | ||
450 | |||
451 | enum MIPS16e_i64_func { | ||
452 | MIPS16e_ldsp_func, | ||
453 | MIPS16e_sdsp_func, | ||
454 | MIPS16e_sdrasp_func, | ||
455 | MIPS16e_dadjsp_func, | ||
456 | MIPS16e_ldpc_func, | ||
457 | }; | ||
458 | |||
459 | enum MIPS16e_rr_func { | ||
460 | MIPS16e_jr_func, | ||
461 | }; | ||
462 | |||
463 | enum MIPS6e_i8_func { | ||
464 | MIPS16e_swrasp_func = 02, | ||
465 | }; | ||
466 | |||
467 | /* | ||
468 | * (microMIPS & MIPS16e) NOP instruction. | ||
469 | */ | ||
470 | #define MM_NOP16 0x0c00 | ||
471 | |||
472 | /* | ||
196 | * Damn ... bitfields depend from byteorder :-( | 473 | * Damn ... bitfields depend from byteorder :-( |
197 | */ | 474 | */ |
198 | #ifdef __MIPSEB__ | 475 | #ifdef __MIPSEB__ |
@@ -311,6 +588,262 @@ struct v_format { /* MDMX vector format */ | |||
311 | ;))))))) | 588 | ;))))))) |
312 | }; | 589 | }; |
313 | 590 | ||
591 | /* | ||
592 | * microMIPS instruction formats (32-bit length) | ||
593 | * | ||
594 | * NOTE: | ||
595 | * Parenthesis denote whether the format is a microMIPS instruction or | ||
596 | * if it is MIPS32 instruction re-encoded for use in the microMIPS ASE. | ||
597 | */ | ||
598 | struct fb_format { /* FPU branch format (MIPS32) */ | ||
599 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
600 | BITFIELD_FIELD(unsigned int bc : 5, | ||
601 | BITFIELD_FIELD(unsigned int cc : 3, | ||
602 | BITFIELD_FIELD(unsigned int flag : 2, | ||
603 | BITFIELD_FIELD(signed int simmediate : 16, | ||
604 | ;))))) | ||
605 | }; | ||
606 | |||
607 | struct fp0_format { /* FPU multiply and add format (MIPS32) */ | ||
608 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
609 | BITFIELD_FIELD(unsigned int fmt : 5, | ||
610 | BITFIELD_FIELD(unsigned int ft : 5, | ||
611 | BITFIELD_FIELD(unsigned int fs : 5, | ||
612 | BITFIELD_FIELD(unsigned int fd : 5, | ||
613 | BITFIELD_FIELD(unsigned int func : 6, | ||
614 | ;)))))) | ||
615 | }; | ||
616 | |||
617 | struct mm_fp0_format { /* FPU multipy and add format (microMIPS) */ | ||
618 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
619 | BITFIELD_FIELD(unsigned int ft : 5, | ||
620 | BITFIELD_FIELD(unsigned int fs : 5, | ||
621 | BITFIELD_FIELD(unsigned int fd : 5, | ||
622 | BITFIELD_FIELD(unsigned int fmt : 3, | ||
623 | BITFIELD_FIELD(unsigned int op : 2, | ||
624 | BITFIELD_FIELD(unsigned int func : 6, | ||
625 | ;))))))) | ||
626 | }; | ||
627 | |||
628 | struct fp1_format { /* FPU mfc1 and cfc1 format (MIPS32) */ | ||
629 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
630 | BITFIELD_FIELD(unsigned int op : 5, | ||
631 | BITFIELD_FIELD(unsigned int rt : 5, | ||
632 | BITFIELD_FIELD(unsigned int fs : 5, | ||
633 | BITFIELD_FIELD(unsigned int fd : 5, | ||
634 | BITFIELD_FIELD(unsigned int func : 6, | ||
635 | ;)))))) | ||
636 | }; | ||
637 | |||
638 | struct mm_fp1_format { /* FPU mfc1 and cfc1 format (microMIPS) */ | ||
639 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
640 | BITFIELD_FIELD(unsigned int rt : 5, | ||
641 | BITFIELD_FIELD(unsigned int fs : 5, | ||
642 | BITFIELD_FIELD(unsigned int fmt : 2, | ||
643 | BITFIELD_FIELD(unsigned int op : 8, | ||
644 | BITFIELD_FIELD(unsigned int func : 6, | ||
645 | ;)))))) | ||
646 | }; | ||
647 | |||
648 | struct mm_fp2_format { /* FPU movt and movf format (microMIPS) */ | ||
649 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
650 | BITFIELD_FIELD(unsigned int fd : 5, | ||
651 | BITFIELD_FIELD(unsigned int fs : 5, | ||
652 | BITFIELD_FIELD(unsigned int cc : 3, | ||
653 | BITFIELD_FIELD(unsigned int zero : 2, | ||
654 | BITFIELD_FIELD(unsigned int fmt : 2, | ||
655 | BITFIELD_FIELD(unsigned int op : 3, | ||
656 | BITFIELD_FIELD(unsigned int func : 6, | ||
657 | ;)))))))) | ||
658 | }; | ||
659 | |||
660 | struct mm_fp3_format { /* FPU abs and neg format (microMIPS) */ | ||
661 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
662 | BITFIELD_FIELD(unsigned int rt : 5, | ||
663 | BITFIELD_FIELD(unsigned int fs : 5, | ||
664 | BITFIELD_FIELD(unsigned int fmt : 3, | ||
665 | BITFIELD_FIELD(unsigned int op : 7, | ||
666 | BITFIELD_FIELD(unsigned int func : 6, | ||
667 | ;)))))) | ||
668 | }; | ||
669 | |||
670 | struct mm_fp4_format { /* FPU c.cond format (microMIPS) */ | ||
671 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
672 | BITFIELD_FIELD(unsigned int rt : 5, | ||
673 | BITFIELD_FIELD(unsigned int fs : 5, | ||
674 | BITFIELD_FIELD(unsigned int cc : 3, | ||
675 | BITFIELD_FIELD(unsigned int fmt : 3, | ||
676 | BITFIELD_FIELD(unsigned int cond : 4, | ||
677 | BITFIELD_FIELD(unsigned int func : 6, | ||
678 | ;))))))) | ||
679 | }; | ||
680 | |||
681 | struct mm_fp5_format { /* FPU lwxc1 and swxc1 format (microMIPS) */ | ||
682 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
683 | BITFIELD_FIELD(unsigned int index : 5, | ||
684 | BITFIELD_FIELD(unsigned int base : 5, | ||
685 | BITFIELD_FIELD(unsigned int fd : 5, | ||
686 | BITFIELD_FIELD(unsigned int op : 5, | ||
687 | BITFIELD_FIELD(unsigned int func : 6, | ||
688 | ;)))))) | ||
689 | }; | ||
690 | |||
691 | struct fp6_format { /* FPU madd and msub format (MIPS IV) */ | ||
692 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
693 | BITFIELD_FIELD(unsigned int fr : 5, | ||
694 | BITFIELD_FIELD(unsigned int ft : 5, | ||
695 | BITFIELD_FIELD(unsigned int fs : 5, | ||
696 | BITFIELD_FIELD(unsigned int fd : 5, | ||
697 | BITFIELD_FIELD(unsigned int func : 6, | ||
698 | ;)))))) | ||
699 | }; | ||
700 | |||
701 | struct mm_fp6_format { /* FPU madd and msub format (microMIPS) */ | ||
702 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
703 | BITFIELD_FIELD(unsigned int ft : 5, | ||
704 | BITFIELD_FIELD(unsigned int fs : 5, | ||
705 | BITFIELD_FIELD(unsigned int fd : 5, | ||
706 | BITFIELD_FIELD(unsigned int fr : 5, | ||
707 | BITFIELD_FIELD(unsigned int func : 6, | ||
708 | ;)))))) | ||
709 | }; | ||
710 | |||
711 | struct mm_i_format { /* Immediate format (microMIPS) */ | ||
712 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
713 | BITFIELD_FIELD(unsigned int rt : 5, | ||
714 | BITFIELD_FIELD(unsigned int rs : 5, | ||
715 | BITFIELD_FIELD(signed int simmediate : 16, | ||
716 | ;)))) | ||
717 | }; | ||
718 | |||
719 | struct mm_m_format { /* Multi-word load/store format (microMIPS) */ | ||
720 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
721 | BITFIELD_FIELD(unsigned int rd : 5, | ||
722 | BITFIELD_FIELD(unsigned int base : 5, | ||
723 | BITFIELD_FIELD(unsigned int func : 4, | ||
724 | BITFIELD_FIELD(signed int simmediate : 12, | ||
725 | ;))))) | ||
726 | }; | ||
727 | |||
728 | struct mm_x_format { /* Scaled indexed load format (microMIPS) */ | ||
729 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
730 | BITFIELD_FIELD(unsigned int index : 5, | ||
731 | BITFIELD_FIELD(unsigned int base : 5, | ||
732 | BITFIELD_FIELD(unsigned int rd : 5, | ||
733 | BITFIELD_FIELD(unsigned int func : 11, | ||
734 | ;))))) | ||
735 | }; | ||
736 | |||
737 | /* | ||
738 | * microMIPS instruction formats (16-bit length) | ||
739 | */ | ||
740 | struct mm_b0_format { /* Unconditional branch format (microMIPS) */ | ||
741 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
742 | BITFIELD_FIELD(signed int simmediate : 10, | ||
743 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | ||
744 | ;))) | ||
745 | }; | ||
746 | |||
747 | struct mm_b1_format { /* Conditional branch format (microMIPS) */ | ||
748 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
749 | BITFIELD_FIELD(unsigned int rs : 3, | ||
750 | BITFIELD_FIELD(signed int simmediate : 7, | ||
751 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | ||
752 | ;)))) | ||
753 | }; | ||
754 | |||
755 | struct mm16_m_format { /* Multi-word load/store format */ | ||
756 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
757 | BITFIELD_FIELD(unsigned int func : 4, | ||
758 | BITFIELD_FIELD(unsigned int rlist : 2, | ||
759 | BITFIELD_FIELD(unsigned int imm : 4, | ||
760 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | ||
761 | ;))))) | ||
762 | }; | ||
763 | |||
764 | struct mm16_rb_format { /* Signed immediate format */ | ||
765 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
766 | BITFIELD_FIELD(unsigned int rt : 3, | ||
767 | BITFIELD_FIELD(unsigned int base : 3, | ||
768 | BITFIELD_FIELD(signed int simmediate : 4, | ||
769 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | ||
770 | ;))))) | ||
771 | }; | ||
772 | |||
773 | struct mm16_r3_format { /* Load from global pointer format */ | ||
774 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
775 | BITFIELD_FIELD(unsigned int rt : 3, | ||
776 | BITFIELD_FIELD(signed int simmediate : 7, | ||
777 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | ||
778 | ;)))) | ||
779 | }; | ||
780 | |||
781 | struct mm16_r5_format { /* Load/store from stack pointer format */ | ||
782 | BITFIELD_FIELD(unsigned int opcode : 6, | ||
783 | BITFIELD_FIELD(unsigned int rt : 5, | ||
784 | BITFIELD_FIELD(signed int simmediate : 5, | ||
785 | BITFIELD_FIELD(unsigned int : 16, /* Ignored */ | ||
786 | ;)))) | ||
787 | }; | ||
788 | |||
789 | /* | ||
790 | * MIPS16e instruction formats (16-bit length) | ||
791 | */ | ||
792 | struct m16e_rr { | ||
793 | BITFIELD_FIELD(unsigned int opcode : 5, | ||
794 | BITFIELD_FIELD(unsigned int rx : 3, | ||
795 | BITFIELD_FIELD(unsigned int nd : 1, | ||
796 | BITFIELD_FIELD(unsigned int l : 1, | ||
797 | BITFIELD_FIELD(unsigned int ra : 1, | ||
798 | BITFIELD_FIELD(unsigned int func : 5, | ||
799 | ;)))))) | ||
800 | }; | ||
801 | |||
802 | struct m16e_jal { | ||
803 | BITFIELD_FIELD(unsigned int opcode : 5, | ||
804 | BITFIELD_FIELD(unsigned int x : 1, | ||
805 | BITFIELD_FIELD(unsigned int imm20_16 : 5, | ||
806 | BITFIELD_FIELD(signed int imm25_21 : 5, | ||
807 | ;)))) | ||
808 | }; | ||
809 | |||
810 | struct m16e_i64 { | ||
811 | BITFIELD_FIELD(unsigned int opcode : 5, | ||
812 | BITFIELD_FIELD(unsigned int func : 3, | ||
813 | BITFIELD_FIELD(unsigned int imm : 8, | ||
814 | ;))) | ||
815 | }; | ||
816 | |||
817 | struct m16e_ri64 { | ||
818 | BITFIELD_FIELD(unsigned int opcode : 5, | ||
819 | BITFIELD_FIELD(unsigned int func : 3, | ||
820 | BITFIELD_FIELD(unsigned int ry : 3, | ||
821 | BITFIELD_FIELD(unsigned int imm : 5, | ||
822 | ;)))) | ||
823 | }; | ||
824 | |||
825 | struct m16e_ri { | ||
826 | BITFIELD_FIELD(unsigned int opcode : 5, | ||
827 | BITFIELD_FIELD(unsigned int rx : 3, | ||
828 | BITFIELD_FIELD(unsigned int imm : 8, | ||
829 | ;))) | ||
830 | }; | ||
831 | |||
832 | struct m16e_rri { | ||
833 | BITFIELD_FIELD(unsigned int opcode : 5, | ||
834 | BITFIELD_FIELD(unsigned int rx : 3, | ||
835 | BITFIELD_FIELD(unsigned int ry : 3, | ||
836 | BITFIELD_FIELD(unsigned int imm : 5, | ||
837 | ;)))) | ||
838 | }; | ||
839 | |||
840 | struct m16e_i8 { | ||
841 | BITFIELD_FIELD(unsigned int opcode : 5, | ||
842 | BITFIELD_FIELD(unsigned int func : 3, | ||
843 | BITFIELD_FIELD(unsigned int imm : 8, | ||
844 | ;))) | ||
845 | }; | ||
846 | |||
314 | union mips_instruction { | 847 | union mips_instruction { |
315 | unsigned int word; | 848 | unsigned int word; |
316 | unsigned short halfword[2]; | 849 | unsigned short halfword[2]; |
@@ -326,6 +859,37 @@ union mips_instruction { | |||
326 | struct b_format b_format; | 859 | struct b_format b_format; |
327 | struct ps_format ps_format; | 860 | struct ps_format ps_format; |
328 | struct v_format v_format; | 861 | struct v_format v_format; |
862 | struct fb_format fb_format; | ||
863 | struct fp0_format fp0_format; | ||
864 | struct mm_fp0_format mm_fp0_format; | ||
865 | struct fp1_format fp1_format; | ||
866 | struct mm_fp1_format mm_fp1_format; | ||
867 | struct mm_fp2_format mm_fp2_format; | ||
868 | struct mm_fp3_format mm_fp3_format; | ||
869 | struct mm_fp4_format mm_fp4_format; | ||
870 | struct mm_fp5_format mm_fp5_format; | ||
871 | struct fp6_format fp6_format; | ||
872 | struct mm_fp6_format mm_fp6_format; | ||
873 | struct mm_i_format mm_i_format; | ||
874 | struct mm_m_format mm_m_format; | ||
875 | struct mm_x_format mm_x_format; | ||
876 | struct mm_b0_format mm_b0_format; | ||
877 | struct mm_b1_format mm_b1_format; | ||
878 | struct mm16_m_format mm16_m_format ; | ||
879 | struct mm16_rb_format mm16_rb_format; | ||
880 | struct mm16_r3_format mm16_r3_format; | ||
881 | struct mm16_r5_format mm16_r5_format; | ||
882 | }; | ||
883 | |||
884 | union mips16e_instruction { | ||
885 | unsigned int full : 16; | ||
886 | struct m16e_rr rr; | ||
887 | struct m16e_jal jal; | ||
888 | struct m16e_i64 i64; | ||
889 | struct m16e_ri64 ri64; | ||
890 | struct m16e_ri ri; | ||
891 | struct m16e_rri rri; | ||
892 | struct m16e_i8 i8; | ||
329 | }; | 893 | }; |
330 | 894 | ||
331 | #endif /* _UAPI_ASM_INST_H */ | 895 | #endif /* _UAPI_ASM_INST_H */ |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index cdb87b2a423d..cb96ace5c8c5 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -19,15 +19,16 @@ obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o | |||
19 | obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o | 19 | obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o |
20 | obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o | 20 | obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o |
21 | obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o | 21 | obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o |
22 | obj-$(CONFIG_CEVT_GIC) += cevt-gic.o | ||
22 | obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o | 23 | obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o |
23 | obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o | 24 | obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o |
24 | obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o | 25 | obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o |
25 | obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o | 26 | obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o |
27 | obj-$(CONFIG_CSRC_GIC) += csrc-gic.o | ||
26 | obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o | 28 | obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o |
27 | obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o | 29 | obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o |
28 | obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o | 30 | obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o |
29 | obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o | 31 | obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o |
30 | obj-$(CONFIG_CSRC_GIC) += csrc-gic.o | ||
31 | obj-$(CONFIG_SYNC_R4K) += sync-r4k.o | 32 | obj-$(CONFIG_SYNC_R4K) += sync-r4k.o |
32 | 33 | ||
33 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 34 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 83ffe950f710..46c2ad0703a0 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c | |||
@@ -14,10 +14,186 @@ | |||
14 | #include <asm/cpu.h> | 14 | #include <asm/cpu.h> |
15 | #include <asm/cpu-features.h> | 15 | #include <asm/cpu-features.h> |
16 | #include <asm/fpu.h> | 16 | #include <asm/fpu.h> |
17 | #include <asm/fpu_emulator.h> | ||
17 | #include <asm/inst.h> | 18 | #include <asm/inst.h> |
18 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
19 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
20 | 21 | ||
22 | /* | ||
23 | * Calculate and return exception PC in case of branch delay slot | ||
24 | * for microMIPS and MIPS16e. It does not clear the ISA mode bit. | ||
25 | */ | ||
26 | int __isa_exception_epc(struct pt_regs *regs) | ||
27 | { | ||
28 | unsigned short inst; | ||
29 | long epc = regs->cp0_epc; | ||
30 | |||
31 | /* Calculate exception PC in branch delay slot. */ | ||
32 | if (__get_user(inst, (u16 __user *) msk_isa16_mode(epc))) { | ||
33 | /* This should never happen because delay slot was checked. */ | ||
34 | force_sig(SIGSEGV, current); | ||
35 | return epc; | ||
36 | } | ||
37 | if (cpu_has_mips16) { | ||
38 | if (((union mips16e_instruction)inst).ri.opcode | ||
39 | == MIPS16e_jal_op) | ||
40 | epc += 4; | ||
41 | else | ||
42 | epc += 2; | ||
43 | } else if (mm_insn_16bit(inst)) | ||
44 | epc += 2; | ||
45 | else | ||
46 | epc += 4; | ||
47 | |||
48 | return epc; | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Compute return address and emulate branch in microMIPS mode after an | ||
53 | * exception only. It does not handle compact branches/jumps and cannot | ||
54 | * be used in interrupt context. (Compact branches/jumps do not cause | ||
55 | * exceptions.) | ||
56 | */ | ||
57 | int __microMIPS_compute_return_epc(struct pt_regs *regs) | ||
58 | { | ||
59 | u16 __user *pc16; | ||
60 | u16 halfword; | ||
61 | unsigned int word; | ||
62 | unsigned long contpc; | ||
63 | struct mm_decoded_insn mminsn = { 0 }; | ||
64 | |||
65 | mminsn.micro_mips_mode = 1; | ||
66 | |||
67 | /* This load never faults. */ | ||
68 | pc16 = (unsigned short __user *)msk_isa16_mode(regs->cp0_epc); | ||
69 | __get_user(halfword, pc16); | ||
70 | pc16++; | ||
71 | contpc = regs->cp0_epc + 2; | ||
72 | word = ((unsigned int)halfword << 16); | ||
73 | mminsn.pc_inc = 2; | ||
74 | |||
75 | if (!mm_insn_16bit(halfword)) { | ||
76 | __get_user(halfword, pc16); | ||
77 | pc16++; | ||
78 | contpc = regs->cp0_epc + 4; | ||
79 | mminsn.pc_inc = 4; | ||
80 | word |= halfword; | ||
81 | } | ||
82 | mminsn.insn = word; | ||
83 | |||
84 | if (get_user(halfword, pc16)) | ||
85 | goto sigsegv; | ||
86 | mminsn.next_pc_inc = 2; | ||
87 | word = ((unsigned int)halfword << 16); | ||
88 | |||
89 | if (!mm_insn_16bit(halfword)) { | ||
90 | pc16++; | ||
91 | if (get_user(halfword, pc16)) | ||
92 | goto sigsegv; | ||
93 | mminsn.next_pc_inc = 4; | ||
94 | word |= halfword; | ||
95 | } | ||
96 | mminsn.next_insn = word; | ||
97 | |||
98 | mm_isBranchInstr(regs, mminsn, &contpc); | ||
99 | |||
100 | regs->cp0_epc = contpc; | ||
101 | |||
102 | return 0; | ||
103 | |||
104 | sigsegv: | ||
105 | force_sig(SIGSEGV, current); | ||
106 | return -EFAULT; | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * Compute return address and emulate branch in MIPS16e mode after an | ||
111 | * exception only. It does not handle compact branches/jumps and cannot | ||
112 | * be used in interrupt context. (Compact branches/jumps do not cause | ||
113 | * exceptions.) | ||
114 | */ | ||
115 | int __MIPS16e_compute_return_epc(struct pt_regs *regs) | ||
116 | { | ||
117 | u16 __user *addr; | ||
118 | union mips16e_instruction inst; | ||
119 | u16 inst2; | ||
120 | u32 fullinst; | ||
121 | long epc; | ||
122 | |||
123 | epc = regs->cp0_epc; | ||
124 | |||
125 | /* Read the instruction. */ | ||
126 | addr = (u16 __user *)msk_isa16_mode(epc); | ||
127 | if (__get_user(inst.full, addr)) { | ||
128 | force_sig(SIGSEGV, current); | ||
129 | return -EFAULT; | ||
130 | } | ||
131 | |||
132 | switch (inst.ri.opcode) { | ||
133 | case MIPS16e_extend_op: | ||
134 | regs->cp0_epc += 4; | ||
135 | return 0; | ||
136 | |||
137 | /* | ||
138 | * JAL and JALX in MIPS16e mode | ||
139 | */ | ||
140 | case MIPS16e_jal_op: | ||
141 | addr += 1; | ||
142 | if (__get_user(inst2, addr)) { | ||
143 | force_sig(SIGSEGV, current); | ||
144 | return -EFAULT; | ||
145 | } | ||
146 | fullinst = ((unsigned)inst.full << 16) | inst2; | ||
147 | regs->regs[31] = epc + 6; | ||
148 | epc += 4; | ||
149 | epc >>= 28; | ||
150 | epc <<= 28; | ||
151 | /* | ||
152 | * JAL:5 X:1 TARGET[20-16]:5 TARGET[25:21]:5 TARGET[15:0]:16 | ||
153 | * | ||
154 | * ......TARGET[15:0].................TARGET[20:16]........... | ||
155 | * ......TARGET[25:21] | ||
156 | */ | ||
157 | epc |= | ||
158 | ((fullinst & 0xffff) << 2) | ((fullinst & 0x3e00000) >> 3) | | ||
159 | ((fullinst & 0x1f0000) << 7); | ||
160 | if (!inst.jal.x) | ||
161 | set_isa16_mode(epc); /* Set ISA mode bit. */ | ||
162 | regs->cp0_epc = epc; | ||
163 | return 0; | ||
164 | |||
165 | /* | ||
166 | * J(AL)R(C) | ||
167 | */ | ||
168 | case MIPS16e_rr_op: | ||
169 | if (inst.rr.func == MIPS16e_jr_func) { | ||
170 | |||
171 | if (inst.rr.ra) | ||
172 | regs->cp0_epc = regs->regs[31]; | ||
173 | else | ||
174 | regs->cp0_epc = | ||
175 | regs->regs[reg16to32[inst.rr.rx]]; | ||
176 | |||
177 | if (inst.rr.l) { | ||
178 | if (inst.rr.nd) | ||
179 | regs->regs[31] = epc + 2; | ||
180 | else | ||
181 | regs->regs[31] = epc + 4; | ||
182 | } | ||
183 | return 0; | ||
184 | } | ||
185 | break; | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * All other cases have no branch delay slot and are 16-bits. | ||
190 | * Branches do not cause an exception. | ||
191 | */ | ||
192 | regs->cp0_epc += 2; | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
21 | /** | 197 | /** |
22 | * __compute_return_epc_for_insn - Computes the return address and do emulate | 198 | * __compute_return_epc_for_insn - Computes the return address and do emulate |
23 | * branch simulation, if required. | 199 | * branch simulation, if required. |
@@ -129,6 +305,8 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, | |||
129 | epc <<= 28; | 305 | epc <<= 28; |
130 | epc |= (insn.j_format.target << 2); | 306 | epc |= (insn.j_format.target << 2); |
131 | regs->cp0_epc = epc; | 307 | regs->cp0_epc = epc; |
308 | if (insn.i_format.opcode == jalx_op) | ||
309 | set_isa16_mode(regs->cp0_epc); | ||
132 | break; | 310 | break; |
133 | 311 | ||
134 | /* | 312 | /* |
diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c new file mode 100644 index 000000000000..730eaf92c018 --- /dev/null +++ b/arch/mips/kernel/cevt-gic.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2013 Imagination Technologies Ltd. | ||
7 | */ | ||
8 | #include <linux/clockchips.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/percpu.h> | ||
11 | #include <linux/smp.h> | ||
12 | #include <linux/irq.h> | ||
13 | |||
14 | #include <asm/time.h> | ||
15 | #include <asm/gic.h> | ||
16 | #include <asm/mips-boards/maltaint.h> | ||
17 | |||
18 | DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); | ||
19 | int gic_timer_irq_installed; | ||
20 | |||
21 | |||
22 | static int gic_next_event(unsigned long delta, struct clock_event_device *evt) | ||
23 | { | ||
24 | u64 cnt; | ||
25 | int res; | ||
26 | |||
27 | cnt = gic_read_count(); | ||
28 | cnt += (u64)delta; | ||
29 | gic_write_compare(cnt); | ||
30 | res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; | ||
31 | return res; | ||
32 | } | ||
33 | |||
34 | void gic_set_clock_mode(enum clock_event_mode mode, | ||
35 | struct clock_event_device *evt) | ||
36 | { | ||
37 | /* Nothing to do ... */ | ||
38 | } | ||
39 | |||
40 | irqreturn_t gic_compare_interrupt(int irq, void *dev_id) | ||
41 | { | ||
42 | struct clock_event_device *cd; | ||
43 | int cpu = smp_processor_id(); | ||
44 | |||
45 | gic_write_compare(gic_read_compare()); | ||
46 | cd = &per_cpu(gic_clockevent_device, cpu); | ||
47 | cd->event_handler(cd); | ||
48 | return IRQ_HANDLED; | ||
49 | } | ||
50 | |||
51 | struct irqaction gic_compare_irqaction = { | ||
52 | .handler = gic_compare_interrupt, | ||
53 | .flags = IRQF_PERCPU | IRQF_TIMER, | ||
54 | .name = "timer", | ||
55 | }; | ||
56 | |||
57 | |||
58 | void gic_event_handler(struct clock_event_device *dev) | ||
59 | { | ||
60 | } | ||
61 | |||
62 | int __cpuinit gic_clockevent_init(void) | ||
63 | { | ||
64 | unsigned int cpu = smp_processor_id(); | ||
65 | struct clock_event_device *cd; | ||
66 | unsigned int irq; | ||
67 | |||
68 | if (!cpu_has_counter || !gic_frequency) | ||
69 | return -ENXIO; | ||
70 | |||
71 | irq = MIPS_GIC_IRQ_BASE; | ||
72 | |||
73 | cd = &per_cpu(gic_clockevent_device, cpu); | ||
74 | |||
75 | cd->name = "MIPS GIC"; | ||
76 | cd->features = CLOCK_EVT_FEAT_ONESHOT; | ||
77 | |||
78 | clockevent_set_clock(cd, gic_frequency); | ||
79 | |||
80 | /* Calculate the min / max delta */ | ||
81 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | ||
82 | cd->min_delta_ns = clockevent_delta2ns(0x300, cd); | ||
83 | |||
84 | cd->rating = 300; | ||
85 | cd->irq = irq; | ||
86 | cd->cpumask = cpumask_of(cpu); | ||
87 | cd->set_next_event = gic_next_event; | ||
88 | cd->set_mode = gic_set_clock_mode; | ||
89 | cd->event_handler = gic_event_handler; | ||
90 | |||
91 | clockevents_register_device(cd); | ||
92 | |||
93 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), 0x80000002); | ||
94 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK); | ||
95 | |||
96 | if (gic_timer_irq_installed) | ||
97 | return 0; | ||
98 | |||
99 | gic_timer_irq_installed = 1; | ||
100 | |||
101 | setup_irq(irq, &gic_compare_irqaction); | ||
102 | irq_set_handler(irq, handle_percpu_irq); | ||
103 | return 0; | ||
104 | } | ||
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index fd75d7144524..02033eaf8825 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
@@ -23,7 +23,6 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #ifndef CONFIG_MIPS_MT_SMTC | 25 | #ifndef CONFIG_MIPS_MT_SMTC |
26 | |||
27 | static int mips_next_event(unsigned long delta, | 26 | static int mips_next_event(unsigned long delta, |
28 | struct clock_event_device *evt) | 27 | struct clock_event_device *evt) |
29 | { | 28 | { |
@@ -49,7 +48,6 @@ DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); | |||
49 | int cp0_timer_irq_installed; | 48 | int cp0_timer_irq_installed; |
50 | 49 | ||
51 | #ifndef CONFIG_MIPS_MT_SMTC | 50 | #ifndef CONFIG_MIPS_MT_SMTC |
52 | |||
53 | irqreturn_t c0_compare_interrupt(int irq, void *dev_id) | 51 | irqreturn_t c0_compare_interrupt(int irq, void *dev_id) |
54 | { | 52 | { |
55 | const int r2 = cpu_has_mips_r2; | 53 | const int r2 = cpu_has_mips_r2; |
@@ -74,6 +72,9 @@ irqreturn_t c0_compare_interrupt(int irq, void *dev_id) | |||
74 | /* Clear Count/Compare Interrupt */ | 72 | /* Clear Count/Compare Interrupt */ |
75 | write_c0_compare(read_c0_compare()); | 73 | write_c0_compare(read_c0_compare()); |
76 | cd = &per_cpu(mips_clockevent_device, cpu); | 74 | cd = &per_cpu(mips_clockevent_device, cpu); |
75 | #ifdef CONFIG_CEVT_GIC | ||
76 | if (!gic_present) | ||
77 | #endif | ||
77 | cd->event_handler(cd); | 78 | cd->event_handler(cd); |
78 | } | 79 | } |
79 | 80 | ||
@@ -170,7 +171,6 @@ int c0_compare_int_usable(void) | |||
170 | } | 171 | } |
171 | 172 | ||
172 | #ifndef CONFIG_MIPS_MT_SMTC | 173 | #ifndef CONFIG_MIPS_MT_SMTC |
173 | |||
174 | int __cpuinit r4k_clockevent_init(void) | 174 | int __cpuinit r4k_clockevent_init(void) |
175 | { | 175 | { |
176 | unsigned int cpu = smp_processor_id(); | 176 | unsigned int cpu = smp_processor_id(); |
@@ -210,6 +210,9 @@ int __cpuinit r4k_clockevent_init(void) | |||
210 | cd->set_mode = mips_set_clock_mode; | 210 | cd->set_mode = mips_set_clock_mode; |
211 | cd->event_handler = mips_event_handler; | 211 | cd->event_handler = mips_event_handler; |
212 | 212 | ||
213 | #ifdef CONFIG_CEVT_GIC | ||
214 | if (!gic_present) | ||
215 | #endif | ||
213 | clockevents_register_device(cd); | 216 | clockevents_register_device(cd); |
214 | 217 | ||
215 | if (cp0_timer_irq_installed) | 218 | if (cp0_timer_irq_installed) |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 5fe66a0c3224..4bbffdb9024f 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -470,6 +470,9 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) | |||
470 | c->options |= MIPS_CPU_ULRI; | 470 | c->options |= MIPS_CPU_ULRI; |
471 | if (config3 & MIPS_CONF3_ISA) | 471 | if (config3 & MIPS_CONF3_ISA) |
472 | c->options |= MIPS_CPU_MICROMIPS; | 472 | c->options |= MIPS_CPU_MICROMIPS; |
473 | #ifdef CONFIG_CPU_MICROMIPS | ||
474 | write_c0_config3(read_c0_config3() | MIPS_CONF3_ISA_OE); | ||
475 | #endif | ||
473 | if (config3 & MIPS_CONF3_VZ) | 476 | if (config3 & MIPS_CONF3_VZ) |
474 | c->ases |= MIPS_ASE_VZ; | 477 | c->ases |= MIPS_ASE_VZ; |
475 | 478 | ||
diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c index 5dca24bce51b..e02620901117 100644 --- a/arch/mips/kernel/csrc-gic.c +++ b/arch/mips/kernel/csrc-gic.c | |||
@@ -5,23 +5,14 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | 6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. |
7 | */ | 7 | */ |
8 | #include <linux/clocksource.h> | ||
9 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/time.h> | ||
10 | 10 | ||
11 | #include <asm/time.h> | ||
12 | #include <asm/gic.h> | 11 | #include <asm/gic.h> |
13 | 12 | ||
14 | static cycle_t gic_hpt_read(struct clocksource *cs) | 13 | static cycle_t gic_hpt_read(struct clocksource *cs) |
15 | { | 14 | { |
16 | unsigned int hi, hi2, lo; | 15 | return gic_read_count(); |
17 | |||
18 | do { | ||
19 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi); | ||
20 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo); | ||
21 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2); | ||
22 | } while (hi2 != hi); | ||
23 | |||
24 | return (((cycle_t) hi) << 32) + lo; | ||
25 | } | 16 | } |
26 | 17 | ||
27 | static struct clocksource gic_clocksource = { | 18 | static struct clocksource gic_clocksource = { |
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index ecb347ce1b3d..5c2ba9f08a80 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -5,8 +5,8 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle | 6 | * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle |
7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
8 | * Copyright (C) 2001 MIPS Technologies, Inc. | ||
9 | * Copyright (C) 2002, 2007 Maciej W. Rozycki | 8 | * Copyright (C) 2002, 2007 Maciej W. Rozycki |
9 | * Copyright (C) 2001, 2012 MIPS Technologies, Inc. All rights reserved. | ||
10 | */ | 10 | */ |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | 12 | ||
@@ -21,8 +21,10 @@ | |||
21 | #include <asm/war.h> | 21 | #include <asm/war.h> |
22 | #include <asm/thread_info.h> | 22 | #include <asm/thread_info.h> |
23 | 23 | ||
24 | #ifdef CONFIG_MIPS_MT_SMTC | ||
24 | #define PANIC_PIC(msg) \ | 25 | #define PANIC_PIC(msg) \ |
25 | .set push; \ | 26 | .set push; \ |
27 | .set nomicromips; \ | ||
26 | .set reorder; \ | 28 | .set reorder; \ |
27 | PTR_LA a0,8f; \ | 29 | PTR_LA a0,8f; \ |
28 | .set noat; \ | 30 | .set noat; \ |
@@ -31,17 +33,10 @@ | |||
31 | 9: b 9b; \ | 33 | 9: b 9b; \ |
32 | .set pop; \ | 34 | .set pop; \ |
33 | TEXT(msg) | 35 | TEXT(msg) |
36 | #endif | ||
34 | 37 | ||
35 | __INIT | 38 | __INIT |
36 | 39 | ||
37 | NESTED(except_vec0_generic, 0, sp) | ||
38 | PANIC_PIC("Exception vector 0 called") | ||
39 | END(except_vec0_generic) | ||
40 | |||
41 | NESTED(except_vec1_generic, 0, sp) | ||
42 | PANIC_PIC("Exception vector 1 called") | ||
43 | END(except_vec1_generic) | ||
44 | |||
45 | /* | 40 | /* |
46 | * General exception vector for all other CPUs. | 41 | * General exception vector for all other CPUs. |
47 | * | 42 | * |
@@ -138,12 +133,19 @@ LEAF(r4k_wait) | |||
138 | nop | 133 | nop |
139 | nop | 134 | nop |
140 | nop | 135 | nop |
136 | #ifdef CONFIG_CPU_MICROMIPS | ||
137 | nop | ||
138 | nop | ||
139 | nop | ||
140 | nop | ||
141 | #endif | ||
141 | .set mips3 | 142 | .set mips3 |
142 | wait | 143 | wait |
143 | /* end of rollback region (the region size must be power of two) */ | 144 | /* end of rollback region (the region size must be power of two) */ |
144 | .set pop | ||
145 | 1: | 145 | 1: |
146 | jr ra | 146 | jr ra |
147 | nop | ||
148 | .set pop | ||
147 | END(r4k_wait) | 149 | END(r4k_wait) |
148 | 150 | ||
149 | .macro BUILD_ROLLBACK_PROLOGUE handler | 151 | .macro BUILD_ROLLBACK_PROLOGUE handler |
@@ -201,7 +203,11 @@ NESTED(handle_int, PT_SIZE, sp) | |||
201 | LONG_L s0, TI_REGS($28) | 203 | LONG_L s0, TI_REGS($28) |
202 | LONG_S sp, TI_REGS($28) | 204 | LONG_S sp, TI_REGS($28) |
203 | PTR_LA ra, ret_from_irq | 205 | PTR_LA ra, ret_from_irq |
204 | j plat_irq_dispatch | 206 | PTR_LA v0, plat_irq_dispatch |
207 | jr v0 | ||
208 | #ifdef CONFIG_CPU_MICROMIPS | ||
209 | nop | ||
210 | #endif | ||
205 | END(handle_int) | 211 | END(handle_int) |
206 | 212 | ||
207 | __INIT | 213 | __INIT |
@@ -222,11 +228,14 @@ NESTED(except_vec4, 0, sp) | |||
222 | /* | 228 | /* |
223 | * EJTAG debug exception handler. | 229 | * EJTAG debug exception handler. |
224 | * The EJTAG debug exception entry point is 0xbfc00480, which | 230 | * The EJTAG debug exception entry point is 0xbfc00480, which |
225 | * normally is in the boot PROM, so the boot PROM must do a | 231 | * normally is in the boot PROM, so the boot PROM must do an |
226 | * unconditional jump to this vector. | 232 | * unconditional jump to this vector. |
227 | */ | 233 | */ |
228 | NESTED(except_vec_ejtag_debug, 0, sp) | 234 | NESTED(except_vec_ejtag_debug, 0, sp) |
229 | j ejtag_debug_handler | 235 | j ejtag_debug_handler |
236 | #ifdef CONFIG_CPU_MICROMIPS | ||
237 | nop | ||
238 | #endif | ||
230 | END(except_vec_ejtag_debug) | 239 | END(except_vec_ejtag_debug) |
231 | 240 | ||
232 | __FINIT | 241 | __FINIT |
@@ -251,9 +260,10 @@ NESTED(except_vec_vi, 0, sp) | |||
251 | FEXPORT(except_vec_vi_mori) | 260 | FEXPORT(except_vec_vi_mori) |
252 | ori a0, $0, 0 | 261 | ori a0, $0, 0 |
253 | #endif /* CONFIG_MIPS_MT_SMTC */ | 262 | #endif /* CONFIG_MIPS_MT_SMTC */ |
263 | PTR_LA v1, except_vec_vi_handler | ||
254 | FEXPORT(except_vec_vi_lui) | 264 | FEXPORT(except_vec_vi_lui) |
255 | lui v0, 0 /* Patched */ | 265 | lui v0, 0 /* Patched */ |
256 | j except_vec_vi_handler | 266 | jr v1 |
257 | FEXPORT(except_vec_vi_ori) | 267 | FEXPORT(except_vec_vi_ori) |
258 | ori v0, 0 /* Patched */ | 268 | ori v0, 0 /* Patched */ |
259 | .set pop | 269 | .set pop |
@@ -354,6 +364,9 @@ EXPORT(ejtag_debug_buffer) | |||
354 | */ | 364 | */ |
355 | NESTED(except_vec_nmi, 0, sp) | 365 | NESTED(except_vec_nmi, 0, sp) |
356 | j nmi_handler | 366 | j nmi_handler |
367 | #ifdef CONFIG_CPU_MICROMIPS | ||
368 | nop | ||
369 | #endif | ||
357 | END(except_vec_nmi) | 370 | END(except_vec_nmi) |
358 | 371 | ||
359 | __FINIT | 372 | __FINIT |
@@ -480,7 +493,7 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
480 | .set noreorder | 493 | .set noreorder |
481 | /* check if TLB contains a entry for EPC */ | 494 | /* check if TLB contains a entry for EPC */ |
482 | MFC0 k1, CP0_ENTRYHI | 495 | MFC0 k1, CP0_ENTRYHI |
483 | andi k1, 0xff /* ASID_MASK */ | 496 | andi k1, 0xff /* ASID_MASK patched at run-time!! */ |
484 | MFC0 k0, CP0_EPC | 497 | MFC0 k0, CP0_EPC |
485 | PTR_SRL k0, _PAGE_SHIFT + 1 | 498 | PTR_SRL k0, _PAGE_SHIFT + 1 |
486 | PTR_SLL k0, _PAGE_SHIFT + 1 | 499 | PTR_SLL k0, _PAGE_SHIFT + 1 |
@@ -500,13 +513,35 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
500 | .set push | 513 | .set push |
501 | .set noat | 514 | .set noat |
502 | .set noreorder | 515 | .set noreorder |
503 | /* 0x7c03e83b: rdhwr v1,$29 */ | 516 | /* MIPS32: 0x7c03e83b: rdhwr v1,$29 */ |
517 | /* microMIPS: 0x007d6b3c: rdhwr v1,$29 */ | ||
504 | MFC0 k1, CP0_EPC | 518 | MFC0 k1, CP0_EPC |
505 | lui k0, 0x7c03 | 519 | #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS64_R2) |
506 | lw k1, (k1) | 520 | and k0, k1, 1 |
507 | ori k0, 0xe83b | 521 | beqz k0, 1f |
508 | .set reorder | 522 | xor k1, k0 |
523 | lhu k0, (k1) | ||
524 | lhu k1, 2(k1) | ||
525 | ins k1, k0, 16, 16 | ||
526 | lui k0, 0x007d | ||
527 | b docheck | ||
528 | ori k0, 0x6b3c | ||
529 | 1: | ||
530 | lui k0, 0x7c03 | ||
531 | lw k1, (k1) | ||
532 | ori k0, 0xe83b | ||
533 | #else | ||
534 | andi k0, k1, 1 | ||
535 | bnez k0, handle_ri | ||
536 | lui k0, 0x7c03 | ||
537 | lw k1, (k1) | ||
538 | ori k0, 0xe83b | ||
539 | #endif | ||
540 | .set reorder | ||
541 | docheck: | ||
509 | bne k0, k1, handle_ri /* if not ours */ | 542 | bne k0, k1, handle_ri /* if not ours */ |
543 | |||
544 | isrdhwr: | ||
510 | /* The insn is rdhwr. No need to check CAUSE.BD here. */ | 545 | /* The insn is rdhwr. No need to check CAUSE.BD here. */ |
511 | get_saved_sp /* k1 := current_thread_info */ | 546 | get_saved_sp /* k1 := current_thread_info */ |
512 | .set noreorder | 547 | .set noreorder |
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index 485e6a961b31..c01b307317a9 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/smp.h> | 11 | #include <linux/smp.h> |
12 | #include <linux/irq.h> | 12 | #include <linux/irq.h> |
13 | #include <linux/clocksource.h> | ||
13 | 14 | ||
14 | #include <asm/io.h> | 15 | #include <asm/io.h> |
15 | #include <asm/gic.h> | 16 | #include <asm/gic.h> |
@@ -19,6 +20,8 @@ | |||
19 | #include <linux/hardirq.h> | 20 | #include <linux/hardirq.h> |
20 | #include <asm-generic/bitops/find.h> | 21 | #include <asm-generic/bitops/find.h> |
21 | 22 | ||
23 | unsigned int gic_frequency; | ||
24 | unsigned int gic_present; | ||
22 | unsigned long _gic_base; | 25 | unsigned long _gic_base; |
23 | unsigned int gic_irq_base; | 26 | unsigned int gic_irq_base; |
24 | unsigned int gic_irq_flags[GIC_NUM_INTRS]; | 27 | unsigned int gic_irq_flags[GIC_NUM_INTRS]; |
@@ -30,6 +33,39 @@ static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; | |||
30 | static struct gic_pending_regs pending_regs[NR_CPUS]; | 33 | static struct gic_pending_regs pending_regs[NR_CPUS]; |
31 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; | 34 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; |
32 | 35 | ||
36 | #if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC) | ||
37 | cycle_t gic_read_count(void) | ||
38 | { | ||
39 | unsigned int hi, hi2, lo; | ||
40 | |||
41 | do { | ||
42 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi); | ||
43 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo); | ||
44 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2); | ||
45 | } while (hi2 != hi); | ||
46 | |||
47 | return (((cycle_t) hi) << 32) + lo; | ||
48 | } | ||
49 | |||
50 | void gic_write_compare(cycle_t cnt) | ||
51 | { | ||
52 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), | ||
53 | (int)(cnt >> 32)); | ||
54 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), | ||
55 | (int)(cnt & 0xffffffff)); | ||
56 | } | ||
57 | |||
58 | cycle_t gic_read_compare(void) | ||
59 | { | ||
60 | unsigned int hi, lo; | ||
61 | |||
62 | GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), hi); | ||
63 | GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), lo); | ||
64 | |||
65 | return (((cycle_t) hi) << 32) + lo; | ||
66 | } | ||
67 | #endif | ||
68 | |||
33 | unsigned int gic_get_timer_pending(void) | 69 | unsigned int gic_get_timer_pending(void) |
34 | { | 70 | { |
35 | unsigned int vpe_pending; | 71 | unsigned int vpe_pending; |
@@ -116,6 +152,17 @@ static void __init vpe_local_setup(unsigned int numvpes) | |||
116 | } | 152 | } |
117 | } | 153 | } |
118 | 154 | ||
155 | unsigned int gic_compare_int(void) | ||
156 | { | ||
157 | unsigned int pending; | ||
158 | |||
159 | GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), pending); | ||
160 | if (pending & GIC_VPE_PEND_CMP_MSK) | ||
161 | return 1; | ||
162 | else | ||
163 | return 0; | ||
164 | } | ||
165 | |||
119 | unsigned int gic_get_int(void) | 166 | unsigned int gic_get_int(void) |
120 | { | 167 | { |
121 | unsigned int i; | 168 | unsigned int i; |
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 1dd137bab5c5..a3e461408b7e 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -99,6 +99,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
99 | if (cpu_has_vz) seq_printf(m, "%s", " vz"); | 99 | if (cpu_has_vz) seq_printf(m, "%s", " vz"); |
100 | seq_printf(m, "\n"); | 100 | seq_printf(m, "\n"); |
101 | 101 | ||
102 | if (cpu_has_mmips) { | ||
103 | seq_printf(m, "micromips kernel\t: %s\n", | ||
104 | (read_c0_config3() & MIPS_CONF3_ISA_OE) ? "yes" : "no"); | ||
105 | } | ||
102 | seq_printf(m, "shadow register sets\t: %d\n", | 106 | seq_printf(m, "shadow register sets\t: %d\n", |
103 | cpu_data[n].srsets); | 107 | cpu_data[n].srsets); |
104 | seq_printf(m, "kscratch registers\t: %d\n", | 108 | seq_printf(m, "kscratch registers\t: %d\n", |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 3be4405c2d14..ef533760d2c8 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Copyright (C) 2005, 2006 by Ralf Baechle (ralf@linux-mips.org) | 7 | * Copyright (C) 2005, 2006 by Ralf Baechle (ralf@linux-mips.org) |
8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
9 | * Copyright (C) 2004 Thiemo Seufer | 9 | * Copyright (C) 2004 Thiemo Seufer |
10 | * Copyright (C) 2013 Imagination Technologies Ltd. | ||
10 | */ | 11 | */ |
11 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
12 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
@@ -243,34 +244,115 @@ struct mips_frame_info { | |||
243 | 244 | ||
244 | static inline int is_ra_save_ins(union mips_instruction *ip) | 245 | static inline int is_ra_save_ins(union mips_instruction *ip) |
245 | { | 246 | { |
247 | #ifdef CONFIG_CPU_MICROMIPS | ||
248 | union mips_instruction mmi; | ||
249 | |||
250 | /* | ||
251 | * swsp ra,offset | ||
252 | * swm16 reglist,offset(sp) | ||
253 | * swm32 reglist,offset(sp) | ||
254 | * sw32 ra,offset(sp) | ||
255 | * jradiussp - NOT SUPPORTED | ||
256 | * | ||
257 | * microMIPS is way more fun... | ||
258 | */ | ||
259 | if (mm_insn_16bit(ip->halfword[0])) { | ||
260 | mmi.word = (ip->halfword[0] << 16); | ||
261 | return ((mmi.mm16_r5_format.opcode == mm_swsp16_op && | ||
262 | mmi.mm16_r5_format.rt == 31) || | ||
263 | (mmi.mm16_m_format.opcode == mm_pool16c_op && | ||
264 | mmi.mm16_m_format.func == mm_swm16_op)); | ||
265 | } | ||
266 | else { | ||
267 | mmi.halfword[0] = ip->halfword[1]; | ||
268 | mmi.halfword[1] = ip->halfword[0]; | ||
269 | return ((mmi.mm_m_format.opcode == mm_pool32b_op && | ||
270 | mmi.mm_m_format.rd > 9 && | ||
271 | mmi.mm_m_format.base == 29 && | ||
272 | mmi.mm_m_format.func == mm_swm32_func) || | ||
273 | (mmi.i_format.opcode == mm_sw32_op && | ||
274 | mmi.i_format.rs == 29 && | ||
275 | mmi.i_format.rt == 31)); | ||
276 | } | ||
277 | #else | ||
246 | /* sw / sd $ra, offset($sp) */ | 278 | /* sw / sd $ra, offset($sp) */ |
247 | return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) && | 279 | return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) && |
248 | ip->i_format.rs == 29 && | 280 | ip->i_format.rs == 29 && |
249 | ip->i_format.rt == 31; | 281 | ip->i_format.rt == 31; |
282 | #endif | ||
250 | } | 283 | } |
251 | 284 | ||
252 | static inline int is_jal_jalr_jr_ins(union mips_instruction *ip) | 285 | static inline int is_jal_jalr_jr_ins(union mips_instruction *ip) |
253 | { | 286 | { |
287 | #ifdef CONFIG_CPU_MICROMIPS | ||
288 | /* | ||
289 | * jr16,jrc,jalr16,jalr16 | ||
290 | * jal | ||
291 | * jalr/jr,jalr.hb/jr.hb,jalrs,jalrs.hb | ||
292 | * jraddiusp - NOT SUPPORTED | ||
293 | * | ||
294 | * microMIPS is kind of more fun... | ||
295 | */ | ||
296 | union mips_instruction mmi; | ||
297 | |||
298 | mmi.word = (ip->halfword[0] << 16); | ||
299 | |||
300 | if ((mmi.mm16_r5_format.opcode == mm_pool16c_op && | ||
301 | (mmi.mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) || | ||
302 | ip->j_format.opcode == mm_jal32_op) | ||
303 | return 1; | ||
304 | if (ip->r_format.opcode != mm_pool32a_op || | ||
305 | ip->r_format.func != mm_pool32axf_op) | ||
306 | return 0; | ||
307 | return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); | ||
308 | #else | ||
254 | if (ip->j_format.opcode == jal_op) | 309 | if (ip->j_format.opcode == jal_op) |
255 | return 1; | 310 | return 1; |
256 | if (ip->r_format.opcode != spec_op) | 311 | if (ip->r_format.opcode != spec_op) |
257 | return 0; | 312 | return 0; |
258 | return ip->r_format.func == jalr_op || ip->r_format.func == jr_op; | 313 | return ip->r_format.func == jalr_op || ip->r_format.func == jr_op; |
314 | #endif | ||
259 | } | 315 | } |
260 | 316 | ||
261 | static inline int is_sp_move_ins(union mips_instruction *ip) | 317 | static inline int is_sp_move_ins(union mips_instruction *ip) |
262 | { | 318 | { |
319 | #ifdef CONFIG_CPU_MICROMIPS | ||
320 | /* | ||
321 | * addiusp -imm | ||
322 | * addius5 sp,-imm | ||
323 | * addiu32 sp,sp,-imm | ||
324 | * jradiussp - NOT SUPPORTED | ||
325 | * | ||
326 | * microMIPS is not more fun... | ||
327 | */ | ||
328 | if (mm_insn_16bit(ip->halfword[0])) { | ||
329 | union mips_instruction mmi; | ||
330 | |||
331 | mmi.word = (ip->halfword[0] << 16); | ||
332 | return ((mmi.mm16_r3_format.opcode == mm_pool16d_op && | ||
333 | mmi.mm16_r3_format.simmediate && mm_addiusp_func) || | ||
334 | (mmi.mm16_r5_format.opcode == mm_pool16d_op && | ||
335 | mmi.mm16_r5_format.rt == 29)); | ||
336 | } | ||
337 | return (ip->mm_i_format.opcode == mm_addiu32_op && | ||
338 | ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29); | ||
339 | #else | ||
263 | /* addiu/daddiu sp,sp,-imm */ | 340 | /* addiu/daddiu sp,sp,-imm */ |
264 | if (ip->i_format.rs != 29 || ip->i_format.rt != 29) | 341 | if (ip->i_format.rs != 29 || ip->i_format.rt != 29) |
265 | return 0; | 342 | return 0; |
266 | if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op) | 343 | if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op) |
267 | return 1; | 344 | return 1; |
345 | #endif | ||
268 | return 0; | 346 | return 0; |
269 | } | 347 | } |
270 | 348 | ||
271 | static int get_frame_info(struct mips_frame_info *info) | 349 | static int get_frame_info(struct mips_frame_info *info) |
272 | { | 350 | { |
351 | #ifdef CONFIG_CPU_MICROMIPS | ||
352 | union mips_instruction *ip = (void *) (((char *) info->func) - 1); | ||
353 | #else | ||
273 | union mips_instruction *ip = info->func; | 354 | union mips_instruction *ip = info->func; |
355 | #endif | ||
274 | unsigned max_insns = info->func_size / sizeof(union mips_instruction); | 356 | unsigned max_insns = info->func_size / sizeof(union mips_instruction); |
275 | unsigned i; | 357 | unsigned i; |
276 | 358 | ||
@@ -290,7 +372,26 @@ static int get_frame_info(struct mips_frame_info *info) | |||
290 | break; | 372 | break; |
291 | if (!info->frame_size) { | 373 | if (!info->frame_size) { |
292 | if (is_sp_move_ins(ip)) | 374 | if (is_sp_move_ins(ip)) |
375 | { | ||
376 | #ifdef CONFIG_CPU_MICROMIPS | ||
377 | if (mm_insn_16bit(ip->halfword[0])) | ||
378 | { | ||
379 | unsigned short tmp; | ||
380 | |||
381 | if (ip->halfword[0] & mm_addiusp_func) | ||
382 | { | ||
383 | tmp = (((ip->halfword[0] >> 1) & 0x1ff) << 2); | ||
384 | info->frame_size = -(signed short)(tmp | ((tmp & 0x100) ? 0xfe00 : 0)); | ||
385 | } else { | ||
386 | tmp = (ip->halfword[0] >> 1); | ||
387 | info->frame_size = -(signed short)(tmp & 0xf); | ||
388 | } | ||
389 | ip = (void *) &ip->halfword[1]; | ||
390 | ip--; | ||
391 | } else | ||
392 | #endif | ||
293 | info->frame_size = - ip->i_format.simmediate; | 393 | info->frame_size = - ip->i_format.simmediate; |
394 | } | ||
294 | continue; | 395 | continue; |
295 | } | 396 | } |
296 | if (info->pc_offset == -1 && is_ra_save_ins(ip)) { | 397 | if (info->pc_offset == -1 && is_ra_save_ins(ip)) { |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 9ea29649fc28..9b36424b03c5 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -138,9 +138,18 @@ stackargs: | |||
138 | 5: jr t1 | 138 | 5: jr t1 |
139 | sw t5, 16(sp) # argument #5 to ksp | 139 | sw t5, 16(sp) # argument #5 to ksp |
140 | 140 | ||
141 | #ifdef CONFIG_CPU_MICROMIPS | ||
141 | sw t8, 28(sp) # argument #8 to ksp | 142 | sw t8, 28(sp) # argument #8 to ksp |
143 | nop | ||
142 | sw t7, 24(sp) # argument #7 to ksp | 144 | sw t7, 24(sp) # argument #7 to ksp |
145 | nop | ||
143 | sw t6, 20(sp) # argument #6 to ksp | 146 | sw t6, 20(sp) # argument #6 to ksp |
147 | nop | ||
148 | #else | ||
149 | sw t8, 28(sp) # argument #8 to ksp | ||
150 | sw t7, 24(sp) # argument #7 to ksp | ||
151 | sw t6, 20(sp) # argument #6 to ksp | ||
152 | #endif | ||
144 | 6: j stack_done # go back | 153 | 6: j stack_done # go back |
145 | nop | 154 | nop |
146 | .set pop | 155 | .set pop |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index b5e88fd83277..fd3ef2c2afbc 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/war.h> | 35 | #include <asm/war.h> |
36 | #include <asm/vdso.h> | 36 | #include <asm/vdso.h> |
37 | #include <asm/dsp.h> | 37 | #include <asm/dsp.h> |
38 | #include <asm/inst.h> | ||
38 | 39 | ||
39 | #include "signal-common.h" | 40 | #include "signal-common.h" |
40 | 41 | ||
@@ -480,7 +481,15 @@ static void handle_signal(unsigned long sig, siginfo_t *info, | |||
480 | sigset_t *oldset = sigmask_to_save(); | 481 | sigset_t *oldset = sigmask_to_save(); |
481 | int ret; | 482 | int ret; |
482 | struct mips_abi *abi = current->thread.abi; | 483 | struct mips_abi *abi = current->thread.abi; |
484 | #ifdef CONFIG_CPU_MICROMIPS | ||
485 | void *vdso; | ||
486 | unsigned int tmp = (unsigned int)current->mm->context.vdso; | ||
487 | |||
488 | set_isa16_mode(tmp); | ||
489 | vdso = (void *)tmp; | ||
490 | #else | ||
483 | void *vdso = current->mm->context.vdso; | 491 | void *vdso = current->mm->context.vdso; |
492 | #endif | ||
484 | 493 | ||
485 | if (regs->regs[0]) { | 494 | if (regs->regs[0]) { |
486 | switch(regs->regs[2]) { | 495 | switch(regs->regs[2]) { |
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index bfede063d96a..3e5164c11cac 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/mipsregs.h> | 34 | #include <asm/mipsregs.h> |
35 | #include <asm/mipsmtregs.h> | 35 | #include <asm/mipsmtregs.h> |
36 | #include <asm/mips_mt.h> | 36 | #include <asm/mips_mt.h> |
37 | #include <asm/gic.h> | ||
37 | 38 | ||
38 | static void __init smvp_copy_vpe_config(void) | 39 | static void __init smvp_copy_vpe_config(void) |
39 | { | 40 | { |
@@ -151,8 +152,6 @@ static void vsmp_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |||
151 | static void __cpuinit vsmp_init_secondary(void) | 152 | static void __cpuinit vsmp_init_secondary(void) |
152 | { | 153 | { |
153 | #ifdef CONFIG_IRQ_GIC | 154 | #ifdef CONFIG_IRQ_GIC |
154 | extern int gic_present; | ||
155 | |||
156 | /* This is Malta specific: IPI,performance and timer interrupts */ | 155 | /* This is Malta specific: IPI,performance and timer interrupts */ |
157 | if (gic_present) | 156 | if (gic_present) |
158 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | | 157 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | |
diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S index 76016ac0a9c8..2866863a39df 100644 --- a/arch/mips/kernel/smtc-asm.S +++ b/arch/mips/kernel/smtc-asm.S | |||
@@ -49,6 +49,9 @@ CAN WE PROVE THAT WE WON'T DO THIS IF INTS DISABLED?? | |||
49 | .text | 49 | .text |
50 | .align 5 | 50 | .align 5 |
51 | FEXPORT(__smtc_ipi_vector) | 51 | FEXPORT(__smtc_ipi_vector) |
52 | #ifdef CONFIG_CPU_MICROMIPS | ||
53 | nop | ||
54 | #endif | ||
52 | .set noat | 55 | .set noat |
53 | /* Disable thread scheduling to make Status update atomic */ | 56 | /* Disable thread scheduling to make Status update atomic */ |
54 | DMT 27 # dmt k1 | 57 | DMT 27 # dmt k1 |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 7186222dc5bb..31d22f3121c9 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -111,7 +111,7 @@ static int vpe0limit; | |||
111 | static int ipibuffers; | 111 | static int ipibuffers; |
112 | static int nostlb; | 112 | static int nostlb; |
113 | static int asidmask; | 113 | static int asidmask; |
114 | unsigned long smtc_asid_mask = 0xff; | 114 | unsigned int smtc_asid_mask = 0xff; |
115 | 115 | ||
116 | static int __init vpe0tcs(char *str) | 116 | static int __init vpe0tcs(char *str) |
117 | { | 117 | { |
@@ -1395,7 +1395,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
1395 | asid = asid_cache(cpu); | 1395 | asid = asid_cache(cpu); |
1396 | 1396 | ||
1397 | do { | 1397 | do { |
1398 | if (!((asid += ASID_INC) & ASID_MASK) ) { | 1398 | if (!ASID_MASK(ASID_INC(asid))) { |
1399 | if (cpu_has_vtag_icache) | 1399 | if (cpu_has_vtag_icache) |
1400 | flush_icache_all(); | 1400 | flush_icache_all(); |
1401 | /* Traverse all online CPUs (hack requires contiguous range) */ | 1401 | /* Traverse all online CPUs (hack requires contiguous range) */ |
@@ -1414,7 +1414,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
1414 | mips_ihb(); | 1414 | mips_ihb(); |
1415 | } | 1415 | } |
1416 | tcstat = read_tc_c0_tcstatus(); | 1416 | tcstat = read_tc_c0_tcstatus(); |
1417 | smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i); | 1417 | smtc_live_asid[tlb][ASID_MASK(tcstat)] |= (asiduse)(0x1 << i); |
1418 | if (!prevhalt) | 1418 | if (!prevhalt) |
1419 | write_tc_c0_tchalt(0); | 1419 | write_tc_c0_tchalt(0); |
1420 | } | 1420 | } |
@@ -1423,7 +1423,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
1423 | asid = ASID_FIRST_VERSION; | 1423 | asid = ASID_FIRST_VERSION; |
1424 | local_flush_tlb_all(); /* start new asid cycle */ | 1424 | local_flush_tlb_all(); /* start new asid cycle */ |
1425 | } | 1425 | } |
1426 | } while (smtc_live_asid[tlb][(asid & ASID_MASK)]); | 1426 | } while (smtc_live_asid[tlb][ASID_MASK(asid)]); |
1427 | 1427 | ||
1428 | /* | 1428 | /* |
1429 | * SMTC shares the TLB within VPEs and possibly across all VPEs. | 1429 | * SMTC shares the TLB within VPEs and possibly across all VPEs. |
@@ -1461,7 +1461,7 @@ void smtc_flush_tlb_asid(unsigned long asid) | |||
1461 | tlb_read(); | 1461 | tlb_read(); |
1462 | ehb(); | 1462 | ehb(); |
1463 | ehi = read_c0_entryhi(); | 1463 | ehi = read_c0_entryhi(); |
1464 | if ((ehi & ASID_MASK) == asid) { | 1464 | if (ASID_MASK(ehi) == asid) { |
1465 | /* | 1465 | /* |
1466 | * Invalidate only entries with specified ASID, | 1466 | * Invalidate only entries with specified ASID, |
1467 | * makiing sure all entries differ. | 1467 | * makiing sure all entries differ. |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 7a99e60dadbd..3c906e723fd4 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -8,8 +8,8 @@ | |||
8 | * Copyright (C) 1998 Ulf Carlsson | 8 | * Copyright (C) 1998 Ulf Carlsson |
9 | * Copyright (C) 1999 Silicon Graphics, Inc. | 9 | * Copyright (C) 1999 Silicon Graphics, Inc. |
10 | * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com | 10 | * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com |
11 | * Copyright (C) 2000, 01 MIPS Technologies, Inc. | ||
12 | * Copyright (C) 2002, 2003, 2004, 2005, 2007 Maciej W. Rozycki | 11 | * Copyright (C) 2002, 2003, 2004, 2005, 2007 Maciej W. Rozycki |
12 | * Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc. All rights reserved. | ||
13 | */ | 13 | */ |
14 | #include <linux/bug.h> | 14 | #include <linux/bug.h> |
15 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
@@ -83,10 +83,6 @@ extern asmlinkage void handle_dsp(void); | |||
83 | extern asmlinkage void handle_mcheck(void); | 83 | extern asmlinkage void handle_mcheck(void); |
84 | extern asmlinkage void handle_reserved(void); | 84 | extern asmlinkage void handle_reserved(void); |
85 | 85 | ||
86 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, | ||
87 | struct mips_fpu_struct *ctx, int has_fpu, | ||
88 | void *__user *fault_addr); | ||
89 | |||
90 | void (*board_be_init)(void); | 86 | void (*board_be_init)(void); |
91 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); | 87 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); |
92 | void (*board_nmi_handler_setup)(void); | 88 | void (*board_nmi_handler_setup)(void); |
@@ -495,6 +491,12 @@ asmlinkage void do_be(struct pt_regs *regs) | |||
495 | #define SYNC 0x0000000f | 491 | #define SYNC 0x0000000f |
496 | #define RDHWR 0x0000003b | 492 | #define RDHWR 0x0000003b |
497 | 493 | ||
494 | /* microMIPS definitions */ | ||
495 | #define MM_POOL32A_FUNC 0xfc00ffff | ||
496 | #define MM_RDHWR 0x00006b3c | ||
497 | #define MM_RS 0x001f0000 | ||
498 | #define MM_RT 0x03e00000 | ||
499 | |||
498 | /* | 500 | /* |
499 | * The ll_bit is cleared by r*_switch.S | 501 | * The ll_bit is cleared by r*_switch.S |
500 | */ | 502 | */ |
@@ -609,42 +611,62 @@ static int simulate_llsc(struct pt_regs *regs, unsigned int opcode) | |||
609 | * Simulate trapping 'rdhwr' instructions to provide user accessible | 611 | * Simulate trapping 'rdhwr' instructions to provide user accessible |
610 | * registers not implemented in hardware. | 612 | * registers not implemented in hardware. |
611 | */ | 613 | */ |
612 | static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode) | 614 | static int simulate_rdhwr(struct pt_regs *regs, int rd, int rt) |
613 | { | 615 | { |
614 | struct thread_info *ti = task_thread_info(current); | 616 | struct thread_info *ti = task_thread_info(current); |
615 | 617 | ||
618 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, | ||
619 | 1, regs, 0); | ||
620 | switch (rd) { | ||
621 | case 0: /* CPU number */ | ||
622 | regs->regs[rt] = smp_processor_id(); | ||
623 | return 0; | ||
624 | case 1: /* SYNCI length */ | ||
625 | regs->regs[rt] = min(current_cpu_data.dcache.linesz, | ||
626 | current_cpu_data.icache.linesz); | ||
627 | return 0; | ||
628 | case 2: /* Read count register */ | ||
629 | regs->regs[rt] = read_c0_count(); | ||
630 | return 0; | ||
631 | case 3: /* Count register resolution */ | ||
632 | switch (current_cpu_data.cputype) { | ||
633 | case CPU_20KC: | ||
634 | case CPU_25KF: | ||
635 | regs->regs[rt] = 1; | ||
636 | break; | ||
637 | default: | ||
638 | regs->regs[rt] = 2; | ||
639 | } | ||
640 | return 0; | ||
641 | case 29: | ||
642 | regs->regs[rt] = ti->tp_value; | ||
643 | return 0; | ||
644 | default: | ||
645 | return -1; | ||
646 | } | ||
647 | } | ||
648 | |||
649 | static int simulate_rdhwr_normal(struct pt_regs *regs, unsigned int opcode) | ||
650 | { | ||
616 | if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) { | 651 | if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) { |
617 | int rd = (opcode & RD) >> 11; | 652 | int rd = (opcode & RD) >> 11; |
618 | int rt = (opcode & RT) >> 16; | 653 | int rt = (opcode & RT) >> 16; |
619 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, | 654 | |
620 | 1, regs, 0); | 655 | simulate_rdhwr(regs, rd, rt); |
621 | switch (rd) { | 656 | return 0; |
622 | case 0: /* CPU number */ | 657 | } |
623 | regs->regs[rt] = smp_processor_id(); | 658 | |
624 | return 0; | 659 | /* Not ours. */ |
625 | case 1: /* SYNCI length */ | 660 | return -1; |
626 | regs->regs[rt] = min(current_cpu_data.dcache.linesz, | 661 | } |
627 | current_cpu_data.icache.linesz); | 662 | |
628 | return 0; | 663 | static int simulate_rdhwr_mm(struct pt_regs *regs, unsigned short opcode) |
629 | case 2: /* Read count register */ | 664 | { |
630 | regs->regs[rt] = read_c0_count(); | 665 | if ((opcode & MM_POOL32A_FUNC) == MM_RDHWR) { |
631 | return 0; | 666 | int rd = (opcode & MM_RS) >> 16; |
632 | case 3: /* Count register resolution */ | 667 | int rt = (opcode & MM_RT) >> 21; |
633 | switch (current_cpu_data.cputype) { | 668 | simulate_rdhwr(regs, rd, rt); |
634 | case CPU_20KC: | 669 | return 0; |
635 | case CPU_25KF: | ||
636 | regs->regs[rt] = 1; | ||
637 | break; | ||
638 | default: | ||
639 | regs->regs[rt] = 2; | ||
640 | } | ||
641 | return 0; | ||
642 | case 29: | ||
643 | regs->regs[rt] = ti->tp_value; | ||
644 | return 0; | ||
645 | default: | ||
646 | return -1; | ||
647 | } | ||
648 | } | 670 | } |
649 | 671 | ||
650 | /* Not ours. */ | 672 | /* Not ours. */ |
@@ -675,7 +697,7 @@ asmlinkage void do_ov(struct pt_regs *regs) | |||
675 | force_sig_info(SIGFPE, &info, current); | 697 | force_sig_info(SIGFPE, &info, current); |
676 | } | 698 | } |
677 | 699 | ||
678 | static int process_fpemu_return(int sig, void __user *fault_addr) | 700 | int process_fpemu_return(int sig, void __user *fault_addr) |
679 | { | 701 | { |
680 | if (sig == SIGSEGV || sig == SIGBUS) { | 702 | if (sig == SIGSEGV || sig == SIGBUS) { |
681 | struct siginfo si = {0}; | 703 | struct siginfo si = {0}; |
@@ -826,9 +848,29 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, | |||
826 | asmlinkage void do_bp(struct pt_regs *regs) | 848 | asmlinkage void do_bp(struct pt_regs *regs) |
827 | { | 849 | { |
828 | unsigned int opcode, bcode; | 850 | unsigned int opcode, bcode; |
829 | 851 | unsigned long epc; | |
830 | if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) | 852 | u16 instr[2]; |
831 | goto out_sigsegv; | 853 | |
854 | if (get_isa16_mode(regs->cp0_epc)) { | ||
855 | /* Calculate EPC. */ | ||
856 | epc = exception_epc(regs); | ||
857 | if (cpu_has_mmips) { | ||
858 | if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc)) || | ||
859 | (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2))))) | ||
860 | goto out_sigsegv; | ||
861 | opcode = (instr[0] << 16) | instr[1]; | ||
862 | } else { | ||
863 | /* MIPS16e mode */ | ||
864 | if (__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc))) | ||
865 | goto out_sigsegv; | ||
866 | bcode = (instr[0] >> 6) & 0x3f; | ||
867 | do_trap_or_bp(regs, bcode, "Break"); | ||
868 | return; | ||
869 | } | ||
870 | } else { | ||
871 | if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) | ||
872 | goto out_sigsegv; | ||
873 | } | ||
832 | 874 | ||
833 | /* | 875 | /* |
834 | * There is the ancient bug in the MIPS assemblers that the break | 876 | * There is the ancient bug in the MIPS assemblers that the break |
@@ -869,13 +911,22 @@ out_sigsegv: | |||
869 | asmlinkage void do_tr(struct pt_regs *regs) | 911 | asmlinkage void do_tr(struct pt_regs *regs) |
870 | { | 912 | { |
871 | unsigned int opcode, tcode = 0; | 913 | unsigned int opcode, tcode = 0; |
914 | u16 instr[2]; | ||
915 | unsigned long epc = exception_epc(regs); | ||
872 | 916 | ||
873 | if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) | 917 | if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc))) || |
874 | goto out_sigsegv; | 918 | (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2)))) |
919 | goto out_sigsegv; | ||
920 | opcode = (instr[0] << 16) | instr[1]; | ||
875 | 921 | ||
876 | /* Immediate versions don't provide a code. */ | 922 | /* Immediate versions don't provide a code. */ |
877 | if (!(opcode & OPCODE)) | 923 | if (!(opcode & OPCODE)) { |
878 | tcode = ((opcode >> 6) & ((1 << 10) - 1)); | 924 | if (get_isa16_mode(regs->cp0_epc)) |
925 | /* microMIPS */ | ||
926 | tcode = (opcode >> 12) & 0x1f; | ||
927 | else | ||
928 | tcode = ((opcode >> 6) & ((1 << 10) - 1)); | ||
929 | } | ||
879 | 930 | ||
880 | do_trap_or_bp(regs, tcode, "Trap"); | 931 | do_trap_or_bp(regs, tcode, "Trap"); |
881 | return; | 932 | return; |
@@ -888,6 +939,7 @@ asmlinkage void do_ri(struct pt_regs *regs) | |||
888 | { | 939 | { |
889 | unsigned int __user *epc = (unsigned int __user *)exception_epc(regs); | 940 | unsigned int __user *epc = (unsigned int __user *)exception_epc(regs); |
890 | unsigned long old_epc = regs->cp0_epc; | 941 | unsigned long old_epc = regs->cp0_epc; |
942 | unsigned long old31 = regs->regs[31]; | ||
891 | unsigned int opcode = 0; | 943 | unsigned int opcode = 0; |
892 | int status = -1; | 944 | int status = -1; |
893 | 945 | ||
@@ -900,23 +952,37 @@ asmlinkage void do_ri(struct pt_regs *regs) | |||
900 | if (unlikely(compute_return_epc(regs) < 0)) | 952 | if (unlikely(compute_return_epc(regs) < 0)) |
901 | return; | 953 | return; |
902 | 954 | ||
903 | if (unlikely(get_user(opcode, epc) < 0)) | 955 | if (get_isa16_mode(regs->cp0_epc)) { |
904 | status = SIGSEGV; | 956 | unsigned short mmop[2] = { 0 }; |
905 | 957 | ||
906 | if (!cpu_has_llsc && status < 0) | 958 | if (unlikely(get_user(mmop[0], epc) < 0)) |
907 | status = simulate_llsc(regs, opcode); | 959 | status = SIGSEGV; |
960 | if (unlikely(get_user(mmop[1], epc) < 0)) | ||
961 | status = SIGSEGV; | ||
962 | opcode = (mmop[0] << 16) | mmop[1]; | ||
908 | 963 | ||
909 | if (status < 0) | 964 | if (status < 0) |
910 | status = simulate_rdhwr(regs, opcode); | 965 | status = simulate_rdhwr_mm(regs, opcode); |
966 | } else { | ||
967 | if (unlikely(get_user(opcode, epc) < 0)) | ||
968 | status = SIGSEGV; | ||
911 | 969 | ||
912 | if (status < 0) | 970 | if (!cpu_has_llsc && status < 0) |
913 | status = simulate_sync(regs, opcode); | 971 | status = simulate_llsc(regs, opcode); |
972 | |||
973 | if (status < 0) | ||
974 | status = simulate_rdhwr_normal(regs, opcode); | ||
975 | |||
976 | if (status < 0) | ||
977 | status = simulate_sync(regs, opcode); | ||
978 | } | ||
914 | 979 | ||
915 | if (status < 0) | 980 | if (status < 0) |
916 | status = SIGILL; | 981 | status = SIGILL; |
917 | 982 | ||
918 | if (unlikely(status > 0)) { | 983 | if (unlikely(status > 0)) { |
919 | regs->cp0_epc = old_epc; /* Undo skip-over. */ | 984 | regs->cp0_epc = old_epc; /* Undo skip-over. */ |
985 | regs->regs[31] = old31; | ||
920 | force_sig(status, current); | 986 | force_sig(status, current); |
921 | } | 987 | } |
922 | } | 988 | } |
@@ -986,7 +1052,7 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action, | |||
986 | asmlinkage void do_cpu(struct pt_regs *regs) | 1052 | asmlinkage void do_cpu(struct pt_regs *regs) |
987 | { | 1053 | { |
988 | unsigned int __user *epc; | 1054 | unsigned int __user *epc; |
989 | unsigned long old_epc; | 1055 | unsigned long old_epc, old31; |
990 | unsigned int opcode; | 1056 | unsigned int opcode; |
991 | unsigned int cpid; | 1057 | unsigned int cpid; |
992 | int status; | 1058 | int status; |
@@ -1000,26 +1066,41 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
1000 | case 0: | 1066 | case 0: |
1001 | epc = (unsigned int __user *)exception_epc(regs); | 1067 | epc = (unsigned int __user *)exception_epc(regs); |
1002 | old_epc = regs->cp0_epc; | 1068 | old_epc = regs->cp0_epc; |
1069 | old31 = regs->regs[31]; | ||
1003 | opcode = 0; | 1070 | opcode = 0; |
1004 | status = -1; | 1071 | status = -1; |
1005 | 1072 | ||
1006 | if (unlikely(compute_return_epc(regs) < 0)) | 1073 | if (unlikely(compute_return_epc(regs) < 0)) |
1007 | return; | 1074 | return; |
1008 | 1075 | ||
1009 | if (unlikely(get_user(opcode, epc) < 0)) | 1076 | if (get_isa16_mode(regs->cp0_epc)) { |
1010 | status = SIGSEGV; | 1077 | unsigned short mmop[2] = { 0 }; |
1011 | 1078 | ||
1012 | if (!cpu_has_llsc && status < 0) | 1079 | if (unlikely(get_user(mmop[0], epc) < 0)) |
1013 | status = simulate_llsc(regs, opcode); | 1080 | status = SIGSEGV; |
1081 | if (unlikely(get_user(mmop[1], epc) < 0)) | ||
1082 | status = SIGSEGV; | ||
1083 | opcode = (mmop[0] << 16) | mmop[1]; | ||
1014 | 1084 | ||
1015 | if (status < 0) | 1085 | if (status < 0) |
1016 | status = simulate_rdhwr(regs, opcode); | 1086 | status = simulate_rdhwr_mm(regs, opcode); |
1087 | } else { | ||
1088 | if (unlikely(get_user(opcode, epc) < 0)) | ||
1089 | status = SIGSEGV; | ||
1090 | |||
1091 | if (!cpu_has_llsc && status < 0) | ||
1092 | status = simulate_llsc(regs, opcode); | ||
1093 | |||
1094 | if (status < 0) | ||
1095 | status = simulate_rdhwr_normal(regs, opcode); | ||
1096 | } | ||
1017 | 1097 | ||
1018 | if (status < 0) | 1098 | if (status < 0) |
1019 | status = SIGILL; | 1099 | status = SIGILL; |
1020 | 1100 | ||
1021 | if (unlikely(status > 0)) { | 1101 | if (unlikely(status > 0)) { |
1022 | regs->cp0_epc = old_epc; /* Undo skip-over. */ | 1102 | regs->cp0_epc = old_epc; /* Undo skip-over. */ |
1103 | regs->regs[31] = old31; | ||
1023 | force_sig(status, current); | 1104 | force_sig(status, current); |
1024 | } | 1105 | } |
1025 | 1106 | ||
@@ -1333,7 +1414,7 @@ asmlinkage void cache_parity_error(void) | |||
1333 | void ejtag_exception_handler(struct pt_regs *regs) | 1414 | void ejtag_exception_handler(struct pt_regs *regs) |
1334 | { | 1415 | { |
1335 | const int field = 2 * sizeof(unsigned long); | 1416 | const int field = 2 * sizeof(unsigned long); |
1336 | unsigned long depc, old_epc; | 1417 | unsigned long depc, old_epc, old_ra; |
1337 | unsigned int debug; | 1418 | unsigned int debug; |
1338 | 1419 | ||
1339 | printk(KERN_DEBUG "SDBBP EJTAG debug exception - not handled yet, just ignored!\n"); | 1420 | printk(KERN_DEBUG "SDBBP EJTAG debug exception - not handled yet, just ignored!\n"); |
@@ -1348,10 +1429,12 @@ void ejtag_exception_handler(struct pt_regs *regs) | |||
1348 | * calculation. | 1429 | * calculation. |
1349 | */ | 1430 | */ |
1350 | old_epc = regs->cp0_epc; | 1431 | old_epc = regs->cp0_epc; |
1432 | old_ra = regs->regs[31]; | ||
1351 | regs->cp0_epc = depc; | 1433 | regs->cp0_epc = depc; |
1352 | __compute_return_epc(regs); | 1434 | compute_return_epc(regs); |
1353 | depc = regs->cp0_epc; | 1435 | depc = regs->cp0_epc; |
1354 | regs->cp0_epc = old_epc; | 1436 | regs->cp0_epc = old_epc; |
1437 | regs->regs[31] = old_ra; | ||
1355 | } else | 1438 | } else |
1356 | depc += 4; | 1439 | depc += 4; |
1357 | write_c0_depc(depc); | 1440 | write_c0_depc(depc); |
@@ -1390,10 +1473,27 @@ unsigned long vi_handlers[64]; | |||
1390 | void __init *set_except_vector(int n, void *addr) | 1473 | void __init *set_except_vector(int n, void *addr) |
1391 | { | 1474 | { |
1392 | unsigned long handler = (unsigned long) addr; | 1475 | unsigned long handler = (unsigned long) addr; |
1393 | unsigned long old_handler = xchg(&exception_handlers[n], handler); | 1476 | unsigned long old_handler; |
1477 | |||
1478 | #ifdef CONFIG_CPU_MICROMIPS | ||
1479 | /* | ||
1480 | * Only the TLB handlers are cache aligned with an even | ||
1481 | * address. All other handlers are on an odd address and | ||
1482 | * require no modification. Otherwise, MIPS32 mode will | ||
1483 | * be entered when handling any TLB exceptions. That | ||
1484 | * would be bad...since we must stay in microMIPS mode. | ||
1485 | */ | ||
1486 | if (!(handler & 0x1)) | ||
1487 | handler |= 1; | ||
1488 | #endif | ||
1489 | old_handler = xchg(&exception_handlers[n], handler); | ||
1394 | 1490 | ||
1395 | if (n == 0 && cpu_has_divec) { | 1491 | if (n == 0 && cpu_has_divec) { |
1492 | #ifdef CONFIG_CPU_MICROMIPS | ||
1493 | unsigned long jump_mask = ~((1 << 27) - 1); | ||
1494 | #else | ||
1396 | unsigned long jump_mask = ~((1 << 28) - 1); | 1495 | unsigned long jump_mask = ~((1 << 28) - 1); |
1496 | #endif | ||
1397 | u32 *buf = (u32 *)(ebase + 0x200); | 1497 | u32 *buf = (u32 *)(ebase + 0x200); |
1398 | unsigned int k0 = 26; | 1498 | unsigned int k0 = 26; |
1399 | if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) { | 1499 | if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) { |
@@ -1420,17 +1520,18 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1420 | unsigned long handler; | 1520 | unsigned long handler; |
1421 | unsigned long old_handler = vi_handlers[n]; | 1521 | unsigned long old_handler = vi_handlers[n]; |
1422 | int srssets = current_cpu_data.srsets; | 1522 | int srssets = current_cpu_data.srsets; |
1423 | u32 *w; | 1523 | u16 *h; |
1424 | unsigned char *b; | 1524 | unsigned char *b; |
1425 | 1525 | ||
1426 | BUG_ON(!cpu_has_veic && !cpu_has_vint); | 1526 | BUG_ON(!cpu_has_veic && !cpu_has_vint); |
1527 | BUG_ON((n < 0) && (n > 9)); | ||
1427 | 1528 | ||
1428 | if (addr == NULL) { | 1529 | if (addr == NULL) { |
1429 | handler = (unsigned long) do_default_vi; | 1530 | handler = (unsigned long) do_default_vi; |
1430 | srs = 0; | 1531 | srs = 0; |
1431 | } else | 1532 | } else |
1432 | handler = (unsigned long) addr; | 1533 | handler = (unsigned long) addr; |
1433 | vi_handlers[n] = (unsigned long) addr; | 1534 | vi_handlers[n] = handler; |
1434 | 1535 | ||
1435 | b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING); | 1536 | b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING); |
1436 | 1537 | ||
@@ -1449,9 +1550,8 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1449 | if (srs == 0) { | 1550 | if (srs == 0) { |
1450 | /* | 1551 | /* |
1451 | * If no shadow set is selected then use the default handler | 1552 | * If no shadow set is selected then use the default handler |
1452 | * that does normal register saving and a standard interrupt exit | 1553 | * that does normal register saving and standard interrupt exit |
1453 | */ | 1554 | */ |
1454 | |||
1455 | extern char except_vec_vi, except_vec_vi_lui; | 1555 | extern char except_vec_vi, except_vec_vi_lui; |
1456 | extern char except_vec_vi_ori, except_vec_vi_end; | 1556 | extern char except_vec_vi_ori, except_vec_vi_end; |
1457 | extern char rollback_except_vec_vi; | 1557 | extern char rollback_except_vec_vi; |
@@ -1464,11 +1564,20 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1464 | * Status.IM bit to be masked before going there. | 1564 | * Status.IM bit to be masked before going there. |
1465 | */ | 1565 | */ |
1466 | extern char except_vec_vi_mori; | 1566 | extern char except_vec_vi_mori; |
1567 | #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN) | ||
1568 | const int mori_offset = &except_vec_vi_mori - vec_start + 2; | ||
1569 | #else | ||
1467 | const int mori_offset = &except_vec_vi_mori - vec_start; | 1570 | const int mori_offset = &except_vec_vi_mori - vec_start; |
1571 | #endif | ||
1468 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1572 | #endif /* CONFIG_MIPS_MT_SMTC */ |
1469 | const int handler_len = &except_vec_vi_end - vec_start; | 1573 | #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN) |
1574 | const int lui_offset = &except_vec_vi_lui - vec_start + 2; | ||
1575 | const int ori_offset = &except_vec_vi_ori - vec_start + 2; | ||
1576 | #else | ||
1470 | const int lui_offset = &except_vec_vi_lui - vec_start; | 1577 | const int lui_offset = &except_vec_vi_lui - vec_start; |
1471 | const int ori_offset = &except_vec_vi_ori - vec_start; | 1578 | const int ori_offset = &except_vec_vi_ori - vec_start; |
1579 | #endif | ||
1580 | const int handler_len = &except_vec_vi_end - vec_start; | ||
1472 | 1581 | ||
1473 | if (handler_len > VECTORSPACING) { | 1582 | if (handler_len > VECTORSPACING) { |
1474 | /* | 1583 | /* |
@@ -1478,30 +1587,44 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1478 | panic("VECTORSPACING too small"); | 1587 | panic("VECTORSPACING too small"); |
1479 | } | 1588 | } |
1480 | 1589 | ||
1481 | memcpy(b, vec_start, handler_len); | 1590 | set_handler(((unsigned long)b - ebase), vec_start, |
1591 | #ifdef CONFIG_CPU_MICROMIPS | ||
1592 | (handler_len - 1)); | ||
1593 | #else | ||
1594 | handler_len); | ||
1595 | #endif | ||
1482 | #ifdef CONFIG_MIPS_MT_SMTC | 1596 | #ifdef CONFIG_MIPS_MT_SMTC |
1483 | BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */ | 1597 | BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */ |
1484 | 1598 | ||
1485 | w = (u32 *)(b + mori_offset); | 1599 | h = (u16 *)(b + mori_offset); |
1486 | *w = (*w & 0xffff0000) | (0x100 << n); | 1600 | *h = (0x100 << n); |
1487 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1601 | #endif /* CONFIG_MIPS_MT_SMTC */ |
1488 | w = (u32 *)(b + lui_offset); | 1602 | h = (u16 *)(b + lui_offset); |
1489 | *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff); | 1603 | *h = (handler >> 16) & 0xffff; |
1490 | w = (u32 *)(b + ori_offset); | 1604 | h = (u16 *)(b + ori_offset); |
1491 | *w = (*w & 0xffff0000) | ((u32)handler & 0xffff); | 1605 | *h = (handler & 0xffff); |
1492 | local_flush_icache_range((unsigned long)b, | 1606 | local_flush_icache_range((unsigned long)b, |
1493 | (unsigned long)(b+handler_len)); | 1607 | (unsigned long)(b+handler_len)); |
1494 | } | 1608 | } |
1495 | else { | 1609 | else { |
1496 | /* | 1610 | /* |
1497 | * In other cases jump directly to the interrupt handler | 1611 | * In other cases jump directly to the interrupt handler. It |
1498 | * | 1612 | * is the handler's responsibility to save registers if required |
1499 | * It is the handlers responsibility to save registers if required | 1613 | * (eg hi/lo) and return from the exception using "eret". |
1500 | * (eg hi/lo) and return from the exception using "eret" | ||
1501 | */ | 1614 | */ |
1502 | w = (u32 *)b; | 1615 | u32 insn; |
1503 | *w++ = 0x08000000 | (((u32)handler >> 2) & 0x03fffff); /* j handler */ | 1616 | |
1504 | *w = 0; | 1617 | h = (u16 *)b; |
1618 | /* j handler */ | ||
1619 | #ifdef CONFIG_CPU_MICROMIPS | ||
1620 | insn = 0xd4000000 | (((u32)handler & 0x07ffffff) >> 1); | ||
1621 | #else | ||
1622 | insn = 0x08000000 | (((u32)handler & 0x0fffffff) >> 2); | ||
1623 | #endif | ||
1624 | h[0] = (insn >> 16) & 0xffff; | ||
1625 | h[1] = insn & 0xffff; | ||
1626 | h[2] = 0; | ||
1627 | h[3] = 0; | ||
1505 | local_flush_icache_range((unsigned long)b, | 1628 | local_flush_icache_range((unsigned long)b, |
1506 | (unsigned long)(b+8)); | 1629 | (unsigned long)(b+8)); |
1507 | } | 1630 | } |
@@ -1546,6 +1669,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) | |||
1546 | unsigned int cpu = smp_processor_id(); | 1669 | unsigned int cpu = smp_processor_id(); |
1547 | unsigned int status_set = ST0_CU0; | 1670 | unsigned int status_set = ST0_CU0; |
1548 | unsigned int hwrena = cpu_hwrena_impl_bits; | 1671 | unsigned int hwrena = cpu_hwrena_impl_bits; |
1672 | unsigned long asid = 0; | ||
1549 | #ifdef CONFIG_MIPS_MT_SMTC | 1673 | #ifdef CONFIG_MIPS_MT_SMTC |
1550 | int secondaryTC = 0; | 1674 | int secondaryTC = 0; |
1551 | int bootTC = (cpu == 0); | 1675 | int bootTC = (cpu == 0); |
@@ -1629,8 +1753,9 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) | |||
1629 | } | 1753 | } |
1630 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1754 | #endif /* CONFIG_MIPS_MT_SMTC */ |
1631 | 1755 | ||
1632 | if (!cpu_data[cpu].asid_cache) | 1756 | asid = ASID_FIRST_VERSION; |
1633 | cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; | 1757 | cpu_data[cpu].asid_cache = asid; |
1758 | TLBMISS_HANDLER_SETUP(); | ||
1634 | 1759 | ||
1635 | atomic_inc(&init_mm.mm_count); | 1760 | atomic_inc(&init_mm.mm_count); |
1636 | current->active_mm = &init_mm; | 1761 | current->active_mm = &init_mm; |
@@ -1660,7 +1785,11 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) | |||
1660 | /* Install CPU exception handler */ | 1785 | /* Install CPU exception handler */ |
1661 | void __cpuinit set_handler(unsigned long offset, void *addr, unsigned long size) | 1786 | void __cpuinit set_handler(unsigned long offset, void *addr, unsigned long size) |
1662 | { | 1787 | { |
1788 | #ifdef CONFIG_CPU_MICROMIPS | ||
1789 | memcpy((void *)(ebase + offset), ((unsigned char *)addr - 1), size); | ||
1790 | #else | ||
1663 | memcpy((void *)(ebase + offset), addr, size); | 1791 | memcpy((void *)(ebase + offset), addr, size); |
1792 | #endif | ||
1664 | local_flush_icache_range(ebase + offset, ebase + offset + size); | 1793 | local_flush_icache_range(ebase + offset, ebase + offset + size); |
1665 | } | 1794 | } |
1666 | 1795 | ||
@@ -1694,8 +1823,9 @@ __setup("rdhwr_noopt", set_rdhwr_noopt); | |||
1694 | 1823 | ||
1695 | void __init trap_init(void) | 1824 | void __init trap_init(void) |
1696 | { | 1825 | { |
1697 | extern char except_vec3_generic, except_vec3_r4000; | 1826 | extern char except_vec3_generic; |
1698 | extern char except_vec4; | 1827 | extern char except_vec4; |
1828 | extern char except_vec3_r4000; | ||
1699 | unsigned long i; | 1829 | unsigned long i; |
1700 | int rollback; | 1830 | int rollback; |
1701 | 1831 | ||
@@ -1833,11 +1963,11 @@ void __init trap_init(void) | |||
1833 | 1963 | ||
1834 | if (cpu_has_vce) | 1964 | if (cpu_has_vce) |
1835 | /* Special exception: R4[04]00 uses also the divec space. */ | 1965 | /* Special exception: R4[04]00 uses also the divec space. */ |
1836 | memcpy((void *)(ebase + 0x180), &except_vec3_r4000, 0x100); | 1966 | set_handler(0x180, &except_vec3_r4000, 0x100); |
1837 | else if (cpu_has_4kex) | 1967 | else if (cpu_has_4kex) |
1838 | memcpy((void *)(ebase + 0x180), &except_vec3_generic, 0x80); | 1968 | set_handler(0x180, &except_vec3_generic, 0x80); |
1839 | else | 1969 | else |
1840 | memcpy((void *)(ebase + 0x080), &except_vec3_generic, 0x80); | 1970 | set_handler(0x080, &except_vec3_generic, 0x80); |
1841 | 1971 | ||
1842 | local_flush_icache_range(ebase, ebase + 0x400); | 1972 | local_flush_icache_range(ebase, ebase + 0x400); |
1843 | flush_tlb_handlers(); | 1973 | flush_tlb_handlers(); |
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 6087a54c86a0..203d8857070d 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c | |||
@@ -83,8 +83,12 @@ | |||
83 | #include <asm/branch.h> | 83 | #include <asm/branch.h> |
84 | #include <asm/byteorder.h> | 84 | #include <asm/byteorder.h> |
85 | #include <asm/cop2.h> | 85 | #include <asm/cop2.h> |
86 | #include <asm/fpu.h> | ||
87 | #include <asm/fpu_emulator.h> | ||
86 | #include <asm/inst.h> | 88 | #include <asm/inst.h> |
87 | #include <asm/uaccess.h> | 89 | #include <asm/uaccess.h> |
90 | #include <asm/fpu.h> | ||
91 | #include <asm/fpu_emulator.h> | ||
88 | 92 | ||
89 | #define STR(x) __STR(x) | 93 | #define STR(x) __STR(x) |
90 | #define __STR(x) #x | 94 | #define __STR(x) #x |
@@ -102,12 +106,332 @@ static u32 unaligned_action; | |||
102 | #endif | 106 | #endif |
103 | extern void show_registers(struct pt_regs *regs); | 107 | extern void show_registers(struct pt_regs *regs); |
104 | 108 | ||
109 | #ifdef __BIG_ENDIAN | ||
110 | #define LoadHW(addr, value, res) \ | ||
111 | __asm__ __volatile__ (".set\tnoat\n" \ | ||
112 | "1:\tlb\t%0, 0(%2)\n" \ | ||
113 | "2:\tlbu\t$1, 1(%2)\n\t" \ | ||
114 | "sll\t%0, 0x8\n\t" \ | ||
115 | "or\t%0, $1\n\t" \ | ||
116 | "li\t%1, 0\n" \ | ||
117 | "3:\t.set\tat\n\t" \ | ||
118 | ".insn\n\t" \ | ||
119 | ".section\t.fixup,\"ax\"\n\t" \ | ||
120 | "4:\tli\t%1, %3\n\t" \ | ||
121 | "j\t3b\n\t" \ | ||
122 | ".previous\n\t" \ | ||
123 | ".section\t__ex_table,\"a\"\n\t" \ | ||
124 | STR(PTR)"\t1b, 4b\n\t" \ | ||
125 | STR(PTR)"\t2b, 4b\n\t" \ | ||
126 | ".previous" \ | ||
127 | : "=&r" (value), "=r" (res) \ | ||
128 | : "r" (addr), "i" (-EFAULT)); | ||
129 | |||
130 | #define LoadW(addr, value, res) \ | ||
131 | __asm__ __volatile__ ( \ | ||
132 | "1:\tlwl\t%0, (%2)\n" \ | ||
133 | "2:\tlwr\t%0, 3(%2)\n\t" \ | ||
134 | "li\t%1, 0\n" \ | ||
135 | "3:\n\t" \ | ||
136 | ".insn\n\t" \ | ||
137 | ".section\t.fixup,\"ax\"\n\t" \ | ||
138 | "4:\tli\t%1, %3\n\t" \ | ||
139 | "j\t3b\n\t" \ | ||
140 | ".previous\n\t" \ | ||
141 | ".section\t__ex_table,\"a\"\n\t" \ | ||
142 | STR(PTR)"\t1b, 4b\n\t" \ | ||
143 | STR(PTR)"\t2b, 4b\n\t" \ | ||
144 | ".previous" \ | ||
145 | : "=&r" (value), "=r" (res) \ | ||
146 | : "r" (addr), "i" (-EFAULT)); | ||
147 | |||
148 | #define LoadHWU(addr, value, res) \ | ||
149 | __asm__ __volatile__ ( \ | ||
150 | ".set\tnoat\n" \ | ||
151 | "1:\tlbu\t%0, 0(%2)\n" \ | ||
152 | "2:\tlbu\t$1, 1(%2)\n\t" \ | ||
153 | "sll\t%0, 0x8\n\t" \ | ||
154 | "or\t%0, $1\n\t" \ | ||
155 | "li\t%1, 0\n" \ | ||
156 | "3:\n\t" \ | ||
157 | ".insn\n\t" \ | ||
158 | ".set\tat\n\t" \ | ||
159 | ".section\t.fixup,\"ax\"\n\t" \ | ||
160 | "4:\tli\t%1, %3\n\t" \ | ||
161 | "j\t3b\n\t" \ | ||
162 | ".previous\n\t" \ | ||
163 | ".section\t__ex_table,\"a\"\n\t" \ | ||
164 | STR(PTR)"\t1b, 4b\n\t" \ | ||
165 | STR(PTR)"\t2b, 4b\n\t" \ | ||
166 | ".previous" \ | ||
167 | : "=&r" (value), "=r" (res) \ | ||
168 | : "r" (addr), "i" (-EFAULT)); | ||
169 | |||
170 | #define LoadWU(addr, value, res) \ | ||
171 | __asm__ __volatile__ ( \ | ||
172 | "1:\tlwl\t%0, (%2)\n" \ | ||
173 | "2:\tlwr\t%0, 3(%2)\n\t" \ | ||
174 | "dsll\t%0, %0, 32\n\t" \ | ||
175 | "dsrl\t%0, %0, 32\n\t" \ | ||
176 | "li\t%1, 0\n" \ | ||
177 | "3:\n\t" \ | ||
178 | ".insn\n\t" \ | ||
179 | "\t.section\t.fixup,\"ax\"\n\t" \ | ||
180 | "4:\tli\t%1, %3\n\t" \ | ||
181 | "j\t3b\n\t" \ | ||
182 | ".previous\n\t" \ | ||
183 | ".section\t__ex_table,\"a\"\n\t" \ | ||
184 | STR(PTR)"\t1b, 4b\n\t" \ | ||
185 | STR(PTR)"\t2b, 4b\n\t" \ | ||
186 | ".previous" \ | ||
187 | : "=&r" (value), "=r" (res) \ | ||
188 | : "r" (addr), "i" (-EFAULT)); | ||
189 | |||
190 | #define LoadDW(addr, value, res) \ | ||
191 | __asm__ __volatile__ ( \ | ||
192 | "1:\tldl\t%0, (%2)\n" \ | ||
193 | "2:\tldr\t%0, 7(%2)\n\t" \ | ||
194 | "li\t%1, 0\n" \ | ||
195 | "3:\n\t" \ | ||
196 | ".insn\n\t" \ | ||
197 | "\t.section\t.fixup,\"ax\"\n\t" \ | ||
198 | "4:\tli\t%1, %3\n\t" \ | ||
199 | "j\t3b\n\t" \ | ||
200 | ".previous\n\t" \ | ||
201 | ".section\t__ex_table,\"a\"\n\t" \ | ||
202 | STR(PTR)"\t1b, 4b\n\t" \ | ||
203 | STR(PTR)"\t2b, 4b\n\t" \ | ||
204 | ".previous" \ | ||
205 | : "=&r" (value), "=r" (res) \ | ||
206 | : "r" (addr), "i" (-EFAULT)); | ||
207 | |||
208 | #define StoreHW(addr, value, res) \ | ||
209 | __asm__ __volatile__ ( \ | ||
210 | ".set\tnoat\n" \ | ||
211 | "1:\tsb\t%1, 1(%2)\n\t" \ | ||
212 | "srl\t$1, %1, 0x8\n" \ | ||
213 | "2:\tsb\t$1, 0(%2)\n\t" \ | ||
214 | ".set\tat\n\t" \ | ||
215 | "li\t%0, 0\n" \ | ||
216 | "3:\n\t" \ | ||
217 | ".insn\n\t" \ | ||
218 | ".section\t.fixup,\"ax\"\n\t" \ | ||
219 | "4:\tli\t%0, %3\n\t" \ | ||
220 | "j\t3b\n\t" \ | ||
221 | ".previous\n\t" \ | ||
222 | ".section\t__ex_table,\"a\"\n\t" \ | ||
223 | STR(PTR)"\t1b, 4b\n\t" \ | ||
224 | STR(PTR)"\t2b, 4b\n\t" \ | ||
225 | ".previous" \ | ||
226 | : "=r" (res) \ | ||
227 | : "r" (value), "r" (addr), "i" (-EFAULT)); | ||
228 | |||
229 | #define StoreW(addr, value, res) \ | ||
230 | __asm__ __volatile__ ( \ | ||
231 | "1:\tswl\t%1,(%2)\n" \ | ||
232 | "2:\tswr\t%1, 3(%2)\n\t" \ | ||
233 | "li\t%0, 0\n" \ | ||
234 | "3:\n\t" \ | ||
235 | ".insn\n\t" \ | ||
236 | ".section\t.fixup,\"ax\"\n\t" \ | ||
237 | "4:\tli\t%0, %3\n\t" \ | ||
238 | "j\t3b\n\t" \ | ||
239 | ".previous\n\t" \ | ||
240 | ".section\t__ex_table,\"a\"\n\t" \ | ||
241 | STR(PTR)"\t1b, 4b\n\t" \ | ||
242 | STR(PTR)"\t2b, 4b\n\t" \ | ||
243 | ".previous" \ | ||
244 | : "=r" (res) \ | ||
245 | : "r" (value), "r" (addr), "i" (-EFAULT)); | ||
246 | |||
247 | #define StoreDW(addr, value, res) \ | ||
248 | __asm__ __volatile__ ( \ | ||
249 | "1:\tsdl\t%1,(%2)\n" \ | ||
250 | "2:\tsdr\t%1, 7(%2)\n\t" \ | ||
251 | "li\t%0, 0\n" \ | ||
252 | "3:\n\t" \ | ||
253 | ".insn\n\t" \ | ||
254 | ".section\t.fixup,\"ax\"\n\t" \ | ||
255 | "4:\tli\t%0, %3\n\t" \ | ||
256 | "j\t3b\n\t" \ | ||
257 | ".previous\n\t" \ | ||
258 | ".section\t__ex_table,\"a\"\n\t" \ | ||
259 | STR(PTR)"\t1b, 4b\n\t" \ | ||
260 | STR(PTR)"\t2b, 4b\n\t" \ | ||
261 | ".previous" \ | ||
262 | : "=r" (res) \ | ||
263 | : "r" (value), "r" (addr), "i" (-EFAULT)); | ||
264 | #endif | ||
265 | |||
266 | #ifdef __LITTLE_ENDIAN | ||
267 | #define LoadHW(addr, value, res) \ | ||
268 | __asm__ __volatile__ (".set\tnoat\n" \ | ||
269 | "1:\tlb\t%0, 1(%2)\n" \ | ||
270 | "2:\tlbu\t$1, 0(%2)\n\t" \ | ||
271 | "sll\t%0, 0x8\n\t" \ | ||
272 | "or\t%0, $1\n\t" \ | ||
273 | "li\t%1, 0\n" \ | ||
274 | "3:\t.set\tat\n\t" \ | ||
275 | ".insn\n\t" \ | ||
276 | ".section\t.fixup,\"ax\"\n\t" \ | ||
277 | "4:\tli\t%1, %3\n\t" \ | ||
278 | "j\t3b\n\t" \ | ||
279 | ".previous\n\t" \ | ||
280 | ".section\t__ex_table,\"a\"\n\t" \ | ||
281 | STR(PTR)"\t1b, 4b\n\t" \ | ||
282 | STR(PTR)"\t2b, 4b\n\t" \ | ||
283 | ".previous" \ | ||
284 | : "=&r" (value), "=r" (res) \ | ||
285 | : "r" (addr), "i" (-EFAULT)); | ||
286 | |||
287 | #define LoadW(addr, value, res) \ | ||
288 | __asm__ __volatile__ ( \ | ||
289 | "1:\tlwl\t%0, 3(%2)\n" \ | ||
290 | "2:\tlwr\t%0, (%2)\n\t" \ | ||
291 | "li\t%1, 0\n" \ | ||
292 | "3:\n\t" \ | ||
293 | ".insn\n\t" \ | ||
294 | ".section\t.fixup,\"ax\"\n\t" \ | ||
295 | "4:\tli\t%1, %3\n\t" \ | ||
296 | "j\t3b\n\t" \ | ||
297 | ".previous\n\t" \ | ||
298 | ".section\t__ex_table,\"a\"\n\t" \ | ||
299 | STR(PTR)"\t1b, 4b\n\t" \ | ||
300 | STR(PTR)"\t2b, 4b\n\t" \ | ||
301 | ".previous" \ | ||
302 | : "=&r" (value), "=r" (res) \ | ||
303 | : "r" (addr), "i" (-EFAULT)); | ||
304 | |||
305 | #define LoadHWU(addr, value, res) \ | ||
306 | __asm__ __volatile__ ( \ | ||
307 | ".set\tnoat\n" \ | ||
308 | "1:\tlbu\t%0, 1(%2)\n" \ | ||
309 | "2:\tlbu\t$1, 0(%2)\n\t" \ | ||
310 | "sll\t%0, 0x8\n\t" \ | ||
311 | "or\t%0, $1\n\t" \ | ||
312 | "li\t%1, 0\n" \ | ||
313 | "3:\n\t" \ | ||
314 | ".insn\n\t" \ | ||
315 | ".set\tat\n\t" \ | ||
316 | ".section\t.fixup,\"ax\"\n\t" \ | ||
317 | "4:\tli\t%1, %3\n\t" \ | ||
318 | "j\t3b\n\t" \ | ||
319 | ".previous\n\t" \ | ||
320 | ".section\t__ex_table,\"a\"\n\t" \ | ||
321 | STR(PTR)"\t1b, 4b\n\t" \ | ||
322 | STR(PTR)"\t2b, 4b\n\t" \ | ||
323 | ".previous" \ | ||
324 | : "=&r" (value), "=r" (res) \ | ||
325 | : "r" (addr), "i" (-EFAULT)); | ||
326 | |||
327 | #define LoadWU(addr, value, res) \ | ||
328 | __asm__ __volatile__ ( \ | ||
329 | "1:\tlwl\t%0, 3(%2)\n" \ | ||
330 | "2:\tlwr\t%0, (%2)\n\t" \ | ||
331 | "dsll\t%0, %0, 32\n\t" \ | ||
332 | "dsrl\t%0, %0, 32\n\t" \ | ||
333 | "li\t%1, 0\n" \ | ||
334 | "3:\n\t" \ | ||
335 | ".insn\n\t" \ | ||
336 | "\t.section\t.fixup,\"ax\"\n\t" \ | ||
337 | "4:\tli\t%1, %3\n\t" \ | ||
338 | "j\t3b\n\t" \ | ||
339 | ".previous\n\t" \ | ||
340 | ".section\t__ex_table,\"a\"\n\t" \ | ||
341 | STR(PTR)"\t1b, 4b\n\t" \ | ||
342 | STR(PTR)"\t2b, 4b\n\t" \ | ||
343 | ".previous" \ | ||
344 | : "=&r" (value), "=r" (res) \ | ||
345 | : "r" (addr), "i" (-EFAULT)); | ||
346 | |||
347 | #define LoadDW(addr, value, res) \ | ||
348 | __asm__ __volatile__ ( \ | ||
349 | "1:\tldl\t%0, 7(%2)\n" \ | ||
350 | "2:\tldr\t%0, (%2)\n\t" \ | ||
351 | "li\t%1, 0\n" \ | ||
352 | "3:\n\t" \ | ||
353 | ".insn\n\t" \ | ||
354 | "\t.section\t.fixup,\"ax\"\n\t" \ | ||
355 | "4:\tli\t%1, %3\n\t" \ | ||
356 | "j\t3b\n\t" \ | ||
357 | ".previous\n\t" \ | ||
358 | ".section\t__ex_table,\"a\"\n\t" \ | ||
359 | STR(PTR)"\t1b, 4b\n\t" \ | ||
360 | STR(PTR)"\t2b, 4b\n\t" \ | ||
361 | ".previous" \ | ||
362 | : "=&r" (value), "=r" (res) \ | ||
363 | : "r" (addr), "i" (-EFAULT)); | ||
364 | |||
365 | #define StoreHW(addr, value, res) \ | ||
366 | __asm__ __volatile__ ( \ | ||
367 | ".set\tnoat\n" \ | ||
368 | "1:\tsb\t%1, 0(%2)\n\t" \ | ||
369 | "srl\t$1,%1, 0x8\n" \ | ||
370 | "2:\tsb\t$1, 1(%2)\n\t" \ | ||
371 | ".set\tat\n\t" \ | ||
372 | "li\t%0, 0\n" \ | ||
373 | "3:\n\t" \ | ||
374 | ".insn\n\t" \ | ||
375 | ".section\t.fixup,\"ax\"\n\t" \ | ||
376 | "4:\tli\t%0, %3\n\t" \ | ||
377 | "j\t3b\n\t" \ | ||
378 | ".previous\n\t" \ | ||
379 | ".section\t__ex_table,\"a\"\n\t" \ | ||
380 | STR(PTR)"\t1b, 4b\n\t" \ | ||
381 | STR(PTR)"\t2b, 4b\n\t" \ | ||
382 | ".previous" \ | ||
383 | : "=r" (res) \ | ||
384 | : "r" (value), "r" (addr), "i" (-EFAULT)); | ||
385 | |||
386 | #define StoreW(addr, value, res) \ | ||
387 | __asm__ __volatile__ ( \ | ||
388 | "1:\tswl\t%1, 3(%2)\n" \ | ||
389 | "2:\tswr\t%1, (%2)\n\t" \ | ||
390 | "li\t%0, 0\n" \ | ||
391 | "3:\n\t" \ | ||
392 | ".insn\n\t" \ | ||
393 | ".section\t.fixup,\"ax\"\n\t" \ | ||
394 | "4:\tli\t%0, %3\n\t" \ | ||
395 | "j\t3b\n\t" \ | ||
396 | ".previous\n\t" \ | ||
397 | ".section\t__ex_table,\"a\"\n\t" \ | ||
398 | STR(PTR)"\t1b, 4b\n\t" \ | ||
399 | STR(PTR)"\t2b, 4b\n\t" \ | ||
400 | ".previous" \ | ||
401 | : "=r" (res) \ | ||
402 | : "r" (value), "r" (addr), "i" (-EFAULT)); | ||
403 | |||
404 | #define StoreDW(addr, value, res) \ | ||
405 | __asm__ __volatile__ ( \ | ||
406 | "1:\tsdl\t%1, 7(%2)\n" \ | ||
407 | "2:\tsdr\t%1, (%2)\n\t" \ | ||
408 | "li\t%0, 0\n" \ | ||
409 | "3:\n\t" \ | ||
410 | ".insn\n\t" \ | ||
411 | ".section\t.fixup,\"ax\"\n\t" \ | ||
412 | "4:\tli\t%0, %3\n\t" \ | ||
413 | "j\t3b\n\t" \ | ||
414 | ".previous\n\t" \ | ||
415 | ".section\t__ex_table,\"a\"\n\t" \ | ||
416 | STR(PTR)"\t1b, 4b\n\t" \ | ||
417 | STR(PTR)"\t2b, 4b\n\t" \ | ||
418 | ".previous" \ | ||
419 | : "=r" (res) \ | ||
420 | : "r" (value), "r" (addr), "i" (-EFAULT)); | ||
421 | #endif | ||
422 | |||
105 | static void emulate_load_store_insn(struct pt_regs *regs, | 423 | static void emulate_load_store_insn(struct pt_regs *regs, |
106 | void __user *addr, unsigned int __user *pc) | 424 | void __user *addr, unsigned int __user *pc) |
107 | { | 425 | { |
108 | union mips_instruction insn; | 426 | union mips_instruction insn; |
109 | unsigned long value; | 427 | unsigned long value; |
110 | unsigned int res; | 428 | unsigned int res; |
429 | unsigned long origpc; | ||
430 | unsigned long orig31; | ||
431 | void __user *fault_addr = NULL; | ||
432 | |||
433 | origpc = (unsigned long)pc; | ||
434 | orig31 = regs->regs[31]; | ||
111 | 435 | ||
112 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); | 436 | perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); |
113 | 437 | ||
@@ -117,22 +441,22 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
117 | __get_user(insn.word, pc); | 441 | __get_user(insn.word, pc); |
118 | 442 | ||
119 | switch (insn.i_format.opcode) { | 443 | switch (insn.i_format.opcode) { |
120 | /* | 444 | /* |
121 | * These are instructions that a compiler doesn't generate. We | 445 | * These are instructions that a compiler doesn't generate. We |
122 | * can assume therefore that the code is MIPS-aware and | 446 | * can assume therefore that the code is MIPS-aware and |
123 | * really buggy. Emulating these instructions would break the | 447 | * really buggy. Emulating these instructions would break the |
124 | * semantics anyway. | 448 | * semantics anyway. |
125 | */ | 449 | */ |
126 | case ll_op: | 450 | case ll_op: |
127 | case lld_op: | 451 | case lld_op: |
128 | case sc_op: | 452 | case sc_op: |
129 | case scd_op: | 453 | case scd_op: |
130 | 454 | ||
131 | /* | 455 | /* |
132 | * For these instructions the only way to create an address | 456 | * For these instructions the only way to create an address |
133 | * error is an attempted access to kernel/supervisor address | 457 | * error is an attempted access to kernel/supervisor address |
134 | * space. | 458 | * space. |
135 | */ | 459 | */ |
136 | case ldl_op: | 460 | case ldl_op: |
137 | case ldr_op: | 461 | case ldr_op: |
138 | case lwl_op: | 462 | case lwl_op: |
@@ -146,36 +470,15 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
146 | case sb_op: | 470 | case sb_op: |
147 | goto sigbus; | 471 | goto sigbus; |
148 | 472 | ||
149 | /* | 473 | /* |
150 | * The remaining opcodes are the ones that are really of interest. | 474 | * The remaining opcodes are the ones that are really of |
151 | */ | 475 | * interest. |
476 | */ | ||
152 | case lh_op: | 477 | case lh_op: |
153 | if (!access_ok(VERIFY_READ, addr, 2)) | 478 | if (!access_ok(VERIFY_READ, addr, 2)) |
154 | goto sigbus; | 479 | goto sigbus; |
155 | 480 | ||
156 | __asm__ __volatile__ (".set\tnoat\n" | 481 | LoadHW(addr, value, res); |
157 | #ifdef __BIG_ENDIAN | ||
158 | "1:\tlb\t%0, 0(%2)\n" | ||
159 | "2:\tlbu\t$1, 1(%2)\n\t" | ||
160 | #endif | ||
161 | #ifdef __LITTLE_ENDIAN | ||
162 | "1:\tlb\t%0, 1(%2)\n" | ||
163 | "2:\tlbu\t$1, 0(%2)\n\t" | ||
164 | #endif | ||
165 | "sll\t%0, 0x8\n\t" | ||
166 | "or\t%0, $1\n\t" | ||
167 | "li\t%1, 0\n" | ||
168 | "3:\t.set\tat\n\t" | ||
169 | ".section\t.fixup,\"ax\"\n\t" | ||
170 | "4:\tli\t%1, %3\n\t" | ||
171 | "j\t3b\n\t" | ||
172 | ".previous\n\t" | ||
173 | ".section\t__ex_table,\"a\"\n\t" | ||
174 | STR(PTR)"\t1b, 4b\n\t" | ||
175 | STR(PTR)"\t2b, 4b\n\t" | ||
176 | ".previous" | ||
177 | : "=&r" (value), "=r" (res) | ||
178 | : "r" (addr), "i" (-EFAULT)); | ||
179 | if (res) | 482 | if (res) |
180 | goto fault; | 483 | goto fault; |
181 | compute_return_epc(regs); | 484 | compute_return_epc(regs); |
@@ -186,26 +489,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
186 | if (!access_ok(VERIFY_READ, addr, 4)) | 489 | if (!access_ok(VERIFY_READ, addr, 4)) |
187 | goto sigbus; | 490 | goto sigbus; |
188 | 491 | ||
189 | __asm__ __volatile__ ( | 492 | LoadW(addr, value, res); |
190 | #ifdef __BIG_ENDIAN | ||
191 | "1:\tlwl\t%0, (%2)\n" | ||
192 | "2:\tlwr\t%0, 3(%2)\n\t" | ||
193 | #endif | ||
194 | #ifdef __LITTLE_ENDIAN | ||
195 | "1:\tlwl\t%0, 3(%2)\n" | ||
196 | "2:\tlwr\t%0, (%2)\n\t" | ||
197 | #endif | ||
198 | "li\t%1, 0\n" | ||
199 | "3:\t.section\t.fixup,\"ax\"\n\t" | ||
200 | "4:\tli\t%1, %3\n\t" | ||
201 | "j\t3b\n\t" | ||
202 | ".previous\n\t" | ||
203 | ".section\t__ex_table,\"a\"\n\t" | ||
204 | STR(PTR)"\t1b, 4b\n\t" | ||
205 | STR(PTR)"\t2b, 4b\n\t" | ||
206 | ".previous" | ||
207 | : "=&r" (value), "=r" (res) | ||
208 | : "r" (addr), "i" (-EFAULT)); | ||
209 | if (res) | 493 | if (res) |
210 | goto fault; | 494 | goto fault; |
211 | compute_return_epc(regs); | 495 | compute_return_epc(regs); |
@@ -216,30 +500,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
216 | if (!access_ok(VERIFY_READ, addr, 2)) | 500 | if (!access_ok(VERIFY_READ, addr, 2)) |
217 | goto sigbus; | 501 | goto sigbus; |
218 | 502 | ||
219 | __asm__ __volatile__ ( | 503 | LoadHWU(addr, value, res); |
220 | ".set\tnoat\n" | ||
221 | #ifdef __BIG_ENDIAN | ||
222 | "1:\tlbu\t%0, 0(%2)\n" | ||
223 | "2:\tlbu\t$1, 1(%2)\n\t" | ||
224 | #endif | ||
225 | #ifdef __LITTLE_ENDIAN | ||
226 | "1:\tlbu\t%0, 1(%2)\n" | ||
227 | "2:\tlbu\t$1, 0(%2)\n\t" | ||
228 | #endif | ||
229 | "sll\t%0, 0x8\n\t" | ||
230 | "or\t%0, $1\n\t" | ||
231 | "li\t%1, 0\n" | ||
232 | "3:\t.set\tat\n\t" | ||
233 | ".section\t.fixup,\"ax\"\n\t" | ||
234 | "4:\tli\t%1, %3\n\t" | ||
235 | "j\t3b\n\t" | ||
236 | ".previous\n\t" | ||
237 | ".section\t__ex_table,\"a\"\n\t" | ||
238 | STR(PTR)"\t1b, 4b\n\t" | ||
239 | STR(PTR)"\t2b, 4b\n\t" | ||
240 | ".previous" | ||
241 | : "=&r" (value), "=r" (res) | ||
242 | : "r" (addr), "i" (-EFAULT)); | ||
243 | if (res) | 504 | if (res) |
244 | goto fault; | 505 | goto fault; |
245 | compute_return_epc(regs); | 506 | compute_return_epc(regs); |
@@ -258,28 +519,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
258 | if (!access_ok(VERIFY_READ, addr, 4)) | 519 | if (!access_ok(VERIFY_READ, addr, 4)) |
259 | goto sigbus; | 520 | goto sigbus; |
260 | 521 | ||
261 | __asm__ __volatile__ ( | 522 | LoadWU(addr, value, res); |
262 | #ifdef __BIG_ENDIAN | ||
263 | "1:\tlwl\t%0, (%2)\n" | ||
264 | "2:\tlwr\t%0, 3(%2)\n\t" | ||
265 | #endif | ||
266 | #ifdef __LITTLE_ENDIAN | ||
267 | "1:\tlwl\t%0, 3(%2)\n" | ||
268 | "2:\tlwr\t%0, (%2)\n\t" | ||
269 | #endif | ||
270 | "dsll\t%0, %0, 32\n\t" | ||
271 | "dsrl\t%0, %0, 32\n\t" | ||
272 | "li\t%1, 0\n" | ||
273 | "3:\t.section\t.fixup,\"ax\"\n\t" | ||
274 | "4:\tli\t%1, %3\n\t" | ||
275 | "j\t3b\n\t" | ||
276 | ".previous\n\t" | ||
277 | ".section\t__ex_table,\"a\"\n\t" | ||
278 | STR(PTR)"\t1b, 4b\n\t" | ||
279 | STR(PTR)"\t2b, 4b\n\t" | ||
280 | ".previous" | ||
281 | : "=&r" (value), "=r" (res) | ||
282 | : "r" (addr), "i" (-EFAULT)); | ||
283 | if (res) | 523 | if (res) |
284 | goto fault; | 524 | goto fault; |
285 | compute_return_epc(regs); | 525 | compute_return_epc(regs); |
@@ -302,26 +542,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
302 | if (!access_ok(VERIFY_READ, addr, 8)) | 542 | if (!access_ok(VERIFY_READ, addr, 8)) |
303 | goto sigbus; | 543 | goto sigbus; |
304 | 544 | ||
305 | __asm__ __volatile__ ( | 545 | LoadDW(addr, value, res); |
306 | #ifdef __BIG_ENDIAN | ||
307 | "1:\tldl\t%0, (%2)\n" | ||
308 | "2:\tldr\t%0, 7(%2)\n\t" | ||
309 | #endif | ||
310 | #ifdef __LITTLE_ENDIAN | ||
311 | "1:\tldl\t%0, 7(%2)\n" | ||
312 | "2:\tldr\t%0, (%2)\n\t" | ||
313 | #endif | ||
314 | "li\t%1, 0\n" | ||
315 | "3:\t.section\t.fixup,\"ax\"\n\t" | ||
316 | "4:\tli\t%1, %3\n\t" | ||
317 | "j\t3b\n\t" | ||
318 | ".previous\n\t" | ||
319 | ".section\t__ex_table,\"a\"\n\t" | ||
320 | STR(PTR)"\t1b, 4b\n\t" | ||
321 | STR(PTR)"\t2b, 4b\n\t" | ||
322 | ".previous" | ||
323 | : "=&r" (value), "=r" (res) | ||
324 | : "r" (addr), "i" (-EFAULT)); | ||
325 | if (res) | 546 | if (res) |
326 | goto fault; | 547 | goto fault; |
327 | compute_return_epc(regs); | 548 | compute_return_epc(regs); |
@@ -336,68 +557,22 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
336 | if (!access_ok(VERIFY_WRITE, addr, 2)) | 557 | if (!access_ok(VERIFY_WRITE, addr, 2)) |
337 | goto sigbus; | 558 | goto sigbus; |
338 | 559 | ||
560 | compute_return_epc(regs); | ||
339 | value = regs->regs[insn.i_format.rt]; | 561 | value = regs->regs[insn.i_format.rt]; |
340 | __asm__ __volatile__ ( | 562 | StoreHW(addr, value, res); |
341 | #ifdef __BIG_ENDIAN | ||
342 | ".set\tnoat\n" | ||
343 | "1:\tsb\t%1, 1(%2)\n\t" | ||
344 | "srl\t$1, %1, 0x8\n" | ||
345 | "2:\tsb\t$1, 0(%2)\n\t" | ||
346 | ".set\tat\n\t" | ||
347 | #endif | ||
348 | #ifdef __LITTLE_ENDIAN | ||
349 | ".set\tnoat\n" | ||
350 | "1:\tsb\t%1, 0(%2)\n\t" | ||
351 | "srl\t$1,%1, 0x8\n" | ||
352 | "2:\tsb\t$1, 1(%2)\n\t" | ||
353 | ".set\tat\n\t" | ||
354 | #endif | ||
355 | "li\t%0, 0\n" | ||
356 | "3:\n\t" | ||
357 | ".section\t.fixup,\"ax\"\n\t" | ||
358 | "4:\tli\t%0, %3\n\t" | ||
359 | "j\t3b\n\t" | ||
360 | ".previous\n\t" | ||
361 | ".section\t__ex_table,\"a\"\n\t" | ||
362 | STR(PTR)"\t1b, 4b\n\t" | ||
363 | STR(PTR)"\t2b, 4b\n\t" | ||
364 | ".previous" | ||
365 | : "=r" (res) | ||
366 | : "r" (value), "r" (addr), "i" (-EFAULT)); | ||
367 | if (res) | 563 | if (res) |
368 | goto fault; | 564 | goto fault; |
369 | compute_return_epc(regs); | ||
370 | break; | 565 | break; |
371 | 566 | ||
372 | case sw_op: | 567 | case sw_op: |
373 | if (!access_ok(VERIFY_WRITE, addr, 4)) | 568 | if (!access_ok(VERIFY_WRITE, addr, 4)) |
374 | goto sigbus; | 569 | goto sigbus; |
375 | 570 | ||
571 | compute_return_epc(regs); | ||
376 | value = regs->regs[insn.i_format.rt]; | 572 | value = regs->regs[insn.i_format.rt]; |
377 | __asm__ __volatile__ ( | 573 | StoreW(addr, value, res); |
378 | #ifdef __BIG_ENDIAN | ||
379 | "1:\tswl\t%1,(%2)\n" | ||
380 | "2:\tswr\t%1, 3(%2)\n\t" | ||
381 | #endif | ||
382 | #ifdef __LITTLE_ENDIAN | ||
383 | "1:\tswl\t%1, 3(%2)\n" | ||
384 | "2:\tswr\t%1, (%2)\n\t" | ||
385 | #endif | ||
386 | "li\t%0, 0\n" | ||
387 | "3:\n\t" | ||
388 | ".section\t.fixup,\"ax\"\n\t" | ||
389 | "4:\tli\t%0, %3\n\t" | ||
390 | "j\t3b\n\t" | ||
391 | ".previous\n\t" | ||
392 | ".section\t__ex_table,\"a\"\n\t" | ||
393 | STR(PTR)"\t1b, 4b\n\t" | ||
394 | STR(PTR)"\t2b, 4b\n\t" | ||
395 | ".previous" | ||
396 | : "=r" (res) | ||
397 | : "r" (value), "r" (addr), "i" (-EFAULT)); | ||
398 | if (res) | 574 | if (res) |
399 | goto fault; | 575 | goto fault; |
400 | compute_return_epc(regs); | ||
401 | break; | 576 | break; |
402 | 577 | ||
403 | case sd_op: | 578 | case sd_op: |
@@ -412,31 +587,11 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
412 | if (!access_ok(VERIFY_WRITE, addr, 8)) | 587 | if (!access_ok(VERIFY_WRITE, addr, 8)) |
413 | goto sigbus; | 588 | goto sigbus; |
414 | 589 | ||
590 | compute_return_epc(regs); | ||
415 | value = regs->regs[insn.i_format.rt]; | 591 | value = regs->regs[insn.i_format.rt]; |
416 | __asm__ __volatile__ ( | 592 | StoreDW(addr, value, res); |
417 | #ifdef __BIG_ENDIAN | ||
418 | "1:\tsdl\t%1,(%2)\n" | ||
419 | "2:\tsdr\t%1, 7(%2)\n\t" | ||
420 | #endif | ||
421 | #ifdef __LITTLE_ENDIAN | ||
422 | "1:\tsdl\t%1, 7(%2)\n" | ||
423 | "2:\tsdr\t%1, (%2)\n\t" | ||
424 | #endif | ||
425 | "li\t%0, 0\n" | ||
426 | "3:\n\t" | ||
427 | ".section\t.fixup,\"ax\"\n\t" | ||
428 | "4:\tli\t%0, %3\n\t" | ||
429 | "j\t3b\n\t" | ||
430 | ".previous\n\t" | ||
431 | ".section\t__ex_table,\"a\"\n\t" | ||
432 | STR(PTR)"\t1b, 4b\n\t" | ||
433 | STR(PTR)"\t2b, 4b\n\t" | ||
434 | ".previous" | ||
435 | : "=r" (res) | ||
436 | : "r" (value), "r" (addr), "i" (-EFAULT)); | ||
437 | if (res) | 593 | if (res) |
438 | goto fault; | 594 | goto fault; |
439 | compute_return_epc(regs); | ||
440 | break; | 595 | break; |
441 | #endif /* CONFIG_64BIT */ | 596 | #endif /* CONFIG_64BIT */ |
442 | 597 | ||
@@ -447,10 +602,21 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
447 | case ldc1_op: | 602 | case ldc1_op: |
448 | case swc1_op: | 603 | case swc1_op: |
449 | case sdc1_op: | 604 | case sdc1_op: |
450 | /* | 605 | die_if_kernel("Unaligned FP access in kernel code", regs); |
451 | * I herewith declare: this does not happen. So send SIGBUS. | 606 | BUG_ON(!used_math()); |
452 | */ | 607 | BUG_ON(!is_fpu_owner()); |
453 | goto sigbus; | 608 | |
609 | lose_fpu(1); /* Save FPU state for the emulator. */ | ||
610 | res = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, | ||
611 | &fault_addr); | ||
612 | own_fpu(1); /* Restore FPU state. */ | ||
613 | |||
614 | /* Signal if something went wrong. */ | ||
615 | process_fpemu_return(res, fault_addr); | ||
616 | |||
617 | if (res == 0) | ||
618 | break; | ||
619 | return; | ||
454 | 620 | ||
455 | /* | 621 | /* |
456 | * COP2 is available to implementor for application specific use. | 622 | * COP2 is available to implementor for application specific use. |
@@ -488,6 +654,9 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
488 | return; | 654 | return; |
489 | 655 | ||
490 | fault: | 656 | fault: |
657 | /* roll back jump/branch */ | ||
658 | regs->cp0_epc = origpc; | ||
659 | regs->regs[31] = orig31; | ||
491 | /* Did we have an exception handler installed? */ | 660 | /* Did we have an exception handler installed? */ |
492 | if (fixup_exception(regs)) | 661 | if (fixup_exception(regs)) |
493 | return; | 662 | return; |
@@ -504,10 +673,881 @@ sigbus: | |||
504 | return; | 673 | return; |
505 | 674 | ||
506 | sigill: | 675 | sigill: |
507 | die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs); | 676 | die_if_kernel |
677 | ("Unhandled kernel unaligned access or invalid instruction", regs); | ||
508 | force_sig(SIGILL, current); | 678 | force_sig(SIGILL, current); |
509 | } | 679 | } |
510 | 680 | ||
681 | /* Recode table from 16-bit register notation to 32-bit GPR. */ | ||
682 | const int reg16to32[] = { 16, 17, 2, 3, 4, 5, 6, 7 }; | ||
683 | |||
684 | /* Recode table from 16-bit STORE register notation to 32-bit GPR. */ | ||
685 | const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; | ||
686 | |||
687 | void emulate_load_store_microMIPS(struct pt_regs *regs, void __user * addr) | ||
688 | { | ||
689 | unsigned long value; | ||
690 | unsigned int res; | ||
691 | int i; | ||
692 | unsigned int reg = 0, rvar; | ||
693 | unsigned long orig31; | ||
694 | u16 __user *pc16; | ||
695 | u16 halfword; | ||
696 | unsigned int word; | ||
697 | unsigned long origpc, contpc; | ||
698 | union mips_instruction insn; | ||
699 | struct mm_decoded_insn mminsn; | ||
700 | void __user *fault_addr = NULL; | ||
701 | |||
702 | origpc = regs->cp0_epc; | ||
703 | orig31 = regs->regs[31]; | ||
704 | |||
705 | mminsn.micro_mips_mode = 1; | ||
706 | |||
707 | /* | ||
708 | * This load never faults. | ||
709 | */ | ||
710 | pc16 = (unsigned short __user *)msk_isa16_mode(regs->cp0_epc); | ||
711 | __get_user(halfword, pc16); | ||
712 | pc16++; | ||
713 | contpc = regs->cp0_epc + 2; | ||
714 | word = ((unsigned int)halfword << 16); | ||
715 | mminsn.pc_inc = 2; | ||
716 | |||
717 | if (!mm_insn_16bit(halfword)) { | ||
718 | __get_user(halfword, pc16); | ||
719 | pc16++; | ||
720 | contpc = regs->cp0_epc + 4; | ||
721 | mminsn.pc_inc = 4; | ||
722 | word |= halfword; | ||
723 | } | ||
724 | mminsn.insn = word; | ||
725 | |||
726 | if (get_user(halfword, pc16)) | ||
727 | goto fault; | ||
728 | mminsn.next_pc_inc = 2; | ||
729 | word = ((unsigned int)halfword << 16); | ||
730 | |||
731 | if (!mm_insn_16bit(halfword)) { | ||
732 | pc16++; | ||
733 | if (get_user(halfword, pc16)) | ||
734 | goto fault; | ||
735 | mminsn.next_pc_inc = 4; | ||
736 | word |= halfword; | ||
737 | } | ||
738 | mminsn.next_insn = word; | ||
739 | |||
740 | insn = (union mips_instruction)(mminsn.insn); | ||
741 | if (mm_isBranchInstr(regs, mminsn, &contpc)) | ||
742 | insn = (union mips_instruction)(mminsn.next_insn); | ||
743 | |||
744 | /* Parse instruction to find what to do */ | ||
745 | |||
746 | switch (insn.mm_i_format.opcode) { | ||
747 | |||
748 | case mm_pool32a_op: | ||
749 | switch (insn.mm_x_format.func) { | ||
750 | case mm_lwxs_op: | ||
751 | reg = insn.mm_x_format.rd; | ||
752 | goto loadW; | ||
753 | } | ||
754 | |||
755 | goto sigbus; | ||
756 | |||
757 | case mm_pool32b_op: | ||
758 | switch (insn.mm_m_format.func) { | ||
759 | case mm_lwp_func: | ||
760 | reg = insn.mm_m_format.rd; | ||
761 | if (reg == 31) | ||
762 | goto sigbus; | ||
763 | |||
764 | if (!access_ok(VERIFY_READ, addr, 8)) | ||
765 | goto sigbus; | ||
766 | |||
767 | LoadW(addr, value, res); | ||
768 | if (res) | ||
769 | goto fault; | ||
770 | regs->regs[reg] = value; | ||
771 | addr += 4; | ||
772 | LoadW(addr, value, res); | ||
773 | if (res) | ||
774 | goto fault; | ||
775 | regs->regs[reg + 1] = value; | ||
776 | goto success; | ||
777 | |||
778 | case mm_swp_func: | ||
779 | reg = insn.mm_m_format.rd; | ||
780 | if (reg == 31) | ||
781 | goto sigbus; | ||
782 | |||
783 | if (!access_ok(VERIFY_WRITE, addr, 8)) | ||
784 | goto sigbus; | ||
785 | |||
786 | value = regs->regs[reg]; | ||
787 | StoreW(addr, value, res); | ||
788 | if (res) | ||
789 | goto fault; | ||
790 | addr += 4; | ||
791 | value = regs->regs[reg + 1]; | ||
792 | StoreW(addr, value, res); | ||
793 | if (res) | ||
794 | goto fault; | ||
795 | goto success; | ||
796 | |||
797 | case mm_ldp_func: | ||
798 | #ifdef CONFIG_64BIT | ||
799 | reg = insn.mm_m_format.rd; | ||
800 | if (reg == 31) | ||
801 | goto sigbus; | ||
802 | |||
803 | if (!access_ok(VERIFY_READ, addr, 16)) | ||
804 | goto sigbus; | ||
805 | |||
806 | LoadDW(addr, value, res); | ||
807 | if (res) | ||
808 | goto fault; | ||
809 | regs->regs[reg] = value; | ||
810 | addr += 8; | ||
811 | LoadDW(addr, value, res); | ||
812 | if (res) | ||
813 | goto fault; | ||
814 | regs->regs[reg + 1] = value; | ||
815 | goto success; | ||
816 | #endif /* CONFIG_64BIT */ | ||
817 | |||
818 | goto sigill; | ||
819 | |||
820 | case mm_sdp_func: | ||
821 | #ifdef CONFIG_64BIT | ||
822 | reg = insn.mm_m_format.rd; | ||
823 | if (reg == 31) | ||
824 | goto sigbus; | ||
825 | |||
826 | if (!access_ok(VERIFY_WRITE, addr, 16)) | ||
827 | goto sigbus; | ||
828 | |||
829 | value = regs->regs[reg]; | ||
830 | StoreDW(addr, value, res); | ||
831 | if (res) | ||
832 | goto fault; | ||
833 | addr += 8; | ||
834 | value = regs->regs[reg + 1]; | ||
835 | StoreDW(addr, value, res); | ||
836 | if (res) | ||
837 | goto fault; | ||
838 | goto success; | ||
839 | #endif /* CONFIG_64BIT */ | ||
840 | |||
841 | goto sigill; | ||
842 | |||
843 | case mm_lwm32_func: | ||
844 | reg = insn.mm_m_format.rd; | ||
845 | rvar = reg & 0xf; | ||
846 | if ((rvar > 9) || !reg) | ||
847 | goto sigill; | ||
848 | if (reg & 0x10) { | ||
849 | if (!access_ok | ||
850 | (VERIFY_READ, addr, 4 * (rvar + 1))) | ||
851 | goto sigbus; | ||
852 | } else { | ||
853 | if (!access_ok(VERIFY_READ, addr, 4 * rvar)) | ||
854 | goto sigbus; | ||
855 | } | ||
856 | if (rvar == 9) | ||
857 | rvar = 8; | ||
858 | for (i = 16; rvar; rvar--, i++) { | ||
859 | LoadW(addr, value, res); | ||
860 | if (res) | ||
861 | goto fault; | ||
862 | addr += 4; | ||
863 | regs->regs[i] = value; | ||
864 | } | ||
865 | if ((reg & 0xf) == 9) { | ||
866 | LoadW(addr, value, res); | ||
867 | if (res) | ||
868 | goto fault; | ||
869 | addr += 4; | ||
870 | regs->regs[30] = value; | ||
871 | } | ||
872 | if (reg & 0x10) { | ||
873 | LoadW(addr, value, res); | ||
874 | if (res) | ||
875 | goto fault; | ||
876 | regs->regs[31] = value; | ||
877 | } | ||
878 | goto success; | ||
879 | |||
880 | case mm_swm32_func: | ||
881 | reg = insn.mm_m_format.rd; | ||
882 | rvar = reg & 0xf; | ||
883 | if ((rvar > 9) || !reg) | ||
884 | goto sigill; | ||
885 | if (reg & 0x10) { | ||
886 | if (!access_ok | ||
887 | (VERIFY_WRITE, addr, 4 * (rvar + 1))) | ||
888 | goto sigbus; | ||
889 | } else { | ||
890 | if (!access_ok(VERIFY_WRITE, addr, 4 * rvar)) | ||
891 | goto sigbus; | ||
892 | } | ||
893 | if (rvar == 9) | ||
894 | rvar = 8; | ||
895 | for (i = 16; rvar; rvar--, i++) { | ||
896 | value = regs->regs[i]; | ||
897 | StoreW(addr, value, res); | ||
898 | if (res) | ||
899 | goto fault; | ||
900 | addr += 4; | ||
901 | } | ||
902 | if ((reg & 0xf) == 9) { | ||
903 | value = regs->regs[30]; | ||
904 | StoreW(addr, value, res); | ||
905 | if (res) | ||
906 | goto fault; | ||
907 | addr += 4; | ||
908 | } | ||
909 | if (reg & 0x10) { | ||
910 | value = regs->regs[31]; | ||
911 | StoreW(addr, value, res); | ||
912 | if (res) | ||
913 | goto fault; | ||
914 | } | ||
915 | goto success; | ||
916 | |||
917 | case mm_ldm_func: | ||
918 | #ifdef CONFIG_64BIT | ||
919 | reg = insn.mm_m_format.rd; | ||
920 | rvar = reg & 0xf; | ||
921 | if ((rvar > 9) || !reg) | ||
922 | goto sigill; | ||
923 | if (reg & 0x10) { | ||
924 | if (!access_ok | ||
925 | (VERIFY_READ, addr, 8 * (rvar + 1))) | ||
926 | goto sigbus; | ||
927 | } else { | ||
928 | if (!access_ok(VERIFY_READ, addr, 8 * rvar)) | ||
929 | goto sigbus; | ||
930 | } | ||
931 | if (rvar == 9) | ||
932 | rvar = 8; | ||
933 | |||
934 | for (i = 16; rvar; rvar--, i++) { | ||
935 | LoadDW(addr, value, res); | ||
936 | if (res) | ||
937 | goto fault; | ||
938 | addr += 4; | ||
939 | regs->regs[i] = value; | ||
940 | } | ||
941 | if ((reg & 0xf) == 9) { | ||
942 | LoadDW(addr, value, res); | ||
943 | if (res) | ||
944 | goto fault; | ||
945 | addr += 8; | ||
946 | regs->regs[30] = value; | ||
947 | } | ||
948 | if (reg & 0x10) { | ||
949 | LoadDW(addr, value, res); | ||
950 | if (res) | ||
951 | goto fault; | ||
952 | regs->regs[31] = value; | ||
953 | } | ||
954 | goto success; | ||
955 | #endif /* CONFIG_64BIT */ | ||
956 | |||
957 | goto sigill; | ||
958 | |||
959 | case mm_sdm_func: | ||
960 | #ifdef CONFIG_64BIT | ||
961 | reg = insn.mm_m_format.rd; | ||
962 | rvar = reg & 0xf; | ||
963 | if ((rvar > 9) || !reg) | ||
964 | goto sigill; | ||
965 | if (reg & 0x10) { | ||
966 | if (!access_ok | ||
967 | (VERIFY_WRITE, addr, 8 * (rvar + 1))) | ||
968 | goto sigbus; | ||
969 | } else { | ||
970 | if (!access_ok(VERIFY_WRITE, addr, 8 * rvar)) | ||
971 | goto sigbus; | ||
972 | } | ||
973 | if (rvar == 9) | ||
974 | rvar = 8; | ||
975 | |||
976 | for (i = 16; rvar; rvar--, i++) { | ||
977 | value = regs->regs[i]; | ||
978 | StoreDW(addr, value, res); | ||
979 | if (res) | ||
980 | goto fault; | ||
981 | addr += 8; | ||
982 | } | ||
983 | if ((reg & 0xf) == 9) { | ||
984 | value = regs->regs[30]; | ||
985 | StoreDW(addr, value, res); | ||
986 | if (res) | ||
987 | goto fault; | ||
988 | addr += 8; | ||
989 | } | ||
990 | if (reg & 0x10) { | ||
991 | value = regs->regs[31]; | ||
992 | StoreDW(addr, value, res); | ||
993 | if (res) | ||
994 | goto fault; | ||
995 | } | ||
996 | goto success; | ||
997 | #endif /* CONFIG_64BIT */ | ||
998 | |||
999 | goto sigill; | ||
1000 | |||
1001 | /* LWC2, SWC2, LDC2, SDC2 are not serviced */ | ||
1002 | } | ||
1003 | |||
1004 | goto sigbus; | ||
1005 | |||
1006 | case mm_pool32c_op: | ||
1007 | switch (insn.mm_m_format.func) { | ||
1008 | case mm_lwu_func: | ||
1009 | reg = insn.mm_m_format.rd; | ||
1010 | goto loadWU; | ||
1011 | } | ||
1012 | |||
1013 | /* LL,SC,LLD,SCD are not serviced */ | ||
1014 | goto sigbus; | ||
1015 | |||
1016 | case mm_pool32f_op: | ||
1017 | switch (insn.mm_x_format.func) { | ||
1018 | case mm_lwxc1_func: | ||
1019 | case mm_swxc1_func: | ||
1020 | case mm_ldxc1_func: | ||
1021 | case mm_sdxc1_func: | ||
1022 | goto fpu_emul; | ||
1023 | } | ||
1024 | |||
1025 | goto sigbus; | ||
1026 | |||
1027 | case mm_ldc132_op: | ||
1028 | case mm_sdc132_op: | ||
1029 | case mm_lwc132_op: | ||
1030 | case mm_swc132_op: | ||
1031 | fpu_emul: | ||
1032 | /* roll back jump/branch */ | ||
1033 | regs->cp0_epc = origpc; | ||
1034 | regs->regs[31] = orig31; | ||
1035 | |||
1036 | die_if_kernel("Unaligned FP access in kernel code", regs); | ||
1037 | BUG_ON(!used_math()); | ||
1038 | BUG_ON(!is_fpu_owner()); | ||
1039 | |||
1040 | lose_fpu(1); /* save the FPU state for the emulator */ | ||
1041 | res = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, | ||
1042 | &fault_addr); | ||
1043 | own_fpu(1); /* restore FPU state */ | ||
1044 | |||
1045 | /* If something went wrong, signal */ | ||
1046 | process_fpemu_return(res, fault_addr); | ||
1047 | |||
1048 | if (res == 0) | ||
1049 | goto success; | ||
1050 | return; | ||
1051 | |||
1052 | case mm_lh32_op: | ||
1053 | reg = insn.mm_i_format.rt; | ||
1054 | goto loadHW; | ||
1055 | |||
1056 | case mm_lhu32_op: | ||
1057 | reg = insn.mm_i_format.rt; | ||
1058 | goto loadHWU; | ||
1059 | |||
1060 | case mm_lw32_op: | ||
1061 | reg = insn.mm_i_format.rt; | ||
1062 | goto loadW; | ||
1063 | |||
1064 | case mm_sh32_op: | ||
1065 | reg = insn.mm_i_format.rt; | ||
1066 | goto storeHW; | ||
1067 | |||
1068 | case mm_sw32_op: | ||
1069 | reg = insn.mm_i_format.rt; | ||
1070 | goto storeW; | ||
1071 | |||
1072 | case mm_ld32_op: | ||
1073 | reg = insn.mm_i_format.rt; | ||
1074 | goto loadDW; | ||
1075 | |||
1076 | case mm_sd32_op: | ||
1077 | reg = insn.mm_i_format.rt; | ||
1078 | goto storeDW; | ||
1079 | |||
1080 | case mm_pool16c_op: | ||
1081 | switch (insn.mm16_m_format.func) { | ||
1082 | case mm_lwm16_op: | ||
1083 | reg = insn.mm16_m_format.rlist; | ||
1084 | rvar = reg + 1; | ||
1085 | if (!access_ok(VERIFY_READ, addr, 4 * rvar)) | ||
1086 | goto sigbus; | ||
1087 | |||
1088 | for (i = 16; rvar; rvar--, i++) { | ||
1089 | LoadW(addr, value, res); | ||
1090 | if (res) | ||
1091 | goto fault; | ||
1092 | addr += 4; | ||
1093 | regs->regs[i] = value; | ||
1094 | } | ||
1095 | LoadW(addr, value, res); | ||
1096 | if (res) | ||
1097 | goto fault; | ||
1098 | regs->regs[31] = value; | ||
1099 | |||
1100 | goto success; | ||
1101 | |||
1102 | case mm_swm16_op: | ||
1103 | reg = insn.mm16_m_format.rlist; | ||
1104 | rvar = reg + 1; | ||
1105 | if (!access_ok(VERIFY_WRITE, addr, 4 * rvar)) | ||
1106 | goto sigbus; | ||
1107 | |||
1108 | for (i = 16; rvar; rvar--, i++) { | ||
1109 | value = regs->regs[i]; | ||
1110 | StoreW(addr, value, res); | ||
1111 | if (res) | ||
1112 | goto fault; | ||
1113 | addr += 4; | ||
1114 | } | ||
1115 | value = regs->regs[31]; | ||
1116 | StoreW(addr, value, res); | ||
1117 | if (res) | ||
1118 | goto fault; | ||
1119 | |||
1120 | goto success; | ||
1121 | |||
1122 | } | ||
1123 | |||
1124 | goto sigbus; | ||
1125 | |||
1126 | case mm_lhu16_op: | ||
1127 | reg = reg16to32[insn.mm16_rb_format.rt]; | ||
1128 | goto loadHWU; | ||
1129 | |||
1130 | case mm_lw16_op: | ||
1131 | reg = reg16to32[insn.mm16_rb_format.rt]; | ||
1132 | goto loadW; | ||
1133 | |||
1134 | case mm_sh16_op: | ||
1135 | reg = reg16to32st[insn.mm16_rb_format.rt]; | ||
1136 | goto storeHW; | ||
1137 | |||
1138 | case mm_sw16_op: | ||
1139 | reg = reg16to32st[insn.mm16_rb_format.rt]; | ||
1140 | goto storeW; | ||
1141 | |||
1142 | case mm_lwsp16_op: | ||
1143 | reg = insn.mm16_r5_format.rt; | ||
1144 | goto loadW; | ||
1145 | |||
1146 | case mm_swsp16_op: | ||
1147 | reg = insn.mm16_r5_format.rt; | ||
1148 | goto storeW; | ||
1149 | |||
1150 | case mm_lwgp16_op: | ||
1151 | reg = reg16to32[insn.mm16_r3_format.rt]; | ||
1152 | goto loadW; | ||
1153 | |||
1154 | default: | ||
1155 | goto sigill; | ||
1156 | } | ||
1157 | |||
1158 | loadHW: | ||
1159 | if (!access_ok(VERIFY_READ, addr, 2)) | ||
1160 | goto sigbus; | ||
1161 | |||
1162 | LoadHW(addr, value, res); | ||
1163 | if (res) | ||
1164 | goto fault; | ||
1165 | regs->regs[reg] = value; | ||
1166 | goto success; | ||
1167 | |||
1168 | loadHWU: | ||
1169 | if (!access_ok(VERIFY_READ, addr, 2)) | ||
1170 | goto sigbus; | ||
1171 | |||
1172 | LoadHWU(addr, value, res); | ||
1173 | if (res) | ||
1174 | goto fault; | ||
1175 | regs->regs[reg] = value; | ||
1176 | goto success; | ||
1177 | |||
1178 | loadW: | ||
1179 | if (!access_ok(VERIFY_READ, addr, 4)) | ||
1180 | goto sigbus; | ||
1181 | |||
1182 | LoadW(addr, value, res); | ||
1183 | if (res) | ||
1184 | goto fault; | ||
1185 | regs->regs[reg] = value; | ||
1186 | goto success; | ||
1187 | |||
1188 | loadWU: | ||
1189 | #ifdef CONFIG_64BIT | ||
1190 | /* | ||
1191 | * A 32-bit kernel might be running on a 64-bit processor. But | ||
1192 | * if we're on a 32-bit processor and an i-cache incoherency | ||
1193 | * or race makes us see a 64-bit instruction here the sdl/sdr | ||
1194 | * would blow up, so for now we don't handle unaligned 64-bit | ||
1195 | * instructions on 32-bit kernels. | ||
1196 | */ | ||
1197 | if (!access_ok(VERIFY_READ, addr, 4)) | ||
1198 | goto sigbus; | ||
1199 | |||
1200 | LoadWU(addr, value, res); | ||
1201 | if (res) | ||
1202 | goto fault; | ||
1203 | regs->regs[reg] = value; | ||
1204 | goto success; | ||
1205 | #endif /* CONFIG_64BIT */ | ||
1206 | |||
1207 | /* Cannot handle 64-bit instructions in 32-bit kernel */ | ||
1208 | goto sigill; | ||
1209 | |||
1210 | loadDW: | ||
1211 | #ifdef CONFIG_64BIT | ||
1212 | /* | ||
1213 | * A 32-bit kernel might be running on a 64-bit processor. But | ||
1214 | * if we're on a 32-bit processor and an i-cache incoherency | ||
1215 | * or race makes us see a 64-bit instruction here the sdl/sdr | ||
1216 | * would blow up, so for now we don't handle unaligned 64-bit | ||
1217 | * instructions on 32-bit kernels. | ||
1218 | */ | ||
1219 | if (!access_ok(VERIFY_READ, addr, 8)) | ||
1220 | goto sigbus; | ||
1221 | |||
1222 | LoadDW(addr, value, res); | ||
1223 | if (res) | ||
1224 | goto fault; | ||
1225 | regs->regs[reg] = value; | ||
1226 | goto success; | ||
1227 | #endif /* CONFIG_64BIT */ | ||
1228 | |||
1229 | /* Cannot handle 64-bit instructions in 32-bit kernel */ | ||
1230 | goto sigill; | ||
1231 | |||
1232 | storeHW: | ||
1233 | if (!access_ok(VERIFY_WRITE, addr, 2)) | ||
1234 | goto sigbus; | ||
1235 | |||
1236 | value = regs->regs[reg]; | ||
1237 | StoreHW(addr, value, res); | ||
1238 | if (res) | ||
1239 | goto fault; | ||
1240 | goto success; | ||
1241 | |||
1242 | storeW: | ||
1243 | if (!access_ok(VERIFY_WRITE, addr, 4)) | ||
1244 | goto sigbus; | ||
1245 | |||
1246 | value = regs->regs[reg]; | ||
1247 | StoreW(addr, value, res); | ||
1248 | if (res) | ||
1249 | goto fault; | ||
1250 | goto success; | ||
1251 | |||
1252 | storeDW: | ||
1253 | #ifdef CONFIG_64BIT | ||
1254 | /* | ||
1255 | * A 32-bit kernel might be running on a 64-bit processor. But | ||
1256 | * if we're on a 32-bit processor and an i-cache incoherency | ||
1257 | * or race makes us see a 64-bit instruction here the sdl/sdr | ||
1258 | * would blow up, so for now we don't handle unaligned 64-bit | ||
1259 | * instructions on 32-bit kernels. | ||
1260 | */ | ||
1261 | if (!access_ok(VERIFY_WRITE, addr, 8)) | ||
1262 | goto sigbus; | ||
1263 | |||
1264 | value = regs->regs[reg]; | ||
1265 | StoreDW(addr, value, res); | ||
1266 | if (res) | ||
1267 | goto fault; | ||
1268 | goto success; | ||
1269 | #endif /* CONFIG_64BIT */ | ||
1270 | |||
1271 | /* Cannot handle 64-bit instructions in 32-bit kernel */ | ||
1272 | goto sigill; | ||
1273 | |||
1274 | success: | ||
1275 | regs->cp0_epc = contpc; /* advance or branch */ | ||
1276 | |||
1277 | #ifdef CONFIG_DEBUG_FS | ||
1278 | unaligned_instructions++; | ||
1279 | #endif | ||
1280 | return; | ||
1281 | |||
1282 | fault: | ||
1283 | /* roll back jump/branch */ | ||
1284 | regs->cp0_epc = origpc; | ||
1285 | regs->regs[31] = orig31; | ||
1286 | /* Did we have an exception handler installed? */ | ||
1287 | if (fixup_exception(regs)) | ||
1288 | return; | ||
1289 | |||
1290 | die_if_kernel("Unhandled kernel unaligned access", regs); | ||
1291 | force_sig(SIGSEGV, current); | ||
1292 | |||
1293 | return; | ||
1294 | |||
1295 | sigbus: | ||
1296 | die_if_kernel("Unhandled kernel unaligned access", regs); | ||
1297 | force_sig(SIGBUS, current); | ||
1298 | |||
1299 | return; | ||
1300 | |||
1301 | sigill: | ||
1302 | die_if_kernel | ||
1303 | ("Unhandled kernel unaligned access or invalid instruction", regs); | ||
1304 | force_sig(SIGILL, current); | ||
1305 | } | ||
1306 | |||
1307 | static void emulate_load_store_MIPS16e(struct pt_regs *regs, void __user * addr) | ||
1308 | { | ||
1309 | unsigned long value; | ||
1310 | unsigned int res; | ||
1311 | int reg; | ||
1312 | unsigned long orig31; | ||
1313 | u16 __user *pc16; | ||
1314 | unsigned long origpc; | ||
1315 | union mips16e_instruction mips16inst, oldinst; | ||
1316 | |||
1317 | origpc = regs->cp0_epc; | ||
1318 | orig31 = regs->regs[31]; | ||
1319 | pc16 = (unsigned short __user *)msk_isa16_mode(origpc); | ||
1320 | /* | ||
1321 | * This load never faults. | ||
1322 | */ | ||
1323 | __get_user(mips16inst.full, pc16); | ||
1324 | oldinst = mips16inst; | ||
1325 | |||
1326 | /* skip EXTEND instruction */ | ||
1327 | if (mips16inst.ri.opcode == MIPS16e_extend_op) { | ||
1328 | pc16++; | ||
1329 | __get_user(mips16inst.full, pc16); | ||
1330 | } else if (delay_slot(regs)) { | ||
1331 | /* skip jump instructions */ | ||
1332 | /* JAL/JALX are 32 bits but have OPCODE in first short int */ | ||
1333 | if (mips16inst.ri.opcode == MIPS16e_jal_op) | ||
1334 | pc16++; | ||
1335 | pc16++; | ||
1336 | if (get_user(mips16inst.full, pc16)) | ||
1337 | goto sigbus; | ||
1338 | } | ||
1339 | |||
1340 | switch (mips16inst.ri.opcode) { | ||
1341 | case MIPS16e_i64_op: /* I64 or RI64 instruction */ | ||
1342 | switch (mips16inst.i64.func) { /* I64/RI64 func field check */ | ||
1343 | case MIPS16e_ldpc_func: | ||
1344 | case MIPS16e_ldsp_func: | ||
1345 | reg = reg16to32[mips16inst.ri64.ry]; | ||
1346 | goto loadDW; | ||
1347 | |||
1348 | case MIPS16e_sdsp_func: | ||
1349 | reg = reg16to32[mips16inst.ri64.ry]; | ||
1350 | goto writeDW; | ||
1351 | |||
1352 | case MIPS16e_sdrasp_func: | ||
1353 | reg = 29; /* GPRSP */ | ||
1354 | goto writeDW; | ||
1355 | } | ||
1356 | |||
1357 | goto sigbus; | ||
1358 | |||
1359 | case MIPS16e_swsp_op: | ||
1360 | case MIPS16e_lwpc_op: | ||
1361 | case MIPS16e_lwsp_op: | ||
1362 | reg = reg16to32[mips16inst.ri.rx]; | ||
1363 | break; | ||
1364 | |||
1365 | case MIPS16e_i8_op: | ||
1366 | if (mips16inst.i8.func != MIPS16e_swrasp_func) | ||
1367 | goto sigbus; | ||
1368 | reg = 29; /* GPRSP */ | ||
1369 | break; | ||
1370 | |||
1371 | default: | ||
1372 | reg = reg16to32[mips16inst.rri.ry]; | ||
1373 | break; | ||
1374 | } | ||
1375 | |||
1376 | switch (mips16inst.ri.opcode) { | ||
1377 | |||
1378 | case MIPS16e_lb_op: | ||
1379 | case MIPS16e_lbu_op: | ||
1380 | case MIPS16e_sb_op: | ||
1381 | goto sigbus; | ||
1382 | |||
1383 | case MIPS16e_lh_op: | ||
1384 | if (!access_ok(VERIFY_READ, addr, 2)) | ||
1385 | goto sigbus; | ||
1386 | |||
1387 | LoadHW(addr, value, res); | ||
1388 | if (res) | ||
1389 | goto fault; | ||
1390 | MIPS16e_compute_return_epc(regs, &oldinst); | ||
1391 | regs->regs[reg] = value; | ||
1392 | break; | ||
1393 | |||
1394 | case MIPS16e_lhu_op: | ||
1395 | if (!access_ok(VERIFY_READ, addr, 2)) | ||
1396 | goto sigbus; | ||
1397 | |||
1398 | LoadHWU(addr, value, res); | ||
1399 | if (res) | ||
1400 | goto fault; | ||
1401 | MIPS16e_compute_return_epc(regs, &oldinst); | ||
1402 | regs->regs[reg] = value; | ||
1403 | break; | ||
1404 | |||
1405 | case MIPS16e_lw_op: | ||
1406 | case MIPS16e_lwpc_op: | ||
1407 | case MIPS16e_lwsp_op: | ||
1408 | if (!access_ok(VERIFY_READ, addr, 4)) | ||
1409 | goto sigbus; | ||
1410 | |||
1411 | LoadW(addr, value, res); | ||
1412 | if (res) | ||
1413 | goto fault; | ||
1414 | MIPS16e_compute_return_epc(regs, &oldinst); | ||
1415 | regs->regs[reg] = value; | ||
1416 | break; | ||
1417 | |||
1418 | case MIPS16e_lwu_op: | ||
1419 | #ifdef CONFIG_64BIT | ||
1420 | /* | ||
1421 | * A 32-bit kernel might be running on a 64-bit processor. But | ||
1422 | * if we're on a 32-bit processor and an i-cache incoherency | ||
1423 | * or race makes us see a 64-bit instruction here the sdl/sdr | ||
1424 | * would blow up, so for now we don't handle unaligned 64-bit | ||
1425 | * instructions on 32-bit kernels. | ||
1426 | */ | ||
1427 | if (!access_ok(VERIFY_READ, addr, 4)) | ||
1428 | goto sigbus; | ||
1429 | |||
1430 | LoadWU(addr, value, res); | ||
1431 | if (res) | ||
1432 | goto fault; | ||
1433 | MIPS16e_compute_return_epc(regs, &oldinst); | ||
1434 | regs->regs[reg] = value; | ||
1435 | break; | ||
1436 | #endif /* CONFIG_64BIT */ | ||
1437 | |||
1438 | /* Cannot handle 64-bit instructions in 32-bit kernel */ | ||
1439 | goto sigill; | ||
1440 | |||
1441 | case MIPS16e_ld_op: | ||
1442 | loadDW: | ||
1443 | #ifdef CONFIG_64BIT | ||
1444 | /* | ||
1445 | * A 32-bit kernel might be running on a 64-bit processor. But | ||
1446 | * if we're on a 32-bit processor and an i-cache incoherency | ||
1447 | * or race makes us see a 64-bit instruction here the sdl/sdr | ||
1448 | * would blow up, so for now we don't handle unaligned 64-bit | ||
1449 | * instructions on 32-bit kernels. | ||
1450 | */ | ||
1451 | if (!access_ok(VERIFY_READ, addr, 8)) | ||
1452 | goto sigbus; | ||
1453 | |||
1454 | LoadDW(addr, value, res); | ||
1455 | if (res) | ||
1456 | goto fault; | ||
1457 | MIPS16e_compute_return_epc(regs, &oldinst); | ||
1458 | regs->regs[reg] = value; | ||
1459 | break; | ||
1460 | #endif /* CONFIG_64BIT */ | ||
1461 | |||
1462 | /* Cannot handle 64-bit instructions in 32-bit kernel */ | ||
1463 | goto sigill; | ||
1464 | |||
1465 | case MIPS16e_sh_op: | ||
1466 | if (!access_ok(VERIFY_WRITE, addr, 2)) | ||
1467 | goto sigbus; | ||
1468 | |||
1469 | MIPS16e_compute_return_epc(regs, &oldinst); | ||
1470 | value = regs->regs[reg]; | ||
1471 | StoreHW(addr, value, res); | ||
1472 | if (res) | ||
1473 | goto fault; | ||
1474 | break; | ||
1475 | |||
1476 | case MIPS16e_sw_op: | ||
1477 | case MIPS16e_swsp_op: | ||
1478 | case MIPS16e_i8_op: /* actually - MIPS16e_swrasp_func */ | ||
1479 | if (!access_ok(VERIFY_WRITE, addr, 4)) | ||
1480 | goto sigbus; | ||
1481 | |||
1482 | MIPS16e_compute_return_epc(regs, &oldinst); | ||
1483 | value = regs->regs[reg]; | ||
1484 | StoreW(addr, value, res); | ||
1485 | if (res) | ||
1486 | goto fault; | ||
1487 | break; | ||
1488 | |||
1489 | case MIPS16e_sd_op: | ||
1490 | writeDW: | ||
1491 | #ifdef CONFIG_64BIT | ||
1492 | /* | ||
1493 | * A 32-bit kernel might be running on a 64-bit processor. But | ||
1494 | * if we're on a 32-bit processor and an i-cache incoherency | ||
1495 | * or race makes us see a 64-bit instruction here the sdl/sdr | ||
1496 | * would blow up, so for now we don't handle unaligned 64-bit | ||
1497 | * instructions on 32-bit kernels. | ||
1498 | */ | ||
1499 | if (!access_ok(VERIFY_WRITE, addr, 8)) | ||
1500 | goto sigbus; | ||
1501 | |||
1502 | MIPS16e_compute_return_epc(regs, &oldinst); | ||
1503 | value = regs->regs[reg]; | ||
1504 | StoreDW(addr, value, res); | ||
1505 | if (res) | ||
1506 | goto fault; | ||
1507 | break; | ||
1508 | #endif /* CONFIG_64BIT */ | ||
1509 | |||
1510 | /* Cannot handle 64-bit instructions in 32-bit kernel */ | ||
1511 | goto sigill; | ||
1512 | |||
1513 | default: | ||
1514 | /* | ||
1515 | * Pheeee... We encountered an yet unknown instruction or | ||
1516 | * cache coherence problem. Die sucker, die ... | ||
1517 | */ | ||
1518 | goto sigill; | ||
1519 | } | ||
1520 | |||
1521 | #ifdef CONFIG_DEBUG_FS | ||
1522 | unaligned_instructions++; | ||
1523 | #endif | ||
1524 | |||
1525 | return; | ||
1526 | |||
1527 | fault: | ||
1528 | /* roll back jump/branch */ | ||
1529 | regs->cp0_epc = origpc; | ||
1530 | regs->regs[31] = orig31; | ||
1531 | /* Did we have an exception handler installed? */ | ||
1532 | if (fixup_exception(regs)) | ||
1533 | return; | ||
1534 | |||
1535 | die_if_kernel("Unhandled kernel unaligned access", regs); | ||
1536 | force_sig(SIGSEGV, current); | ||
1537 | |||
1538 | return; | ||
1539 | |||
1540 | sigbus: | ||
1541 | die_if_kernel("Unhandled kernel unaligned access", regs); | ||
1542 | force_sig(SIGBUS, current); | ||
1543 | |||
1544 | return; | ||
1545 | |||
1546 | sigill: | ||
1547 | die_if_kernel | ||
1548 | ("Unhandled kernel unaligned access or invalid instruction", regs); | ||
1549 | force_sig(SIGILL, current); | ||
1550 | } | ||
511 | asmlinkage void do_ade(struct pt_regs *regs) | 1551 | asmlinkage void do_ade(struct pt_regs *regs) |
512 | { | 1552 | { |
513 | unsigned int __user *pc; | 1553 | unsigned int __user *pc; |
@@ -517,23 +1557,62 @@ asmlinkage void do_ade(struct pt_regs *regs) | |||
517 | 1, regs, regs->cp0_badvaddr); | 1557 | 1, regs, regs->cp0_badvaddr); |
518 | /* | 1558 | /* |
519 | * Did we catch a fault trying to load an instruction? | 1559 | * Did we catch a fault trying to load an instruction? |
520 | * Or are we running in MIPS16 mode? | ||
521 | */ | 1560 | */ |
522 | if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1)) | 1561 | if (regs->cp0_badvaddr == regs->cp0_epc) |
523 | goto sigbus; | 1562 | goto sigbus; |
524 | 1563 | ||
525 | pc = (unsigned int __user *) exception_epc(regs); | ||
526 | if (user_mode(regs) && !test_thread_flag(TIF_FIXADE)) | 1564 | if (user_mode(regs) && !test_thread_flag(TIF_FIXADE)) |
527 | goto sigbus; | 1565 | goto sigbus; |
528 | if (unaligned_action == UNALIGNED_ACTION_SIGNAL) | 1566 | if (unaligned_action == UNALIGNED_ACTION_SIGNAL) |
529 | goto sigbus; | 1567 | goto sigbus; |
530 | else if (unaligned_action == UNALIGNED_ACTION_SHOW) | ||
531 | show_registers(regs); | ||
532 | 1568 | ||
533 | /* | 1569 | /* |
534 | * Do branch emulation only if we didn't forward the exception. | 1570 | * Do branch emulation only if we didn't forward the exception. |
535 | * This is all so but ugly ... | 1571 | * This is all so but ugly ... |
536 | */ | 1572 | */ |
1573 | |||
1574 | /* | ||
1575 | * Are we running in microMIPS mode? | ||
1576 | */ | ||
1577 | if (get_isa16_mode(regs->cp0_epc)) { | ||
1578 | /* | ||
1579 | * Did we catch a fault trying to load an instruction in | ||
1580 | * 16-bit mode? | ||
1581 | */ | ||
1582 | if (regs->cp0_badvaddr == msk_isa16_mode(regs->cp0_epc)) | ||
1583 | goto sigbus; | ||
1584 | if (unaligned_action == UNALIGNED_ACTION_SHOW) | ||
1585 | show_registers(regs); | ||
1586 | |||
1587 | if (cpu_has_mmips) { | ||
1588 | seg = get_fs(); | ||
1589 | if (!user_mode(regs)) | ||
1590 | set_fs(KERNEL_DS); | ||
1591 | emulate_load_store_microMIPS(regs, | ||
1592 | (void __user *)regs->cp0_badvaddr); | ||
1593 | set_fs(seg); | ||
1594 | |||
1595 | return; | ||
1596 | } | ||
1597 | |||
1598 | if (cpu_has_mips16) { | ||
1599 | seg = get_fs(); | ||
1600 | if (!user_mode(regs)) | ||
1601 | set_fs(KERNEL_DS); | ||
1602 | emulate_load_store_MIPS16e(regs, | ||
1603 | (void __user *)regs->cp0_badvaddr); | ||
1604 | set_fs(seg); | ||
1605 | |||
1606 | return; | ||
1607 | } | ||
1608 | |||
1609 | goto sigbus; | ||
1610 | } | ||
1611 | |||
1612 | if (unaligned_action == UNALIGNED_ACTION_SHOW) | ||
1613 | show_registers(regs); | ||
1614 | pc = (unsigned int __user *)exception_epc(regs); | ||
1615 | |||
537 | seg = get_fs(); | 1616 | seg = get_fs(); |
538 | if (!user_mode(regs)) | 1617 | if (!user_mode(regs)) |
539 | set_fs(KERNEL_DS); | 1618 | set_fs(KERNEL_DS); |
diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c index 4b6274b47f33..2b2bac9a40aa 100644 --- a/arch/mips/kvm/kvm_mips_emul.c +++ b/arch/mips/kvm/kvm_mips_emul.c | |||
@@ -525,18 +525,16 @@ kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, uint32_t cause, | |||
525 | printk("MTCz, cop0->reg[EBASE]: %#lx\n", | 525 | printk("MTCz, cop0->reg[EBASE]: %#lx\n", |
526 | kvm_read_c0_guest_ebase(cop0)); | 526 | kvm_read_c0_guest_ebase(cop0)); |
527 | } else if (rd == MIPS_CP0_TLB_HI && sel == 0) { | 527 | } else if (rd == MIPS_CP0_TLB_HI && sel == 0) { |
528 | uint32_t nasid = | 528 | uint32_t nasid = ASID_MASK(vcpu->arch.gprs[rt]); |
529 | vcpu->arch.gprs[rt] & ASID_MASK; | ||
530 | if ((KSEGX(vcpu->arch.gprs[rt]) != CKSEG0) | 529 | if ((KSEGX(vcpu->arch.gprs[rt]) != CKSEG0) |
531 | && | 530 | && |
532 | ((kvm_read_c0_guest_entryhi(cop0) & | 531 | (ASID_MASK(kvm_read_c0_guest_entryhi(cop0)) |
533 | ASID_MASK) != nasid)) { | 532 | != nasid)) { |
534 | 533 | ||
535 | kvm_debug | 534 | kvm_debug |
536 | ("MTCz, change ASID from %#lx to %#lx\n", | 535 | ("MTCz, change ASID from %#lx to %#lx\n", |
537 | kvm_read_c0_guest_entryhi(cop0) & | 536 | ASID_MASK(kvm_read_c0_guest_entryhi(cop0)), |
538 | ASID_MASK, | 537 | ASID_MASK(vcpu->arch.gprs[rt])); |
539 | vcpu->arch.gprs[rt] & ASID_MASK); | ||
540 | 538 | ||
541 | /* Blow away the shadow host TLBs */ | 539 | /* Blow away the shadow host TLBs */ |
542 | kvm_mips_flush_host_tlb(1); | 540 | kvm_mips_flush_host_tlb(1); |
@@ -988,8 +986,7 @@ kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, uint32_t cause, | |||
988 | * resulting handler will do the right thing | 986 | * resulting handler will do the right thing |
989 | */ | 987 | */ |
990 | index = kvm_mips_guest_tlb_lookup(vcpu, (va & VPN2_MASK) | | 988 | index = kvm_mips_guest_tlb_lookup(vcpu, (va & VPN2_MASK) | |
991 | (kvm_read_c0_guest_entryhi | 989 | ASID_MASK(kvm_read_c0_guest_entryhi(cop0))); |
992 | (cop0) & ASID_MASK)); | ||
993 | 990 | ||
994 | if (index < 0) { | 991 | if (index < 0) { |
995 | vcpu->arch.host_cp0_entryhi = (va & VPN2_MASK); | 992 | vcpu->arch.host_cp0_entryhi = (va & VPN2_MASK); |
@@ -1154,7 +1151,7 @@ kvm_mips_emulate_tlbmiss_ld(unsigned long cause, uint32_t *opc, | |||
1154 | struct kvm_vcpu_arch *arch = &vcpu->arch; | 1151 | struct kvm_vcpu_arch *arch = &vcpu->arch; |
1155 | enum emulation_result er = EMULATE_DONE; | 1152 | enum emulation_result er = EMULATE_DONE; |
1156 | unsigned long entryhi = (vcpu->arch. host_cp0_badvaddr & VPN2_MASK) | | 1153 | unsigned long entryhi = (vcpu->arch. host_cp0_badvaddr & VPN2_MASK) | |
1157 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1154 | ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); |
1158 | 1155 | ||
1159 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | 1156 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { |
1160 | /* save old pc */ | 1157 | /* save old pc */ |
@@ -1201,7 +1198,7 @@ kvm_mips_emulate_tlbinv_ld(unsigned long cause, uint32_t *opc, | |||
1201 | enum emulation_result er = EMULATE_DONE; | 1198 | enum emulation_result er = EMULATE_DONE; |
1202 | unsigned long entryhi = | 1199 | unsigned long entryhi = |
1203 | (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | | 1200 | (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | |
1204 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1201 | ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); |
1205 | 1202 | ||
1206 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | 1203 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { |
1207 | /* save old pc */ | 1204 | /* save old pc */ |
@@ -1246,7 +1243,7 @@ kvm_mips_emulate_tlbmiss_st(unsigned long cause, uint32_t *opc, | |||
1246 | struct kvm_vcpu_arch *arch = &vcpu->arch; | 1243 | struct kvm_vcpu_arch *arch = &vcpu->arch; |
1247 | enum emulation_result er = EMULATE_DONE; | 1244 | enum emulation_result er = EMULATE_DONE; |
1248 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | | 1245 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | |
1249 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1246 | ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); |
1250 | 1247 | ||
1251 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | 1248 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { |
1252 | /* save old pc */ | 1249 | /* save old pc */ |
@@ -1290,7 +1287,7 @@ kvm_mips_emulate_tlbinv_st(unsigned long cause, uint32_t *opc, | |||
1290 | struct kvm_vcpu_arch *arch = &vcpu->arch; | 1287 | struct kvm_vcpu_arch *arch = &vcpu->arch; |
1291 | enum emulation_result er = EMULATE_DONE; | 1288 | enum emulation_result er = EMULATE_DONE; |
1292 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | | 1289 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | |
1293 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1290 | ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); |
1294 | 1291 | ||
1295 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | 1292 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { |
1296 | /* save old pc */ | 1293 | /* save old pc */ |
@@ -1359,7 +1356,7 @@ kvm_mips_emulate_tlbmod(unsigned long cause, uint32_t *opc, | |||
1359 | { | 1356 | { |
1360 | struct mips_coproc *cop0 = vcpu->arch.cop0; | 1357 | struct mips_coproc *cop0 = vcpu->arch.cop0; |
1361 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | | 1358 | unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | |
1362 | (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); | 1359 | ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); |
1363 | struct kvm_vcpu_arch *arch = &vcpu->arch; | 1360 | struct kvm_vcpu_arch *arch = &vcpu->arch; |
1364 | enum emulation_result er = EMULATE_DONE; | 1361 | enum emulation_result er = EMULATE_DONE; |
1365 | 1362 | ||
@@ -1786,8 +1783,8 @@ kvm_mips_handle_tlbmiss(unsigned long cause, uint32_t *opc, | |||
1786 | */ | 1783 | */ |
1787 | index = kvm_mips_guest_tlb_lookup(vcpu, | 1784 | index = kvm_mips_guest_tlb_lookup(vcpu, |
1788 | (va & VPN2_MASK) | | 1785 | (va & VPN2_MASK) | |
1789 | (kvm_read_c0_guest_entryhi | 1786 | ASID_MASK(kvm_read_c0_guest_entryhi |
1790 | (vcpu->arch.cop0) & ASID_MASK)); | 1787 | (vcpu->arch.cop0))); |
1791 | if (index < 0) { | 1788 | if (index < 0) { |
1792 | if (exccode == T_TLB_LD_MISS) { | 1789 | if (exccode == T_TLB_LD_MISS) { |
1793 | er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu); | 1790 | er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu); |
diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c index e3f0d9b8b6c5..89511a9258d3 100644 --- a/arch/mips/kvm/kvm_tlb.c +++ b/arch/mips/kvm/kvm_tlb.c | |||
@@ -51,13 +51,13 @@ EXPORT_SYMBOL(kvm_mips_is_error_pfn); | |||
51 | 51 | ||
52 | uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu) | 52 | uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu) |
53 | { | 53 | { |
54 | return vcpu->arch.guest_kernel_asid[smp_processor_id()] & ASID_MASK; | 54 | return ASID_MASK(vcpu->arch.guest_kernel_asid[smp_processor_id()]); |
55 | } | 55 | } |
56 | 56 | ||
57 | 57 | ||
58 | uint32_t kvm_mips_get_user_asid(struct kvm_vcpu *vcpu) | 58 | uint32_t kvm_mips_get_user_asid(struct kvm_vcpu *vcpu) |
59 | { | 59 | { |
60 | return vcpu->arch.guest_user_asid[smp_processor_id()] & ASID_MASK; | 60 | return ASID_MASK(vcpu->arch.guest_user_asid[smp_processor_id()]); |
61 | } | 61 | } |
62 | 62 | ||
63 | inline uint32_t kvm_mips_get_commpage_asid (struct kvm_vcpu *vcpu) | 63 | inline uint32_t kvm_mips_get_commpage_asid (struct kvm_vcpu *vcpu) |
@@ -84,7 +84,7 @@ void kvm_mips_dump_host_tlbs(void) | |||
84 | old_pagemask = read_c0_pagemask(); | 84 | old_pagemask = read_c0_pagemask(); |
85 | 85 | ||
86 | printk("HOST TLBs:\n"); | 86 | printk("HOST TLBs:\n"); |
87 | printk("ASID: %#lx\n", read_c0_entryhi() & ASID_MASK); | 87 | printk("ASID: %#lx\n", ASID_MASK(read_c0_entryhi())); |
88 | 88 | ||
89 | for (i = 0; i < current_cpu_data.tlbsize; i++) { | 89 | for (i = 0; i < current_cpu_data.tlbsize; i++) { |
90 | write_c0_index(i); | 90 | write_c0_index(i); |
@@ -428,7 +428,7 @@ int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi) | |||
428 | 428 | ||
429 | for (i = 0; i < KVM_MIPS_GUEST_TLB_SIZE; i++) { | 429 | for (i = 0; i < KVM_MIPS_GUEST_TLB_SIZE; i++) { |
430 | if (((TLB_VPN2(tlb[i]) & ~tlb[i].tlb_mask) == ((entryhi & VPN2_MASK) & ~tlb[i].tlb_mask)) && | 430 | if (((TLB_VPN2(tlb[i]) & ~tlb[i].tlb_mask) == ((entryhi & VPN2_MASK) & ~tlb[i].tlb_mask)) && |
431 | (TLB_IS_GLOBAL(tlb[i]) || (TLB_ASID(tlb[i]) == (entryhi & ASID_MASK)))) { | 431 | (TLB_IS_GLOBAL(tlb[i]) || (TLB_ASID(tlb[i]) == ASID_MASK(entryhi)))) { |
432 | index = i; | 432 | index = i; |
433 | break; | 433 | break; |
434 | } | 434 | } |
@@ -626,7 +626,7 @@ kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu, | |||
626 | { | 626 | { |
627 | unsigned long asid = asid_cache(cpu); | 627 | unsigned long asid = asid_cache(cpu); |
628 | 628 | ||
629 | if (!((asid += ASID_INC) & ASID_MASK)) { | 629 | if (!(ASID_MASK(ASID_INC(asid)))) { |
630 | if (cpu_has_vtag_icache) { | 630 | if (cpu_has_vtag_icache) { |
631 | flush_icache_all(); | 631 | flush_icache_all(); |
632 | } | 632 | } |
@@ -804,8 +804,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
804 | if (!newasid) { | 804 | if (!newasid) { |
805 | /* If we preempted while the guest was executing, then reload the pre-empted ASID */ | 805 | /* If we preempted while the guest was executing, then reload the pre-empted ASID */ |
806 | if (current->flags & PF_VCPU) { | 806 | if (current->flags & PF_VCPU) { |
807 | write_c0_entryhi(vcpu->arch. | 807 | write_c0_entryhi(ASID_MASK(vcpu->arch.preempt_entryhi)); |
808 | preempt_entryhi & ASID_MASK); | ||
809 | ehb(); | 808 | ehb(); |
810 | } | 809 | } |
811 | } else { | 810 | } else { |
@@ -817,13 +816,11 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
817 | */ | 816 | */ |
818 | if (current->flags & PF_VCPU) { | 817 | if (current->flags & PF_VCPU) { |
819 | if (KVM_GUEST_KERNEL_MODE(vcpu)) | 818 | if (KVM_GUEST_KERNEL_MODE(vcpu)) |
820 | write_c0_entryhi(vcpu->arch. | 819 | write_c0_entryhi(ASID_MASK(vcpu->arch. |
821 | guest_kernel_asid[cpu] & | 820 | guest_kernel_asid[cpu])); |
822 | ASID_MASK); | ||
823 | else | 821 | else |
824 | write_c0_entryhi(vcpu->arch. | 822 | write_c0_entryhi(ASID_MASK(vcpu->arch. |
825 | guest_user_asid[cpu] & | 823 | guest_user_asid[cpu])); |
826 | ASID_MASK); | ||
827 | ehb(); | 824 | ehb(); |
828 | } | 825 | } |
829 | } | 826 | } |
@@ -882,8 +879,7 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu) | |||
882 | kvm_mips_guest_tlb_lookup(vcpu, | 879 | kvm_mips_guest_tlb_lookup(vcpu, |
883 | ((unsigned long) opc & VPN2_MASK) | 880 | ((unsigned long) opc & VPN2_MASK) |
884 | | | 881 | | |
885 | (kvm_read_c0_guest_entryhi | 882 | ASID_MASK(kvm_read_c0_guest_entryhi(cop0))); |
886 | (cop0) & ASID_MASK)); | ||
887 | if (index < 0) { | 883 | if (index < 0) { |
888 | kvm_err | 884 | kvm_err |
889 | ("%s: get_user_failed for %p, vcpu: %p, ASID: %#lx\n", | 885 | ("%s: get_user_failed for %p, vcpu: %p, ASID: %#lx\n", |
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index 32b9f21bfd85..8a12d00908e0 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <asm/page.h> | 11 | #include <asm/page.h> |
12 | #include <asm/pgtable.h> | 12 | #include <asm/pgtable.h> |
13 | #include <asm/tlbdebug.h> | 13 | #include <asm/tlbdebug.h> |
14 | #include <asm/mmu_context.h> | ||
14 | 15 | ||
15 | static inline const char *msk2str(unsigned int mask) | 16 | static inline const char *msk2str(unsigned int mask) |
16 | { | 17 | { |
@@ -55,7 +56,7 @@ static void dump_tlb(int first, int last) | |||
55 | s_pagemask = read_c0_pagemask(); | 56 | s_pagemask = read_c0_pagemask(); |
56 | s_entryhi = read_c0_entryhi(); | 57 | s_entryhi = read_c0_entryhi(); |
57 | s_index = read_c0_index(); | 58 | s_index = read_c0_index(); |
58 | asid = s_entryhi & 0xff; | 59 | asid = ASID_MASK(s_entryhi); |
59 | 60 | ||
60 | for (i = first; i <= last; i++) { | 61 | for (i = first; i <= last; i++) { |
61 | write_c0_index(i); | 62 | write_c0_index(i); |
@@ -85,7 +86,7 @@ static void dump_tlb(int first, int last) | |||
85 | 86 | ||
86 | printk("va=%0*lx asid=%02lx\n", | 87 | printk("va=%0*lx asid=%02lx\n", |
87 | width, (entryhi & ~0x1fffUL), | 88 | width, (entryhi & ~0x1fffUL), |
88 | entryhi & 0xff); | 89 | ASID_MASK(entryhi)); |
89 | printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ", | 90 | printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ", |
90 | width, | 91 | width, |
91 | (entrylo0 << 6) & PAGE_MASK, c0, | 92 | (entrylo0 << 6) & PAGE_MASK, c0, |
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 053d3b0b0317..0580194e7402 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S | |||
@@ -5,7 +5,8 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 1998, 1999, 2000 by Ralf Baechle | 6 | * Copyright (C) 1998, 1999, 2000 by Ralf Baechle |
7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
8 | * Copyright (C) 2007 Maciej W. Rozycki | 8 | * Copyright (C) 2007 by Maciej W. Rozycki |
9 | * Copyright (C) 2011, 2012 MIPS Technologies, Inc. | ||
9 | */ | 10 | */ |
10 | #include <asm/asm.h> | 11 | #include <asm/asm.h> |
11 | #include <asm/asm-offsets.h> | 12 | #include <asm/asm-offsets.h> |
@@ -19,6 +20,20 @@ | |||
19 | #define LONG_S_R sdr | 20 | #define LONG_S_R sdr |
20 | #endif | 21 | #endif |
21 | 22 | ||
23 | #ifdef CONFIG_CPU_MICROMIPS | ||
24 | #define STORSIZE (LONGSIZE * 2) | ||
25 | #define STORMASK (STORSIZE - 1) | ||
26 | #define FILL64RG t8 | ||
27 | #define FILLPTRG t7 | ||
28 | #undef LONG_S | ||
29 | #define LONG_S LONG_SP | ||
30 | #else | ||
31 | #define STORSIZE LONGSIZE | ||
32 | #define STORMASK LONGMASK | ||
33 | #define FILL64RG a1 | ||
34 | #define FILLPTRG t0 | ||
35 | #endif | ||
36 | |||
22 | #define EX(insn,reg,addr,handler) \ | 37 | #define EX(insn,reg,addr,handler) \ |
23 | 9: insn reg, addr; \ | 38 | 9: insn reg, addr; \ |
24 | .section __ex_table,"a"; \ | 39 | .section __ex_table,"a"; \ |
@@ -26,23 +41,25 @@ | |||
26 | .previous | 41 | .previous |
27 | 42 | ||
28 | .macro f_fill64 dst, offset, val, fixup | 43 | .macro f_fill64 dst, offset, val, fixup |
29 | EX(LONG_S, \val, (\offset + 0 * LONGSIZE)(\dst), \fixup) | 44 | EX(LONG_S, \val, (\offset + 0 * STORSIZE)(\dst), \fixup) |
30 | EX(LONG_S, \val, (\offset + 1 * LONGSIZE)(\dst), \fixup) | 45 | EX(LONG_S, \val, (\offset + 1 * STORSIZE)(\dst), \fixup) |
31 | EX(LONG_S, \val, (\offset + 2 * LONGSIZE)(\dst), \fixup) | 46 | EX(LONG_S, \val, (\offset + 2 * STORSIZE)(\dst), \fixup) |
32 | EX(LONG_S, \val, (\offset + 3 * LONGSIZE)(\dst), \fixup) | 47 | EX(LONG_S, \val, (\offset + 3 * STORSIZE)(\dst), \fixup) |
33 | EX(LONG_S, \val, (\offset + 4 * LONGSIZE)(\dst), \fixup) | 48 | #if ((defined(CONFIG_CPU_MICROMIPS) && (LONGSIZE == 4)) || !defined(CONFIG_CPU_MICROMIPS)) |
34 | EX(LONG_S, \val, (\offset + 5 * LONGSIZE)(\dst), \fixup) | 49 | EX(LONG_S, \val, (\offset + 4 * STORSIZE)(\dst), \fixup) |
35 | EX(LONG_S, \val, (\offset + 6 * LONGSIZE)(\dst), \fixup) | 50 | EX(LONG_S, \val, (\offset + 5 * STORSIZE)(\dst), \fixup) |
36 | EX(LONG_S, \val, (\offset + 7 * LONGSIZE)(\dst), \fixup) | 51 | EX(LONG_S, \val, (\offset + 6 * STORSIZE)(\dst), \fixup) |
37 | #if LONGSIZE == 4 | 52 | EX(LONG_S, \val, (\offset + 7 * STORSIZE)(\dst), \fixup) |
38 | EX(LONG_S, \val, (\offset + 8 * LONGSIZE)(\dst), \fixup) | 53 | #endif |
39 | EX(LONG_S, \val, (\offset + 9 * LONGSIZE)(\dst), \fixup) | 54 | #if (!defined(CONFIG_CPU_MICROMIPS) && (LONGSIZE == 4)) |
40 | EX(LONG_S, \val, (\offset + 10 * LONGSIZE)(\dst), \fixup) | 55 | EX(LONG_S, \val, (\offset + 8 * STORSIZE)(\dst), \fixup) |
41 | EX(LONG_S, \val, (\offset + 11 * LONGSIZE)(\dst), \fixup) | 56 | EX(LONG_S, \val, (\offset + 9 * STORSIZE)(\dst), \fixup) |
42 | EX(LONG_S, \val, (\offset + 12 * LONGSIZE)(\dst), \fixup) | 57 | EX(LONG_S, \val, (\offset + 10 * STORSIZE)(\dst), \fixup) |
43 | EX(LONG_S, \val, (\offset + 13 * LONGSIZE)(\dst), \fixup) | 58 | EX(LONG_S, \val, (\offset + 11 * STORSIZE)(\dst), \fixup) |
44 | EX(LONG_S, \val, (\offset + 14 * LONGSIZE)(\dst), \fixup) | 59 | EX(LONG_S, \val, (\offset + 12 * STORSIZE)(\dst), \fixup) |
45 | EX(LONG_S, \val, (\offset + 15 * LONGSIZE)(\dst), \fixup) | 60 | EX(LONG_S, \val, (\offset + 13 * STORSIZE)(\dst), \fixup) |
61 | EX(LONG_S, \val, (\offset + 14 * STORSIZE)(\dst), \fixup) | ||
62 | EX(LONG_S, \val, (\offset + 15 * STORSIZE)(\dst), \fixup) | ||
46 | #endif | 63 | #endif |
47 | .endm | 64 | .endm |
48 | 65 | ||
@@ -71,16 +88,20 @@ LEAF(memset) | |||
71 | 1: | 88 | 1: |
72 | 89 | ||
73 | FEXPORT(__bzero) | 90 | FEXPORT(__bzero) |
74 | sltiu t0, a2, LONGSIZE /* very small region? */ | 91 | sltiu t0, a2, STORSIZE /* very small region? */ |
75 | bnez t0, .Lsmall_memset | 92 | bnez t0, .Lsmall_memset |
76 | andi t0, a0, LONGMASK /* aligned? */ | 93 | andi t0, a0, STORMASK /* aligned? */ |
77 | 94 | ||
95 | #ifdef CONFIG_CPU_MICROMIPS | ||
96 | move t8, a1 /* used by 'swp' instruction */ | ||
97 | move t9, a1 | ||
98 | #endif | ||
78 | #ifndef CONFIG_CPU_DADDI_WORKAROUNDS | 99 | #ifndef CONFIG_CPU_DADDI_WORKAROUNDS |
79 | beqz t0, 1f | 100 | beqz t0, 1f |
80 | PTR_SUBU t0, LONGSIZE /* alignment in bytes */ | 101 | PTR_SUBU t0, STORSIZE /* alignment in bytes */ |
81 | #else | 102 | #else |
82 | .set noat | 103 | .set noat |
83 | li AT, LONGSIZE | 104 | li AT, STORSIZE |
84 | beqz t0, 1f | 105 | beqz t0, 1f |
85 | PTR_SUBU t0, AT /* alignment in bytes */ | 106 | PTR_SUBU t0, AT /* alignment in bytes */ |
86 | .set at | 107 | .set at |
@@ -99,24 +120,27 @@ FEXPORT(__bzero) | |||
99 | 1: ori t1, a2, 0x3f /* # of full blocks */ | 120 | 1: ori t1, a2, 0x3f /* # of full blocks */ |
100 | xori t1, 0x3f | 121 | xori t1, 0x3f |
101 | beqz t1, .Lmemset_partial /* no block to fill */ | 122 | beqz t1, .Lmemset_partial /* no block to fill */ |
102 | andi t0, a2, 0x40-LONGSIZE | 123 | andi t0, a2, 0x40-STORSIZE |
103 | 124 | ||
104 | PTR_ADDU t1, a0 /* end address */ | 125 | PTR_ADDU t1, a0 /* end address */ |
105 | .set reorder | 126 | .set reorder |
106 | 1: PTR_ADDIU a0, 64 | 127 | 1: PTR_ADDIU a0, 64 |
107 | R10KCBARRIER(0(ra)) | 128 | R10KCBARRIER(0(ra)) |
108 | f_fill64 a0, -64, a1, .Lfwd_fixup | 129 | f_fill64 a0, -64, FILL64RG, .Lfwd_fixup |
109 | bne t1, a0, 1b | 130 | bne t1, a0, 1b |
110 | .set noreorder | 131 | .set noreorder |
111 | 132 | ||
112 | .Lmemset_partial: | 133 | .Lmemset_partial: |
113 | R10KCBARRIER(0(ra)) | 134 | R10KCBARRIER(0(ra)) |
114 | PTR_LA t1, 2f /* where to start */ | 135 | PTR_LA t1, 2f /* where to start */ |
136 | #ifdef CONFIG_CPU_MICROMIPS | ||
137 | LONG_SRL t7, t0, 1 | ||
138 | #endif | ||
115 | #if LONGSIZE == 4 | 139 | #if LONGSIZE == 4 |
116 | PTR_SUBU t1, t0 | 140 | PTR_SUBU t1, FILLPTRG |
117 | #else | 141 | #else |
118 | .set noat | 142 | .set noat |
119 | LONG_SRL AT, t0, 1 | 143 | LONG_SRL AT, FILLPTRG, 1 |
120 | PTR_SUBU t1, AT | 144 | PTR_SUBU t1, AT |
121 | .set at | 145 | .set at |
122 | #endif | 146 | #endif |
@@ -126,9 +150,9 @@ FEXPORT(__bzero) | |||
126 | .set push | 150 | .set push |
127 | .set noreorder | 151 | .set noreorder |
128 | .set nomacro | 152 | .set nomacro |
129 | f_fill64 a0, -64, a1, .Lpartial_fixup /* ... but first do longs ... */ | 153 | f_fill64 a0, -64, FILL64RG, .Lpartial_fixup /* ... but first do longs ... */ |
130 | 2: .set pop | 154 | 2: .set pop |
131 | andi a2, LONGMASK /* At most one long to go */ | 155 | andi a2, STORMASK /* At most one long to go */ |
132 | 156 | ||
133 | beqz a2, 1f | 157 | beqz a2, 1f |
134 | PTR_ADDU a0, a2 /* What's left */ | 158 | PTR_ADDU a0, a2 /* What's left */ |
@@ -169,7 +193,7 @@ FEXPORT(__bzero) | |||
169 | 193 | ||
170 | .Lpartial_fixup: | 194 | .Lpartial_fixup: |
171 | PTR_L t0, TI_TASK($28) | 195 | PTR_L t0, TI_TASK($28) |
172 | andi a2, LONGMASK | 196 | andi a2, STORMASK |
173 | LONG_L t0, THREAD_BUADDR(t0) | 197 | LONG_L t0, THREAD_BUADDR(t0) |
174 | LONG_ADDU a2, t1 | 198 | LONG_ADDU a2, t1 |
175 | jr ra | 199 | jr ra |
@@ -177,4 +201,4 @@ FEXPORT(__bzero) | |||
177 | 201 | ||
178 | .Llast_fixup: | 202 | .Llast_fixup: |
179 | jr ra | 203 | jr ra |
180 | andi v1, a2, LONGMASK | 204 | andi v1, a2, STORMASK |
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c index 91615c2ef0cf..8327698b9937 100644 --- a/arch/mips/lib/r3k_dump_tlb.c +++ b/arch/mips/lib/r3k_dump_tlb.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | 10 | ||
11 | #include <asm/mipsregs.h> | 11 | #include <asm/mipsregs.h> |
12 | #include <asm/mmu_context.h> | ||
12 | #include <asm/page.h> | 13 | #include <asm/page.h> |
13 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
14 | #include <asm/tlbdebug.h> | 15 | #include <asm/tlbdebug.h> |
@@ -21,7 +22,7 @@ static void dump_tlb(int first, int last) | |||
21 | unsigned int asid; | 22 | unsigned int asid; |
22 | unsigned long entryhi, entrylo0; | 23 | unsigned long entryhi, entrylo0; |
23 | 24 | ||
24 | asid = read_c0_entryhi() & 0xfc0; | 25 | asid = ASID_MASK(read_c0_entryhi()); |
25 | 26 | ||
26 | for (i = first; i <= last; i++) { | 27 | for (i = first; i <= last; i++) { |
27 | write_c0_index(i<<8); | 28 | write_c0_index(i<<8); |
@@ -35,7 +36,7 @@ static void dump_tlb(int first, int last) | |||
35 | 36 | ||
36 | /* Unused entries have a virtual address of KSEG0. */ | 37 | /* Unused entries have a virtual address of KSEG0. */ |
37 | if ((entryhi & 0xffffe000) != 0x80000000 | 38 | if ((entryhi & 0xffffe000) != 0x80000000 |
38 | && (entryhi & 0xfc0) == asid) { | 39 | && (ASID_MASK(entryhi) == asid)) { |
39 | /* | 40 | /* |
40 | * Only print entries in use | 41 | * Only print entries in use |
41 | */ | 42 | */ |
@@ -44,7 +45,7 @@ static void dump_tlb(int first, int last) | |||
44 | printk("va=%08lx asid=%08lx" | 45 | printk("va=%08lx asid=%08lx" |
45 | " [pa=%06lx n=%d d=%d v=%d g=%d]", | 46 | " [pa=%06lx n=%d d=%d v=%d g=%d]", |
46 | (entryhi & 0xffffe000), | 47 | (entryhi & 0xffffe000), |
47 | entryhi & 0xfc0, | 48 | ASID_MASK(entryhi), |
48 | entrylo0 & PAGE_MASK, | 49 | entrylo0 & PAGE_MASK, |
49 | (entrylo0 & (1 << 11)) ? 1 : 0, | 50 | (entrylo0 & (1 << 11)) ? 1 : 0, |
50 | (entrylo0 & (1 << 10)) ? 1 : 0, | 51 | (entrylo0 & (1 << 10)) ? 1 : 0, |
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S index fdbb970f670d..e362dcdc69d1 100644 --- a/arch/mips/lib/strlen_user.S +++ b/arch/mips/lib/strlen_user.S | |||
@@ -3,8 +3,9 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (c) 1996, 1998, 1999, 2004 by Ralf Baechle | 6 | * Copyright (C) 1996, 1998, 1999, 2004 by Ralf Baechle |
7 | * Copyright (c) 1999 Silicon Graphics, Inc. | 7 | * Copyright (C) 1999 Silicon Graphics, Inc. |
8 | * Copyright (C) 2011 MIPS Technologies, Inc. | ||
8 | */ | 9 | */ |
9 | #include <asm/asm.h> | 10 | #include <asm/asm.h> |
10 | #include <asm/asm-offsets.h> | 11 | #include <asm/asm-offsets.h> |
@@ -28,9 +29,9 @@ LEAF(__strlen_user_asm) | |||
28 | 29 | ||
29 | FEXPORT(__strlen_user_nocheck_asm) | 30 | FEXPORT(__strlen_user_nocheck_asm) |
30 | move v0, a0 | 31 | move v0, a0 |
31 | 1: EX(lb, t0, (v0), .Lfault) | 32 | 1: EX(lbu, v1, (v0), .Lfault) |
32 | PTR_ADDIU v0, 1 | 33 | PTR_ADDIU v0, 1 |
33 | bnez t0, 1b | 34 | bnez v1, 1b |
34 | PTR_SUBU v0, a0 | 35 | PTR_SUBU v0, a0 |
35 | jr ra | 36 | jr ra |
36 | END(__strlen_user_asm) | 37 | END(__strlen_user_asm) |
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S index bad539487503..92870b6b53ea 100644 --- a/arch/mips/lib/strncpy_user.S +++ b/arch/mips/lib/strncpy_user.S | |||
@@ -3,7 +3,8 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (c) 1996, 1999 by Ralf Baechle | 6 | * Copyright (C) 1996, 1999 by Ralf Baechle |
7 | * Copyright (C) 2011 MIPS Technologies, Inc. | ||
7 | */ | 8 | */ |
8 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
9 | #include <asm/asm.h> | 10 | #include <asm/asm.h> |
@@ -33,26 +34,27 @@ LEAF(__strncpy_from_user_asm) | |||
33 | bnez v0, .Lfault | 34 | bnez v0, .Lfault |
34 | 35 | ||
35 | FEXPORT(__strncpy_from_user_nocheck_asm) | 36 | FEXPORT(__strncpy_from_user_nocheck_asm) |
36 | move v0, zero | ||
37 | move v1, a1 | ||
38 | .set noreorder | 37 | .set noreorder |
39 | 1: EX(lbu, t0, (v1), .Lfault) | 38 | move t0, zero |
39 | move v1, a1 | ||
40 | 1: EX(lbu, v0, (v1), .Lfault) | ||
40 | PTR_ADDIU v1, 1 | 41 | PTR_ADDIU v1, 1 |
41 | R10KCBARRIER(0(ra)) | 42 | R10KCBARRIER(0(ra)) |
42 | beqz t0, 2f | 43 | beqz v0, 2f |
43 | sb t0, (a0) | 44 | sb v0, (a0) |
44 | PTR_ADDIU v0, 1 | 45 | PTR_ADDIU t0, 1 |
45 | .set reorder | 46 | bne t0, a2, 1b |
46 | PTR_ADDIU a0, 1 | 47 | PTR_ADDIU a0, 1 |
47 | bne v0, a2, 1b | 48 | 2: PTR_ADDU v0, a1, t0 |
48 | 2: PTR_ADDU t0, a1, v0 | 49 | xor v0, a1 |
49 | xor t0, a1 | 50 | bltz v0, .Lfault |
50 | bltz t0, .Lfault | 51 | nop |
51 | jr ra # return n | 52 | jr ra # return n |
53 | move v0, t0 | ||
52 | END(__strncpy_from_user_asm) | 54 | END(__strncpy_from_user_asm) |
53 | 55 | ||
54 | .Lfault: li v0, -EFAULT | 56 | .Lfault: jr ra |
55 | jr ra | 57 | li v0, -EFAULT |
56 | 58 | ||
57 | .section __ex_table,"a" | 59 | .section __ex_table,"a" |
58 | PTR 1b, .Lfault | 60 | PTR 1b, .Lfault |
diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S index beea03c8c0ce..fcacea5e61f1 100644 --- a/arch/mips/lib/strnlen_user.S +++ b/arch/mips/lib/strnlen_user.S | |||
@@ -35,7 +35,7 @@ FEXPORT(__strnlen_user_nocheck_asm) | |||
35 | PTR_ADDU a1, a0 # stop pointer | 35 | PTR_ADDU a1, a0 # stop pointer |
36 | 1: beq v0, a1, 1f # limit reached? | 36 | 1: beq v0, a1, 1f # limit reached? |
37 | EX(lb, t0, (v0), .Lfault) | 37 | EX(lb, t0, (v0), .Lfault) |
38 | PTR_ADDU v0, 1 | 38 | PTR_ADDIU v0, 1 |
39 | bnez t0, 1b | 39 | bnez t0, 1b |
40 | 1: PTR_SUBU v0, a0 | 40 | 1: PTR_SUBU v0, a0 |
41 | jr ra | 41 | jr ra |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index afb5a0bcf7a5..f03771900813 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/signal.h> | 45 | #include <asm/signal.h> |
46 | #include <asm/mipsregs.h> | 46 | #include <asm/mipsregs.h> |
47 | #include <asm/fpu_emulator.h> | 47 | #include <asm/fpu_emulator.h> |
48 | #include <asm/fpu.h> | ||
48 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
49 | #include <asm/branch.h> | 50 | #include <asm/branch.h> |
50 | 51 | ||
@@ -81,6 +82,11 @@ DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); | |||
81 | /* Determine rounding mode from the RM bits of the FCSR */ | 82 | /* Determine rounding mode from the RM bits of the FCSR */ |
82 | #define modeindex(v) ((v) & FPU_CSR_RM) | 83 | #define modeindex(v) ((v) & FPU_CSR_RM) |
83 | 84 | ||
85 | /* microMIPS bitfields */ | ||
86 | #define MM_POOL32A_MINOR_MASK 0x3f | ||
87 | #define MM_POOL32A_MINOR_SHIFT 0x6 | ||
88 | #define MM_MIPS32_COND_FC 0x30 | ||
89 | |||
84 | /* Convert Mips rounding mode (0..3) to IEEE library modes. */ | 90 | /* Convert Mips rounding mode (0..3) to IEEE library modes. */ |
85 | static const unsigned char ieee_rm[4] = { | 91 | static const unsigned char ieee_rm[4] = { |
86 | [FPU_CSR_RN] = IEEE754_RN, | 92 | [FPU_CSR_RN] = IEEE754_RN, |
@@ -110,6 +116,556 @@ static const unsigned int fpucondbit[8] = { | |||
110 | }; | 116 | }; |
111 | #endif | 117 | #endif |
112 | 118 | ||
119 | /* (microMIPS) Convert 16-bit register encoding to 32-bit register encoding. */ | ||
120 | static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7}; | ||
121 | |||
122 | /* (microMIPS) Convert certain microMIPS instructions to MIPS32 format. */ | ||
123 | static const int sd_format[] = {16, 17, 0, 0, 0, 0, 0, 0}; | ||
124 | static const int sdps_format[] = {16, 17, 22, 0, 0, 0, 0, 0}; | ||
125 | static const int dwl_format[] = {17, 20, 21, 0, 0, 0, 0, 0}; | ||
126 | static const int swl_format[] = {16, 20, 21, 0, 0, 0, 0, 0}; | ||
127 | |||
128 | /* | ||
129 | * This functions translates a 32-bit microMIPS instruction | ||
130 | * into a 32-bit MIPS32 instruction. Returns 0 on success | ||
131 | * and SIGILL otherwise. | ||
132 | */ | ||
133 | static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr) | ||
134 | { | ||
135 | union mips_instruction insn = *insn_ptr; | ||
136 | union mips_instruction mips32_insn = insn; | ||
137 | int func, fmt, op; | ||
138 | |||
139 | switch (insn.mm_i_format.opcode) { | ||
140 | case mm_ldc132_op: | ||
141 | mips32_insn.mm_i_format.opcode = ldc1_op; | ||
142 | mips32_insn.mm_i_format.rt = insn.mm_i_format.rs; | ||
143 | mips32_insn.mm_i_format.rs = insn.mm_i_format.rt; | ||
144 | break; | ||
145 | case mm_lwc132_op: | ||
146 | mips32_insn.mm_i_format.opcode = lwc1_op; | ||
147 | mips32_insn.mm_i_format.rt = insn.mm_i_format.rs; | ||
148 | mips32_insn.mm_i_format.rs = insn.mm_i_format.rt; | ||
149 | break; | ||
150 | case mm_sdc132_op: | ||
151 | mips32_insn.mm_i_format.opcode = sdc1_op; | ||
152 | mips32_insn.mm_i_format.rt = insn.mm_i_format.rs; | ||
153 | mips32_insn.mm_i_format.rs = insn.mm_i_format.rt; | ||
154 | break; | ||
155 | case mm_swc132_op: | ||
156 | mips32_insn.mm_i_format.opcode = swc1_op; | ||
157 | mips32_insn.mm_i_format.rt = insn.mm_i_format.rs; | ||
158 | mips32_insn.mm_i_format.rs = insn.mm_i_format.rt; | ||
159 | break; | ||
160 | case mm_pool32i_op: | ||
161 | /* NOTE: offset is << by 1 if in microMIPS mode. */ | ||
162 | if ((insn.mm_i_format.rt == mm_bc1f_op) || | ||
163 | (insn.mm_i_format.rt == mm_bc1t_op)) { | ||
164 | mips32_insn.fb_format.opcode = cop1_op; | ||
165 | mips32_insn.fb_format.bc = bc_op; | ||
166 | mips32_insn.fb_format.flag = | ||
167 | (insn.mm_i_format.rt == mm_bc1t_op) ? 1 : 0; | ||
168 | } else | ||
169 | return SIGILL; | ||
170 | break; | ||
171 | case mm_pool32f_op: | ||
172 | switch (insn.mm_fp0_format.func) { | ||
173 | case mm_32f_01_op: | ||
174 | case mm_32f_11_op: | ||
175 | case mm_32f_02_op: | ||
176 | case mm_32f_12_op: | ||
177 | case mm_32f_41_op: | ||
178 | case mm_32f_51_op: | ||
179 | case mm_32f_42_op: | ||
180 | case mm_32f_52_op: | ||
181 | op = insn.mm_fp0_format.func; | ||
182 | if (op == mm_32f_01_op) | ||
183 | func = madd_s_op; | ||
184 | else if (op == mm_32f_11_op) | ||
185 | func = madd_d_op; | ||
186 | else if (op == mm_32f_02_op) | ||
187 | func = nmadd_s_op; | ||
188 | else if (op == mm_32f_12_op) | ||
189 | func = nmadd_d_op; | ||
190 | else if (op == mm_32f_41_op) | ||
191 | func = msub_s_op; | ||
192 | else if (op == mm_32f_51_op) | ||
193 | func = msub_d_op; | ||
194 | else if (op == mm_32f_42_op) | ||
195 | func = nmsub_s_op; | ||
196 | else | ||
197 | func = nmsub_d_op; | ||
198 | mips32_insn.fp6_format.opcode = cop1x_op; | ||
199 | mips32_insn.fp6_format.fr = insn.mm_fp6_format.fr; | ||
200 | mips32_insn.fp6_format.ft = insn.mm_fp6_format.ft; | ||
201 | mips32_insn.fp6_format.fs = insn.mm_fp6_format.fs; | ||
202 | mips32_insn.fp6_format.fd = insn.mm_fp6_format.fd; | ||
203 | mips32_insn.fp6_format.func = func; | ||
204 | break; | ||
205 | case mm_32f_10_op: | ||
206 | func = -1; /* Invalid */ | ||
207 | op = insn.mm_fp5_format.op & 0x7; | ||
208 | if (op == mm_ldxc1_op) | ||
209 | func = ldxc1_op; | ||
210 | else if (op == mm_sdxc1_op) | ||
211 | func = sdxc1_op; | ||
212 | else if (op == mm_lwxc1_op) | ||
213 | func = lwxc1_op; | ||
214 | else if (op == mm_swxc1_op) | ||
215 | func = swxc1_op; | ||
216 | |||
217 | if (func != -1) { | ||
218 | mips32_insn.r_format.opcode = cop1x_op; | ||
219 | mips32_insn.r_format.rs = | ||
220 | insn.mm_fp5_format.base; | ||
221 | mips32_insn.r_format.rt = | ||
222 | insn.mm_fp5_format.index; | ||
223 | mips32_insn.r_format.rd = 0; | ||
224 | mips32_insn.r_format.re = insn.mm_fp5_format.fd; | ||
225 | mips32_insn.r_format.func = func; | ||
226 | } else | ||
227 | return SIGILL; | ||
228 | break; | ||
229 | case mm_32f_40_op: | ||
230 | op = -1; /* Invalid */ | ||
231 | if (insn.mm_fp2_format.op == mm_fmovt_op) | ||
232 | op = 1; | ||
233 | else if (insn.mm_fp2_format.op == mm_fmovf_op) | ||
234 | op = 0; | ||
235 | if (op != -1) { | ||
236 | mips32_insn.fp0_format.opcode = cop1_op; | ||
237 | mips32_insn.fp0_format.fmt = | ||
238 | sdps_format[insn.mm_fp2_format.fmt]; | ||
239 | mips32_insn.fp0_format.ft = | ||
240 | (insn.mm_fp2_format.cc<<2) + op; | ||
241 | mips32_insn.fp0_format.fs = | ||
242 | insn.mm_fp2_format.fs; | ||
243 | mips32_insn.fp0_format.fd = | ||
244 | insn.mm_fp2_format.fd; | ||
245 | mips32_insn.fp0_format.func = fmovc_op; | ||
246 | } else | ||
247 | return SIGILL; | ||
248 | break; | ||
249 | case mm_32f_60_op: | ||
250 | func = -1; /* Invalid */ | ||
251 | if (insn.mm_fp0_format.op == mm_fadd_op) | ||
252 | func = fadd_op; | ||
253 | else if (insn.mm_fp0_format.op == mm_fsub_op) | ||
254 | func = fsub_op; | ||
255 | else if (insn.mm_fp0_format.op == mm_fmul_op) | ||
256 | func = fmul_op; | ||
257 | else if (insn.mm_fp0_format.op == mm_fdiv_op) | ||
258 | func = fdiv_op; | ||
259 | if (func != -1) { | ||
260 | mips32_insn.fp0_format.opcode = cop1_op; | ||
261 | mips32_insn.fp0_format.fmt = | ||
262 | sdps_format[insn.mm_fp0_format.fmt]; | ||
263 | mips32_insn.fp0_format.ft = | ||
264 | insn.mm_fp0_format.ft; | ||
265 | mips32_insn.fp0_format.fs = | ||
266 | insn.mm_fp0_format.fs; | ||
267 | mips32_insn.fp0_format.fd = | ||
268 | insn.mm_fp0_format.fd; | ||
269 | mips32_insn.fp0_format.func = func; | ||
270 | } else | ||
271 | return SIGILL; | ||
272 | break; | ||
273 | case mm_32f_70_op: | ||
274 | func = -1; /* Invalid */ | ||
275 | if (insn.mm_fp0_format.op == mm_fmovn_op) | ||
276 | func = fmovn_op; | ||
277 | else if (insn.mm_fp0_format.op == mm_fmovz_op) | ||
278 | func = fmovz_op; | ||
279 | if (func != -1) { | ||
280 | mips32_insn.fp0_format.opcode = cop1_op; | ||
281 | mips32_insn.fp0_format.fmt = | ||
282 | sdps_format[insn.mm_fp0_format.fmt]; | ||
283 | mips32_insn.fp0_format.ft = | ||
284 | insn.mm_fp0_format.ft; | ||
285 | mips32_insn.fp0_format.fs = | ||
286 | insn.mm_fp0_format.fs; | ||
287 | mips32_insn.fp0_format.fd = | ||
288 | insn.mm_fp0_format.fd; | ||
289 | mips32_insn.fp0_format.func = func; | ||
290 | } else | ||
291 | return SIGILL; | ||
292 | break; | ||
293 | case mm_32f_73_op: /* POOL32FXF */ | ||
294 | switch (insn.mm_fp1_format.op) { | ||
295 | case mm_movf0_op: | ||
296 | case mm_movf1_op: | ||
297 | case mm_movt0_op: | ||
298 | case mm_movt1_op: | ||
299 | if ((insn.mm_fp1_format.op & 0x7f) == | ||
300 | mm_movf0_op) | ||
301 | op = 0; | ||
302 | else | ||
303 | op = 1; | ||
304 | mips32_insn.r_format.opcode = spec_op; | ||
305 | mips32_insn.r_format.rs = insn.mm_fp4_format.fs; | ||
306 | mips32_insn.r_format.rt = | ||
307 | (insn.mm_fp4_format.cc << 2) + op; | ||
308 | mips32_insn.r_format.rd = insn.mm_fp4_format.rt; | ||
309 | mips32_insn.r_format.re = 0; | ||
310 | mips32_insn.r_format.func = movc_op; | ||
311 | break; | ||
312 | case mm_fcvtd0_op: | ||
313 | case mm_fcvtd1_op: | ||
314 | case mm_fcvts0_op: | ||
315 | case mm_fcvts1_op: | ||
316 | if ((insn.mm_fp1_format.op & 0x7f) == | ||
317 | mm_fcvtd0_op) { | ||
318 | func = fcvtd_op; | ||
319 | fmt = swl_format[insn.mm_fp3_format.fmt]; | ||
320 | } else { | ||
321 | func = fcvts_op; | ||
322 | fmt = dwl_format[insn.mm_fp3_format.fmt]; | ||
323 | } | ||
324 | mips32_insn.fp0_format.opcode = cop1_op; | ||
325 | mips32_insn.fp0_format.fmt = fmt; | ||
326 | mips32_insn.fp0_format.ft = 0; | ||
327 | mips32_insn.fp0_format.fs = | ||
328 | insn.mm_fp3_format.fs; | ||
329 | mips32_insn.fp0_format.fd = | ||
330 | insn.mm_fp3_format.rt; | ||
331 | mips32_insn.fp0_format.func = func; | ||
332 | break; | ||
333 | case mm_fmov0_op: | ||
334 | case mm_fmov1_op: | ||
335 | case mm_fabs0_op: | ||
336 | case mm_fabs1_op: | ||
337 | case mm_fneg0_op: | ||
338 | case mm_fneg1_op: | ||
339 | if ((insn.mm_fp1_format.op & 0x7f) == | ||
340 | mm_fmov0_op) | ||
341 | func = fmov_op; | ||
342 | else if ((insn.mm_fp1_format.op & 0x7f) == | ||
343 | mm_fabs0_op) | ||
344 | func = fabs_op; | ||
345 | else | ||
346 | func = fneg_op; | ||
347 | mips32_insn.fp0_format.opcode = cop1_op; | ||
348 | mips32_insn.fp0_format.fmt = | ||
349 | sdps_format[insn.mm_fp3_format.fmt]; | ||
350 | mips32_insn.fp0_format.ft = 0; | ||
351 | mips32_insn.fp0_format.fs = | ||
352 | insn.mm_fp3_format.fs; | ||
353 | mips32_insn.fp0_format.fd = | ||
354 | insn.mm_fp3_format.rt; | ||
355 | mips32_insn.fp0_format.func = func; | ||
356 | break; | ||
357 | case mm_ffloorl_op: | ||
358 | case mm_ffloorw_op: | ||
359 | case mm_fceill_op: | ||
360 | case mm_fceilw_op: | ||
361 | case mm_ftruncl_op: | ||
362 | case mm_ftruncw_op: | ||
363 | case mm_froundl_op: | ||
364 | case mm_froundw_op: | ||
365 | case mm_fcvtl_op: | ||
366 | case mm_fcvtw_op: | ||
367 | if (insn.mm_fp1_format.op == mm_ffloorl_op) | ||
368 | func = ffloorl_op; | ||
369 | else if (insn.mm_fp1_format.op == mm_ffloorw_op) | ||
370 | func = ffloor_op; | ||
371 | else if (insn.mm_fp1_format.op == mm_fceill_op) | ||
372 | func = fceill_op; | ||
373 | else if (insn.mm_fp1_format.op == mm_fceilw_op) | ||
374 | func = fceil_op; | ||
375 | else if (insn.mm_fp1_format.op == mm_ftruncl_op) | ||
376 | func = ftruncl_op; | ||
377 | else if (insn.mm_fp1_format.op == mm_ftruncw_op) | ||
378 | func = ftrunc_op; | ||
379 | else if (insn.mm_fp1_format.op == mm_froundl_op) | ||
380 | func = froundl_op; | ||
381 | else if (insn.mm_fp1_format.op == mm_froundw_op) | ||
382 | func = fround_op; | ||
383 | else if (insn.mm_fp1_format.op == mm_fcvtl_op) | ||
384 | func = fcvtl_op; | ||
385 | else | ||
386 | func = fcvtw_op; | ||
387 | mips32_insn.fp0_format.opcode = cop1_op; | ||
388 | mips32_insn.fp0_format.fmt = | ||
389 | sd_format[insn.mm_fp1_format.fmt]; | ||
390 | mips32_insn.fp0_format.ft = 0; | ||
391 | mips32_insn.fp0_format.fs = | ||
392 | insn.mm_fp1_format.fs; | ||
393 | mips32_insn.fp0_format.fd = | ||
394 | insn.mm_fp1_format.rt; | ||
395 | mips32_insn.fp0_format.func = func; | ||
396 | break; | ||
397 | case mm_frsqrt_op: | ||
398 | case mm_fsqrt_op: | ||
399 | case mm_frecip_op: | ||
400 | if (insn.mm_fp1_format.op == mm_frsqrt_op) | ||
401 | func = frsqrt_op; | ||
402 | else if (insn.mm_fp1_format.op == mm_fsqrt_op) | ||
403 | func = fsqrt_op; | ||
404 | else | ||
405 | func = frecip_op; | ||
406 | mips32_insn.fp0_format.opcode = cop1_op; | ||
407 | mips32_insn.fp0_format.fmt = | ||
408 | sdps_format[insn.mm_fp1_format.fmt]; | ||
409 | mips32_insn.fp0_format.ft = 0; | ||
410 | mips32_insn.fp0_format.fs = | ||
411 | insn.mm_fp1_format.fs; | ||
412 | mips32_insn.fp0_format.fd = | ||
413 | insn.mm_fp1_format.rt; | ||
414 | mips32_insn.fp0_format.func = func; | ||
415 | break; | ||
416 | case mm_mfc1_op: | ||
417 | case mm_mtc1_op: | ||
418 | case mm_cfc1_op: | ||
419 | case mm_ctc1_op: | ||
420 | if (insn.mm_fp1_format.op == mm_mfc1_op) | ||
421 | op = mfc_op; | ||
422 | else if (insn.mm_fp1_format.op == mm_mtc1_op) | ||
423 | op = mtc_op; | ||
424 | else if (insn.mm_fp1_format.op == mm_cfc1_op) | ||
425 | op = cfc_op; | ||
426 | else | ||
427 | op = ctc_op; | ||
428 | mips32_insn.fp1_format.opcode = cop1_op; | ||
429 | mips32_insn.fp1_format.op = op; | ||
430 | mips32_insn.fp1_format.rt = | ||
431 | insn.mm_fp1_format.rt; | ||
432 | mips32_insn.fp1_format.fs = | ||
433 | insn.mm_fp1_format.fs; | ||
434 | mips32_insn.fp1_format.fd = 0; | ||
435 | mips32_insn.fp1_format.func = 0; | ||
436 | break; | ||
437 | default: | ||
438 | return SIGILL; | ||
439 | break; | ||
440 | } | ||
441 | break; | ||
442 | case mm_32f_74_op: /* c.cond.fmt */ | ||
443 | mips32_insn.fp0_format.opcode = cop1_op; | ||
444 | mips32_insn.fp0_format.fmt = | ||
445 | sdps_format[insn.mm_fp4_format.fmt]; | ||
446 | mips32_insn.fp0_format.ft = insn.mm_fp4_format.rt; | ||
447 | mips32_insn.fp0_format.fs = insn.mm_fp4_format.fs; | ||
448 | mips32_insn.fp0_format.fd = insn.mm_fp4_format.cc << 2; | ||
449 | mips32_insn.fp0_format.func = | ||
450 | insn.mm_fp4_format.cond | MM_MIPS32_COND_FC; | ||
451 | break; | ||
452 | default: | ||
453 | return SIGILL; | ||
454 | break; | ||
455 | } | ||
456 | break; | ||
457 | default: | ||
458 | return SIGILL; | ||
459 | break; | ||
460 | } | ||
461 | |||
462 | *insn_ptr = mips32_insn; | ||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, | ||
467 | unsigned long *contpc) | ||
468 | { | ||
469 | union mips_instruction insn = (union mips_instruction)dec_insn.insn; | ||
470 | int bc_false = 0; | ||
471 | unsigned int fcr31; | ||
472 | unsigned int bit; | ||
473 | |||
474 | switch (insn.mm_i_format.opcode) { | ||
475 | case mm_pool32a_op: | ||
476 | if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) == | ||
477 | mm_pool32axf_op) { | ||
478 | switch (insn.mm_i_format.simmediate >> | ||
479 | MM_POOL32A_MINOR_SHIFT) { | ||
480 | case mm_jalr_op: | ||
481 | case mm_jalrhb_op: | ||
482 | case mm_jalrs_op: | ||
483 | case mm_jalrshb_op: | ||
484 | if (insn.mm_i_format.rt != 0) /* Not mm_jr */ | ||
485 | regs->regs[insn.mm_i_format.rt] = | ||
486 | regs->cp0_epc + | ||
487 | dec_insn.pc_inc + | ||
488 | dec_insn.next_pc_inc; | ||
489 | *contpc = regs->regs[insn.mm_i_format.rs]; | ||
490 | return 1; | ||
491 | break; | ||
492 | } | ||
493 | } | ||
494 | break; | ||
495 | case mm_pool32i_op: | ||
496 | switch (insn.mm_i_format.rt) { | ||
497 | case mm_bltzals_op: | ||
498 | case mm_bltzal_op: | ||
499 | regs->regs[31] = regs->cp0_epc + | ||
500 | dec_insn.pc_inc + | ||
501 | dec_insn.next_pc_inc; | ||
502 | /* Fall through */ | ||
503 | case mm_bltz_op: | ||
504 | if ((long)regs->regs[insn.mm_i_format.rs] < 0) | ||
505 | *contpc = regs->cp0_epc + | ||
506 | dec_insn.pc_inc + | ||
507 | (insn.mm_i_format.simmediate << 1); | ||
508 | else | ||
509 | *contpc = regs->cp0_epc + | ||
510 | dec_insn.pc_inc + | ||
511 | dec_insn.next_pc_inc; | ||
512 | return 1; | ||
513 | break; | ||
514 | case mm_bgezals_op: | ||
515 | case mm_bgezal_op: | ||
516 | regs->regs[31] = regs->cp0_epc + | ||
517 | dec_insn.pc_inc + | ||
518 | dec_insn.next_pc_inc; | ||
519 | /* Fall through */ | ||
520 | case mm_bgez_op: | ||
521 | if ((long)regs->regs[insn.mm_i_format.rs] >= 0) | ||
522 | *contpc = regs->cp0_epc + | ||
523 | dec_insn.pc_inc + | ||
524 | (insn.mm_i_format.simmediate << 1); | ||
525 | else | ||
526 | *contpc = regs->cp0_epc + | ||
527 | dec_insn.pc_inc + | ||
528 | dec_insn.next_pc_inc; | ||
529 | return 1; | ||
530 | break; | ||
531 | case mm_blez_op: | ||
532 | if ((long)regs->regs[insn.mm_i_format.rs] <= 0) | ||
533 | *contpc = regs->cp0_epc + | ||
534 | dec_insn.pc_inc + | ||
535 | (insn.mm_i_format.simmediate << 1); | ||
536 | else | ||
537 | *contpc = regs->cp0_epc + | ||
538 | dec_insn.pc_inc + | ||
539 | dec_insn.next_pc_inc; | ||
540 | return 1; | ||
541 | break; | ||
542 | case mm_bgtz_op: | ||
543 | if ((long)regs->regs[insn.mm_i_format.rs] <= 0) | ||
544 | *contpc = regs->cp0_epc + | ||
545 | dec_insn.pc_inc + | ||
546 | (insn.mm_i_format.simmediate << 1); | ||
547 | else | ||
548 | *contpc = regs->cp0_epc + | ||
549 | dec_insn.pc_inc + | ||
550 | dec_insn.next_pc_inc; | ||
551 | return 1; | ||
552 | break; | ||
553 | case mm_bc2f_op: | ||
554 | case mm_bc1f_op: | ||
555 | bc_false = 1; | ||
556 | /* Fall through */ | ||
557 | case mm_bc2t_op: | ||
558 | case mm_bc1t_op: | ||
559 | preempt_disable(); | ||
560 | if (is_fpu_owner()) | ||
561 | asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); | ||
562 | else | ||
563 | fcr31 = current->thread.fpu.fcr31; | ||
564 | preempt_enable(); | ||
565 | |||
566 | if (bc_false) | ||
567 | fcr31 = ~fcr31; | ||
568 | |||
569 | bit = (insn.mm_i_format.rs >> 2); | ||
570 | bit += (bit != 0); | ||
571 | bit += 23; | ||
572 | if (fcr31 & (1 << bit)) | ||
573 | *contpc = regs->cp0_epc + | ||
574 | dec_insn.pc_inc + | ||
575 | (insn.mm_i_format.simmediate << 1); | ||
576 | else | ||
577 | *contpc = regs->cp0_epc + | ||
578 | dec_insn.pc_inc + dec_insn.next_pc_inc; | ||
579 | return 1; | ||
580 | break; | ||
581 | } | ||
582 | break; | ||
583 | case mm_pool16c_op: | ||
584 | switch (insn.mm_i_format.rt) { | ||
585 | case mm_jalr16_op: | ||
586 | case mm_jalrs16_op: | ||
587 | regs->regs[31] = regs->cp0_epc + | ||
588 | dec_insn.pc_inc + dec_insn.next_pc_inc; | ||
589 | /* Fall through */ | ||
590 | case mm_jr16_op: | ||
591 | *contpc = regs->regs[insn.mm_i_format.rs]; | ||
592 | return 1; | ||
593 | break; | ||
594 | } | ||
595 | break; | ||
596 | case mm_beqz16_op: | ||
597 | if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] == 0) | ||
598 | *contpc = regs->cp0_epc + | ||
599 | dec_insn.pc_inc + | ||
600 | (insn.mm_b1_format.simmediate << 1); | ||
601 | else | ||
602 | *contpc = regs->cp0_epc + | ||
603 | dec_insn.pc_inc + dec_insn.next_pc_inc; | ||
604 | return 1; | ||
605 | break; | ||
606 | case mm_bnez16_op: | ||
607 | if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0) | ||
608 | *contpc = regs->cp0_epc + | ||
609 | dec_insn.pc_inc + | ||
610 | (insn.mm_b1_format.simmediate << 1); | ||
611 | else | ||
612 | *contpc = regs->cp0_epc + | ||
613 | dec_insn.pc_inc + dec_insn.next_pc_inc; | ||
614 | return 1; | ||
615 | break; | ||
616 | case mm_b16_op: | ||
617 | *contpc = regs->cp0_epc + dec_insn.pc_inc + | ||
618 | (insn.mm_b0_format.simmediate << 1); | ||
619 | return 1; | ||
620 | break; | ||
621 | case mm_beq32_op: | ||
622 | if (regs->regs[insn.mm_i_format.rs] == | ||
623 | regs->regs[insn.mm_i_format.rt]) | ||
624 | *contpc = regs->cp0_epc + | ||
625 | dec_insn.pc_inc + | ||
626 | (insn.mm_i_format.simmediate << 1); | ||
627 | else | ||
628 | *contpc = regs->cp0_epc + | ||
629 | dec_insn.pc_inc + | ||
630 | dec_insn.next_pc_inc; | ||
631 | return 1; | ||
632 | break; | ||
633 | case mm_bne32_op: | ||
634 | if (regs->regs[insn.mm_i_format.rs] != | ||
635 | regs->regs[insn.mm_i_format.rt]) | ||
636 | *contpc = regs->cp0_epc + | ||
637 | dec_insn.pc_inc + | ||
638 | (insn.mm_i_format.simmediate << 1); | ||
639 | else | ||
640 | *contpc = regs->cp0_epc + | ||
641 | dec_insn.pc_inc + dec_insn.next_pc_inc; | ||
642 | return 1; | ||
643 | break; | ||
644 | case mm_jalx32_op: | ||
645 | regs->regs[31] = regs->cp0_epc + | ||
646 | dec_insn.pc_inc + dec_insn.next_pc_inc; | ||
647 | *contpc = regs->cp0_epc + dec_insn.pc_inc; | ||
648 | *contpc >>= 28; | ||
649 | *contpc <<= 28; | ||
650 | *contpc |= (insn.j_format.target << 2); | ||
651 | return 1; | ||
652 | break; | ||
653 | case mm_jals32_op: | ||
654 | case mm_jal32_op: | ||
655 | regs->regs[31] = regs->cp0_epc + | ||
656 | dec_insn.pc_inc + dec_insn.next_pc_inc; | ||
657 | /* Fall through */ | ||
658 | case mm_j32_op: | ||
659 | *contpc = regs->cp0_epc + dec_insn.pc_inc; | ||
660 | *contpc >>= 27; | ||
661 | *contpc <<= 27; | ||
662 | *contpc |= (insn.j_format.target << 1); | ||
663 | set_isa16_mode(*contpc); | ||
664 | return 1; | ||
665 | break; | ||
666 | } | ||
667 | return 0; | ||
668 | } | ||
113 | 669 | ||
114 | /* | 670 | /* |
115 | * Redundant with logic already in kernel/branch.c, | 671 | * Redundant with logic already in kernel/branch.c, |
@@ -117,53 +673,177 @@ static const unsigned int fpucondbit[8] = { | |||
117 | * a single subroutine should be used across both | 673 | * a single subroutine should be used across both |
118 | * modules. | 674 | * modules. |
119 | */ | 675 | */ |
120 | static int isBranchInstr(mips_instruction * i) | 676 | static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, |
677 | unsigned long *contpc) | ||
121 | { | 678 | { |
122 | switch (MIPSInst_OPCODE(*i)) { | 679 | union mips_instruction insn = (union mips_instruction)dec_insn.insn; |
680 | unsigned int fcr31; | ||
681 | unsigned int bit = 0; | ||
682 | |||
683 | switch (insn.i_format.opcode) { | ||
123 | case spec_op: | 684 | case spec_op: |
124 | switch (MIPSInst_FUNC(*i)) { | 685 | switch (insn.r_format.func) { |
125 | case jalr_op: | 686 | case jalr_op: |
687 | regs->regs[insn.r_format.rd] = | ||
688 | regs->cp0_epc + dec_insn.pc_inc + | ||
689 | dec_insn.next_pc_inc; | ||
690 | /* Fall through */ | ||
126 | case jr_op: | 691 | case jr_op: |
692 | *contpc = regs->regs[insn.r_format.rs]; | ||
127 | return 1; | 693 | return 1; |
694 | break; | ||
128 | } | 695 | } |
129 | break; | 696 | break; |
130 | |||
131 | case bcond_op: | 697 | case bcond_op: |
132 | switch (MIPSInst_RT(*i)) { | 698 | switch (insn.i_format.rt) { |
699 | case bltzal_op: | ||
700 | case bltzall_op: | ||
701 | regs->regs[31] = regs->cp0_epc + | ||
702 | dec_insn.pc_inc + | ||
703 | dec_insn.next_pc_inc; | ||
704 | /* Fall through */ | ||
133 | case bltz_op: | 705 | case bltz_op: |
134 | case bgez_op: | ||
135 | case bltzl_op: | 706 | case bltzl_op: |
136 | case bgezl_op: | 707 | if ((long)regs->regs[insn.i_format.rs] < 0) |
137 | case bltzal_op: | 708 | *contpc = regs->cp0_epc + |
709 | dec_insn.pc_inc + | ||
710 | (insn.i_format.simmediate << 2); | ||
711 | else | ||
712 | *contpc = regs->cp0_epc + | ||
713 | dec_insn.pc_inc + | ||
714 | dec_insn.next_pc_inc; | ||
715 | return 1; | ||
716 | break; | ||
138 | case bgezal_op: | 717 | case bgezal_op: |
139 | case bltzall_op: | ||
140 | case bgezall_op: | 718 | case bgezall_op: |
719 | regs->regs[31] = regs->cp0_epc + | ||
720 | dec_insn.pc_inc + | ||
721 | dec_insn.next_pc_inc; | ||
722 | /* Fall through */ | ||
723 | case bgez_op: | ||
724 | case bgezl_op: | ||
725 | if ((long)regs->regs[insn.i_format.rs] >= 0) | ||
726 | *contpc = regs->cp0_epc + | ||
727 | dec_insn.pc_inc + | ||
728 | (insn.i_format.simmediate << 2); | ||
729 | else | ||
730 | *contpc = regs->cp0_epc + | ||
731 | dec_insn.pc_inc + | ||
732 | dec_insn.next_pc_inc; | ||
141 | return 1; | 733 | return 1; |
734 | break; | ||
142 | } | 735 | } |
143 | break; | 736 | break; |
144 | |||
145 | case j_op: | ||
146 | case jal_op: | ||
147 | case jalx_op: | 737 | case jalx_op: |
738 | set_isa16_mode(bit); | ||
739 | case jal_op: | ||
740 | regs->regs[31] = regs->cp0_epc + | ||
741 | dec_insn.pc_inc + | ||
742 | dec_insn.next_pc_inc; | ||
743 | /* Fall through */ | ||
744 | case j_op: | ||
745 | *contpc = regs->cp0_epc + dec_insn.pc_inc; | ||
746 | *contpc >>= 28; | ||
747 | *contpc <<= 28; | ||
748 | *contpc |= (insn.j_format.target << 2); | ||
749 | /* Set microMIPS mode bit: XOR for jalx. */ | ||
750 | *contpc ^= bit; | ||
751 | return 1; | ||
752 | break; | ||
148 | case beq_op: | 753 | case beq_op: |
149 | case bne_op: | ||
150 | case blez_op: | ||
151 | case bgtz_op: | ||
152 | case beql_op: | 754 | case beql_op: |
755 | if (regs->regs[insn.i_format.rs] == | ||
756 | regs->regs[insn.i_format.rt]) | ||
757 | *contpc = regs->cp0_epc + | ||
758 | dec_insn.pc_inc + | ||
759 | (insn.i_format.simmediate << 2); | ||
760 | else | ||
761 | *contpc = regs->cp0_epc + | ||
762 | dec_insn.pc_inc + | ||
763 | dec_insn.next_pc_inc; | ||
764 | return 1; | ||
765 | break; | ||
766 | case bne_op: | ||
153 | case bnel_op: | 767 | case bnel_op: |
768 | if (regs->regs[insn.i_format.rs] != | ||
769 | regs->regs[insn.i_format.rt]) | ||
770 | *contpc = regs->cp0_epc + | ||
771 | dec_insn.pc_inc + | ||
772 | (insn.i_format.simmediate << 2); | ||
773 | else | ||
774 | *contpc = regs->cp0_epc + | ||
775 | dec_insn.pc_inc + | ||
776 | dec_insn.next_pc_inc; | ||
777 | return 1; | ||
778 | break; | ||
779 | case blez_op: | ||
154 | case blezl_op: | 780 | case blezl_op: |
781 | if ((long)regs->regs[insn.i_format.rs] <= 0) | ||
782 | *contpc = regs->cp0_epc + | ||
783 | dec_insn.pc_inc + | ||
784 | (insn.i_format.simmediate << 2); | ||
785 | else | ||
786 | *contpc = regs->cp0_epc + | ||
787 | dec_insn.pc_inc + | ||
788 | dec_insn.next_pc_inc; | ||
789 | return 1; | ||
790 | break; | ||
791 | case bgtz_op: | ||
155 | case bgtzl_op: | 792 | case bgtzl_op: |
793 | if ((long)regs->regs[insn.i_format.rs] > 0) | ||
794 | *contpc = regs->cp0_epc + | ||
795 | dec_insn.pc_inc + | ||
796 | (insn.i_format.simmediate << 2); | ||
797 | else | ||
798 | *contpc = regs->cp0_epc + | ||
799 | dec_insn.pc_inc + | ||
800 | dec_insn.next_pc_inc; | ||
156 | return 1; | 801 | return 1; |
157 | 802 | break; | |
158 | case cop0_op: | 803 | case cop0_op: |
159 | case cop1_op: | 804 | case cop1_op: |
160 | case cop2_op: | 805 | case cop2_op: |
161 | case cop1x_op: | 806 | case cop1x_op: |
162 | if (MIPSInst_RS(*i) == bc_op) | 807 | if (insn.i_format.rs == bc_op) { |
163 | return 1; | 808 | preempt_disable(); |
809 | if (is_fpu_owner()) | ||
810 | asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); | ||
811 | else | ||
812 | fcr31 = current->thread.fpu.fcr31; | ||
813 | preempt_enable(); | ||
814 | |||
815 | bit = (insn.i_format.rt >> 2); | ||
816 | bit += (bit != 0); | ||
817 | bit += 23; | ||
818 | switch (insn.i_format.rt & 3) { | ||
819 | case 0: /* bc1f */ | ||
820 | case 2: /* bc1fl */ | ||
821 | if (~fcr31 & (1 << bit)) | ||
822 | *contpc = regs->cp0_epc + | ||
823 | dec_insn.pc_inc + | ||
824 | (insn.i_format.simmediate << 2); | ||
825 | else | ||
826 | *contpc = regs->cp0_epc + | ||
827 | dec_insn.pc_inc + | ||
828 | dec_insn.next_pc_inc; | ||
829 | return 1; | ||
830 | break; | ||
831 | case 1: /* bc1t */ | ||
832 | case 3: /* bc1tl */ | ||
833 | if (fcr31 & (1 << bit)) | ||
834 | *contpc = regs->cp0_epc + | ||
835 | dec_insn.pc_inc + | ||
836 | (insn.i_format.simmediate << 2); | ||
837 | else | ||
838 | *contpc = regs->cp0_epc + | ||
839 | dec_insn.pc_inc + | ||
840 | dec_insn.next_pc_inc; | ||
841 | return 1; | ||
842 | break; | ||
843 | } | ||
844 | } | ||
164 | break; | 845 | break; |
165 | } | 846 | } |
166 | |||
167 | return 0; | 847 | return 0; |
168 | } | 848 | } |
169 | 849 | ||
@@ -210,26 +890,23 @@ static inline int cop1_64bit(struct pt_regs *xcp) | |||
210 | */ | 890 | */ |
211 | 891 | ||
212 | static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | 892 | static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
213 | void *__user *fault_addr) | 893 | struct mm_decoded_insn dec_insn, void *__user *fault_addr) |
214 | { | 894 | { |
215 | mips_instruction ir; | 895 | mips_instruction ir; |
216 | unsigned long emulpc, contpc; | 896 | unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc; |
217 | unsigned int cond; | 897 | unsigned int cond; |
218 | 898 | int pc_inc; | |
219 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) { | ||
220 | MIPS_FPU_EMU_INC_STATS(errors); | ||
221 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
222 | return SIGBUS; | ||
223 | } | ||
224 | if (__get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) { | ||
225 | MIPS_FPU_EMU_INC_STATS(errors); | ||
226 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
227 | return SIGSEGV; | ||
228 | } | ||
229 | 899 | ||
230 | /* XXX NEC Vr54xx bug workaround */ | 900 | /* XXX NEC Vr54xx bug workaround */ |
231 | if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir)) | 901 | if (xcp->cp0_cause & CAUSEF_BD) { |
232 | xcp->cp0_cause &= ~CAUSEF_BD; | 902 | if (dec_insn.micro_mips_mode) { |
903 | if (!mm_isBranchInstr(xcp, dec_insn, &contpc)) | ||
904 | xcp->cp0_cause &= ~CAUSEF_BD; | ||
905 | } else { | ||
906 | if (!isBranchInstr(xcp, dec_insn, &contpc)) | ||
907 | xcp->cp0_cause &= ~CAUSEF_BD; | ||
908 | } | ||
909 | } | ||
233 | 910 | ||
234 | if (xcp->cp0_cause & CAUSEF_BD) { | 911 | if (xcp->cp0_cause & CAUSEF_BD) { |
235 | /* | 912 | /* |
@@ -244,32 +921,33 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
244 | * Linux MIPS branch emulator operates on context, updating the | 921 | * Linux MIPS branch emulator operates on context, updating the |
245 | * cp0_epc. | 922 | * cp0_epc. |
246 | */ | 923 | */ |
247 | emulpc = xcp->cp0_epc + 4; /* Snapshot emulation target */ | 924 | ir = dec_insn.next_insn; /* process delay slot instr */ |
925 | pc_inc = dec_insn.next_pc_inc; | ||
926 | } else { | ||
927 | ir = dec_insn.insn; /* process current instr */ | ||
928 | pc_inc = dec_insn.pc_inc; | ||
929 | } | ||
248 | 930 | ||
249 | if (__compute_return_epc(xcp) < 0) { | 931 | /* |
250 | #ifdef CP1DBG | 932 | * Since microMIPS FPU instructios are a subset of MIPS32 FPU |
251 | printk("failed to emulate branch at %p\n", | 933 | * instructions, we want to convert microMIPS FPU instructions |
252 | (void *) (xcp->cp0_epc)); | 934 | * into MIPS32 instructions so that we could reuse all of the |
253 | #endif | 935 | * FPU emulation code. |
936 | * | ||
937 | * NOTE: We cannot do this for branch instructions since they | ||
938 | * are not a subset. Example: Cannot emulate a 16-bit | ||
939 | * aligned target address with a MIPS32 instruction. | ||
940 | */ | ||
941 | if (dec_insn.micro_mips_mode) { | ||
942 | /* | ||
943 | * If next instruction is a 16-bit instruction, then it | ||
944 | * it cannot be a FPU instruction. This could happen | ||
945 | * since we can be called for non-FPU instructions. | ||
946 | */ | ||
947 | if ((pc_inc == 2) || | ||
948 | (microMIPS32_to_MIPS32((union mips_instruction *)&ir) | ||
949 | == SIGILL)) | ||
254 | return SIGILL; | 950 | return SIGILL; |
255 | } | ||
256 | if (!access_ok(VERIFY_READ, emulpc, sizeof(mips_instruction))) { | ||
257 | MIPS_FPU_EMU_INC_STATS(errors); | ||
258 | *fault_addr = (mips_instruction __user *)emulpc; | ||
259 | return SIGBUS; | ||
260 | } | ||
261 | if (__get_user(ir, (mips_instruction __user *) emulpc)) { | ||
262 | MIPS_FPU_EMU_INC_STATS(errors); | ||
263 | *fault_addr = (mips_instruction __user *)emulpc; | ||
264 | return SIGSEGV; | ||
265 | } | ||
266 | /* __compute_return_epc() will have updated cp0_epc */ | ||
267 | contpc = xcp->cp0_epc; | ||
268 | /* In order not to confuse ptrace() et al, tweak context */ | ||
269 | xcp->cp0_epc = emulpc - 4; | ||
270 | } else { | ||
271 | emulpc = xcp->cp0_epc; | ||
272 | contpc = xcp->cp0_epc + 4; | ||
273 | } | 951 | } |
274 | 952 | ||
275 | emul: | 953 | emul: |
@@ -474,22 +1152,35 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
474 | /* branch taken: emulate dslot | 1152 | /* branch taken: emulate dslot |
475 | * instruction | 1153 | * instruction |
476 | */ | 1154 | */ |
477 | xcp->cp0_epc += 4; | 1155 | xcp->cp0_epc += dec_insn.pc_inc; |
478 | contpc = (xcp->cp0_epc + | 1156 | |
479 | (MIPSInst_SIMM(ir) << 2)); | 1157 | contpc = MIPSInst_SIMM(ir); |
480 | 1158 | ir = dec_insn.next_insn; | |
481 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, | 1159 | if (dec_insn.micro_mips_mode) { |
482 | sizeof(mips_instruction))) { | 1160 | contpc = (xcp->cp0_epc + (contpc << 1)); |
483 | MIPS_FPU_EMU_INC_STATS(errors); | 1161 | |
484 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | 1162 | /* If 16-bit instruction, not FPU. */ |
485 | return SIGBUS; | 1163 | if ((dec_insn.next_pc_inc == 2) || |
486 | } | 1164 | (microMIPS32_to_MIPS32((union mips_instruction *)&ir) == SIGILL)) { |
487 | if (__get_user(ir, | 1165 | |
488 | (mips_instruction __user *) xcp->cp0_epc)) { | 1166 | /* |
489 | MIPS_FPU_EMU_INC_STATS(errors); | 1167 | * Since this instruction will |
490 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | 1168 | * be put on the stack with |
491 | return SIGSEGV; | 1169 | * 32-bit words, get around |
492 | } | 1170 | * this problem by putting a |
1171 | * NOP16 as the second one. | ||
1172 | */ | ||
1173 | if (dec_insn.next_pc_inc == 2) | ||
1174 | ir = (ir & (~0xffff)) | MM_NOP16; | ||
1175 | |||
1176 | /* | ||
1177 | * Single step the non-CP1 | ||
1178 | * instruction in the dslot. | ||
1179 | */ | ||
1180 | return mips_dsemul(xcp, ir, contpc); | ||
1181 | } | ||
1182 | } else | ||
1183 | contpc = (xcp->cp0_epc + (contpc << 2)); | ||
493 | 1184 | ||
494 | switch (MIPSInst_OPCODE(ir)) { | 1185 | switch (MIPSInst_OPCODE(ir)) { |
495 | case lwc1_op: | 1186 | case lwc1_op: |
@@ -525,8 +1216,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
525 | * branch likely nullifies | 1216 | * branch likely nullifies |
526 | * dslot if not taken | 1217 | * dslot if not taken |
527 | */ | 1218 | */ |
528 | xcp->cp0_epc += 4; | 1219 | xcp->cp0_epc += dec_insn.pc_inc; |
529 | contpc += 4; | 1220 | contpc += dec_insn.pc_inc; |
530 | /* | 1221 | /* |
531 | * else continue & execute | 1222 | * else continue & execute |
532 | * dslot as normal insn | 1223 | * dslot as normal insn |
@@ -1313,25 +2004,75 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
1313 | int has_fpu, void *__user *fault_addr) | 2004 | int has_fpu, void *__user *fault_addr) |
1314 | { | 2005 | { |
1315 | unsigned long oldepc, prevepc; | 2006 | unsigned long oldepc, prevepc; |
1316 | mips_instruction insn; | 2007 | struct mm_decoded_insn dec_insn; |
2008 | u16 instr[4]; | ||
2009 | u16 *instr_ptr; | ||
1317 | int sig = 0; | 2010 | int sig = 0; |
1318 | 2011 | ||
1319 | oldepc = xcp->cp0_epc; | 2012 | oldepc = xcp->cp0_epc; |
1320 | do { | 2013 | do { |
1321 | prevepc = xcp->cp0_epc; | 2014 | prevepc = xcp->cp0_epc; |
1322 | 2015 | ||
1323 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) { | 2016 | if (get_isa16_mode(prevepc) && cpu_has_mmips) { |
1324 | MIPS_FPU_EMU_INC_STATS(errors); | 2017 | /* |
1325 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | 2018 | * Get next 2 microMIPS instructions and convert them |
1326 | return SIGBUS; | 2019 | * into 32-bit instructions. |
1327 | } | 2020 | */ |
1328 | if (__get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) { | 2021 | if ((get_user(instr[0], (u16 __user *)msk_isa16_mode(xcp->cp0_epc))) || |
1329 | MIPS_FPU_EMU_INC_STATS(errors); | 2022 | (get_user(instr[1], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 2))) || |
1330 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | 2023 | (get_user(instr[2], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 4))) || |
1331 | return SIGSEGV; | 2024 | (get_user(instr[3], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 6)))) { |
2025 | MIPS_FPU_EMU_INC_STATS(errors); | ||
2026 | return SIGBUS; | ||
2027 | } | ||
2028 | instr_ptr = instr; | ||
2029 | |||
2030 | /* Get first instruction. */ | ||
2031 | if (mm_insn_16bit(*instr_ptr)) { | ||
2032 | /* Duplicate the half-word. */ | ||
2033 | dec_insn.insn = (*instr_ptr << 16) | | ||
2034 | (*instr_ptr); | ||
2035 | /* 16-bit instruction. */ | ||
2036 | dec_insn.pc_inc = 2; | ||
2037 | instr_ptr += 1; | ||
2038 | } else { | ||
2039 | dec_insn.insn = (*instr_ptr << 16) | | ||
2040 | *(instr_ptr+1); | ||
2041 | /* 32-bit instruction. */ | ||
2042 | dec_insn.pc_inc = 4; | ||
2043 | instr_ptr += 2; | ||
2044 | } | ||
2045 | /* Get second instruction. */ | ||
2046 | if (mm_insn_16bit(*instr_ptr)) { | ||
2047 | /* Duplicate the half-word. */ | ||
2048 | dec_insn.next_insn = (*instr_ptr << 16) | | ||
2049 | (*instr_ptr); | ||
2050 | /* 16-bit instruction. */ | ||
2051 | dec_insn.next_pc_inc = 2; | ||
2052 | } else { | ||
2053 | dec_insn.next_insn = (*instr_ptr << 16) | | ||
2054 | *(instr_ptr+1); | ||
2055 | /* 32-bit instruction. */ | ||
2056 | dec_insn.next_pc_inc = 4; | ||
2057 | } | ||
2058 | dec_insn.micro_mips_mode = 1; | ||
2059 | } else { | ||
2060 | if ((get_user(dec_insn.insn, | ||
2061 | (mips_instruction __user *) xcp->cp0_epc)) || | ||
2062 | (get_user(dec_insn.next_insn, | ||
2063 | (mips_instruction __user *)(xcp->cp0_epc+4)))) { | ||
2064 | MIPS_FPU_EMU_INC_STATS(errors); | ||
2065 | return SIGBUS; | ||
2066 | } | ||
2067 | dec_insn.pc_inc = 4; | ||
2068 | dec_insn.next_pc_inc = 4; | ||
2069 | dec_insn.micro_mips_mode = 0; | ||
1332 | } | 2070 | } |
1333 | if (insn == 0) | 2071 | |
1334 | xcp->cp0_epc += 4; /* skip nops */ | 2072 | if ((dec_insn.insn == 0) || |
2073 | ((dec_insn.pc_inc == 2) && | ||
2074 | ((dec_insn.insn & 0xffff) == MM_NOP16))) | ||
2075 | xcp->cp0_epc += dec_insn.pc_inc; /* Skip NOPs */ | ||
1335 | else { | 2076 | else { |
1336 | /* | 2077 | /* |
1337 | * The 'ieee754_csr' is an alias of | 2078 | * The 'ieee754_csr' is an alias of |
@@ -1341,7 +2082,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
1341 | */ | 2082 | */ |
1342 | /* convert to ieee library modes */ | 2083 | /* convert to ieee library modes */ |
1343 | ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; | 2084 | ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; |
1344 | sig = cop1Emulate(xcp, ctx, fault_addr); | 2085 | sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr); |
1345 | /* revert to mips rounding mode */ | 2086 | /* revert to mips rounding mode */ |
1346 | ieee754_csr.rm = mips_rm[ieee754_csr.rm]; | 2087 | ieee754_csr.rm = mips_rm[ieee754_csr.rm]; |
1347 | } | 2088 | } |
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c index 384a3b0091ea..7ea622ab8dad 100644 --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c | |||
@@ -55,7 +55,9 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) | |||
55 | struct emuframe __user *fr; | 55 | struct emuframe __user *fr; |
56 | int err; | 56 | int err; |
57 | 57 | ||
58 | if (ir == 0) { /* a nop is easy */ | 58 | if ((get_isa16_mode(regs->cp0_epc) && ((ir >> 16) == MM_NOP16)) || |
59 | (ir == 0)) { | ||
60 | /* NOP is easy */ | ||
59 | regs->cp0_epc = cpc; | 61 | regs->cp0_epc = cpc; |
60 | regs->cp0_cause &= ~CAUSEF_BD; | 62 | regs->cp0_cause &= ~CAUSEF_BD; |
61 | return 0; | 63 | return 0; |
@@ -91,8 +93,16 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) | |||
91 | if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe)))) | 93 | if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe)))) |
92 | return SIGBUS; | 94 | return SIGBUS; |
93 | 95 | ||
94 | err = __put_user(ir, &fr->emul); | 96 | if (get_isa16_mode(regs->cp0_epc)) { |
95 | err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst); | 97 | err = __put_user(ir >> 16, (u16 __user *)(&fr->emul)); |
98 | err |= __put_user(ir & 0xffff, (u16 __user *)((long)(&fr->emul) + 2)); | ||
99 | err |= __put_user(BREAK_MATH >> 16, (u16 __user *)(&fr->badinst)); | ||
100 | err |= __put_user(BREAK_MATH & 0xffff, (u16 __user *)((long)(&fr->badinst) + 2)); | ||
101 | } else { | ||
102 | err = __put_user(ir, &fr->emul); | ||
103 | err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst); | ||
104 | } | ||
105 | |||
96 | err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie); | 106 | err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie); |
97 | err |= __put_user(cpc, &fr->epc); | 107 | err |= __put_user(cpc, &fr->epc); |
98 | 108 | ||
@@ -101,7 +111,8 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) | |||
101 | return SIGBUS; | 111 | return SIGBUS; |
102 | } | 112 | } |
103 | 113 | ||
104 | regs->cp0_epc = (unsigned long) &fr->emul; | 114 | regs->cp0_epc = ((unsigned long) &fr->emul) | |
115 | get_isa16_mode(regs->cp0_epc); | ||
105 | 116 | ||
106 | flush_cache_sigtramp((unsigned long)&fr->badinst); | 117 | flush_cache_sigtramp((unsigned long)&fr->badinst); |
107 | 118 | ||
@@ -114,9 +125,10 @@ int do_dsemulret(struct pt_regs *xcp) | |||
114 | unsigned long epc; | 125 | unsigned long epc; |
115 | u32 insn, cookie; | 126 | u32 insn, cookie; |
116 | int err = 0; | 127 | int err = 0; |
128 | u16 instr[2]; | ||
117 | 129 | ||
118 | fr = (struct emuframe __user *) | 130 | fr = (struct emuframe __user *) |
119 | (xcp->cp0_epc - sizeof(mips_instruction)); | 131 | (msk_isa16_mode(xcp->cp0_epc) - sizeof(mips_instruction)); |
120 | 132 | ||
121 | /* | 133 | /* |
122 | * If we can't even access the area, something is very wrong, but we'll | 134 | * If we can't even access the area, something is very wrong, but we'll |
@@ -131,7 +143,13 @@ int do_dsemulret(struct pt_regs *xcp) | |||
131 | * - Is the instruction pointed to by the EPC an BREAK_MATH? | 143 | * - Is the instruction pointed to by the EPC an BREAK_MATH? |
132 | * - Is the following memory word the BD_COOKIE? | 144 | * - Is the following memory word the BD_COOKIE? |
133 | */ | 145 | */ |
134 | err = __get_user(insn, &fr->badinst); | 146 | if (get_isa16_mode(xcp->cp0_epc)) { |
147 | err = __get_user(instr[0], (u16 __user *)(&fr->badinst)); | ||
148 | err |= __get_user(instr[1], (u16 __user *)((long)(&fr->badinst) + 2)); | ||
149 | insn = (instr[0] << 16) | instr[1]; | ||
150 | } else { | ||
151 | err = __get_user(insn, &fr->badinst); | ||
152 | } | ||
135 | err |= __get_user(cookie, &fr->cookie); | 153 | err |= __get_user(cookie, &fr->cookie); |
136 | 154 | ||
137 | if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) { | 155 | if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) { |
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 1dcec30ad1c4..e87aae1f2e80 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-y += cache.o dma-default.o extable.o fault.o \ | 5 | obj-y += cache.o dma-default.o extable.o fault.o \ |
6 | gup.o init.o mmap.o page.o page-funcs.o \ | 6 | gup.o init.o mmap.o page.o page-funcs.o \ |
7 | tlbex.o tlbex-fault.o uasm.o | 7 | tlbex.o tlbex-fault.o uasm-mips.o |
8 | 8 | ||
9 | obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o | 9 | obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o |
10 | obj-$(CONFIG_64BIT) += pgtable-64.o | 10 | obj-$(CONFIG_64BIT) += pgtable-64.o |
@@ -22,3 +22,5 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o | |||
22 | obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o | 22 | obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o |
23 | obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o | 23 | obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o |
24 | obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o | 24 | obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o |
25 | |||
26 | obj-$(CONFIG_SYS_SUPPORTS_MICROMIPS) += uasm-micromips.o | ||
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 96f4d5a6c21c..21813beec7a5 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/war.h> | 33 | #include <asm/war.h> |
34 | #include <asm/cacheflush.h> /* for run_uncached() */ | 34 | #include <asm/cacheflush.h> /* for run_uncached() */ |
35 | #include <asm/traps.h> | 35 | #include <asm/traps.h> |
36 | #include <asm/dma-coherence.h> | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Special Variant of smp_call_function for use by cache functions: | 39 | * Special Variant of smp_call_function for use by cache functions: |
@@ -1379,20 +1380,6 @@ static void __cpuinit coherency_setup(void) | |||
1379 | } | 1380 | } |
1380 | } | 1381 | } |
1381 | 1382 | ||
1382 | #if defined(CONFIG_DMA_NONCOHERENT) | ||
1383 | |||
1384 | static int __cpuinitdata coherentio; | ||
1385 | |||
1386 | static int __init setcoherentio(char *str) | ||
1387 | { | ||
1388 | coherentio = 1; | ||
1389 | |||
1390 | return 0; | ||
1391 | } | ||
1392 | |||
1393 | early_param("coherentio", setcoherentio); | ||
1394 | #endif | ||
1395 | |||
1396 | static void __cpuinit r4k_cache_error_setup(void) | 1383 | static void __cpuinit r4k_cache_error_setup(void) |
1397 | { | 1384 | { |
1398 | extern char __weak except_vec2_generic; | 1385 | extern char __weak except_vec2_generic; |
@@ -1474,9 +1461,14 @@ void __cpuinit r4k_cache_init(void) | |||
1474 | 1461 | ||
1475 | build_clear_page(); | 1462 | build_clear_page(); |
1476 | build_copy_page(); | 1463 | build_copy_page(); |
1477 | #if !defined(CONFIG_MIPS_CMP) | 1464 | |
1465 | /* | ||
1466 | * We want to run CMP kernels on core with and without coherent | ||
1467 | * caches. Therefore, do not use CONFIG_MIPS_CMP to decide whether | ||
1468 | * or not to flush caches. | ||
1469 | */ | ||
1478 | local_r4k___flush_cache_all(NULL); | 1470 | local_r4k___flush_cache_all(NULL); |
1479 | #endif | 1471 | |
1480 | coherency_setup(); | 1472 | coherency_setup(); |
1481 | board_cache_error_setup = r4k_cache_error_setup; | 1473 | board_cache_error_setup = r4k_cache_error_setup; |
1482 | } | 1474 | } |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index f9ef83829a52..caf92ecb37d6 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -22,6 +22,26 @@ | |||
22 | 22 | ||
23 | #include <dma-coherence.h> | 23 | #include <dma-coherence.h> |
24 | 24 | ||
25 | int coherentio = 0; /* User defined DMA coherency from command line. */ | ||
26 | EXPORT_SYMBOL_GPL(coherentio); | ||
27 | int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */ | ||
28 | |||
29 | static int __init setcoherentio(char *str) | ||
30 | { | ||
31 | coherentio = 1; | ||
32 | pr_info("Hardware DMA cache coherency (command line)\n"); | ||
33 | return 0; | ||
34 | } | ||
35 | early_param("coherentio", setcoherentio); | ||
36 | |||
37 | static int __init setnocoherentio(char *str) | ||
38 | { | ||
39 | coherentio = 0; | ||
40 | pr_info("Software DMA cache coherency (command line)\n"); | ||
41 | return 0; | ||
42 | } | ||
43 | early_param("nocoherentio", setnocoherentio); | ||
44 | |||
25 | static inline struct page *dma_addr_to_page(struct device *dev, | 45 | static inline struct page *dma_addr_to_page(struct device *dev, |
26 | dma_addr_t dma_addr) | 46 | dma_addr_t dma_addr) |
27 | { | 47 | { |
@@ -115,7 +135,8 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, | |||
115 | 135 | ||
116 | if (!plat_device_is_coherent(dev)) { | 136 | if (!plat_device_is_coherent(dev)) { |
117 | dma_cache_wback_inv((unsigned long) ret, size); | 137 | dma_cache_wback_inv((unsigned long) ret, size); |
118 | ret = UNCAC_ADDR(ret); | 138 | if (!hw_coherentio) |
139 | ret = UNCAC_ADDR(ret); | ||
119 | } | 140 | } |
120 | } | 141 | } |
121 | 142 | ||
@@ -142,7 +163,7 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, | |||
142 | 163 | ||
143 | plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); | 164 | plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); |
144 | 165 | ||
145 | if (!plat_device_is_coherent(dev)) | 166 | if (!plat_device_is_coherent(dev) && !hw_coherentio) |
146 | addr = CAC_ADDR(addr); | 167 | addr = CAC_ADDR(addr); |
147 | 168 | ||
148 | free_pages(addr, get_order(size)); | 169 | free_pages(addr, get_order(size)); |
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c index a63d1ed0827f..4a13c150f31b 100644 --- a/arch/mips/mm/tlb-r3k.c +++ b/arch/mips/mm/tlb-r3k.c | |||
@@ -51,7 +51,7 @@ void local_flush_tlb_all(void) | |||
51 | #endif | 51 | #endif |
52 | 52 | ||
53 | local_irq_save(flags); | 53 | local_irq_save(flags); |
54 | old_ctx = read_c0_entryhi() & ASID_MASK; | 54 | old_ctx = ASID_MASK(read_c0_entryhi()); |
55 | write_c0_entrylo0(0); | 55 | write_c0_entrylo0(0); |
56 | entry = r3k_have_wired_reg ? read_c0_wired() : 8; | 56 | entry = r3k_have_wired_reg ? read_c0_wired() : 8; |
57 | for (; entry < current_cpu_data.tlbsize; entry++) { | 57 | for (; entry < current_cpu_data.tlbsize; entry++) { |
@@ -87,13 +87,13 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
87 | 87 | ||
88 | #ifdef DEBUG_TLB | 88 | #ifdef DEBUG_TLB |
89 | printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", | 89 | printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", |
90 | cpu_context(cpu, mm) & ASID_MASK, start, end); | 90 | ASID_MASK(cpu_context(cpu, mm)), start, end); |
91 | #endif | 91 | #endif |
92 | local_irq_save(flags); | 92 | local_irq_save(flags); |
93 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 93 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
94 | if (size <= current_cpu_data.tlbsize) { | 94 | if (size <= current_cpu_data.tlbsize) { |
95 | int oldpid = read_c0_entryhi() & ASID_MASK; | 95 | int oldpid = ASID_MASK(read_c0_entryhi()); |
96 | int newpid = cpu_context(cpu, mm) & ASID_MASK; | 96 | int newpid = ASID_MASK(cpu_context(cpu, mm)); |
97 | 97 | ||
98 | start &= PAGE_MASK; | 98 | start &= PAGE_MASK; |
99 | end += PAGE_SIZE - 1; | 99 | end += PAGE_SIZE - 1; |
@@ -166,10 +166,10 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
166 | #ifdef DEBUG_TLB | 166 | #ifdef DEBUG_TLB |
167 | printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page); | 167 | printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page); |
168 | #endif | 168 | #endif |
169 | newpid = cpu_context(cpu, vma->vm_mm) & ASID_MASK; | 169 | newpid = ASID_MASK(cpu_context(cpu, vma->vm_mm)); |
170 | page &= PAGE_MASK; | 170 | page &= PAGE_MASK; |
171 | local_irq_save(flags); | 171 | local_irq_save(flags); |
172 | oldpid = read_c0_entryhi() & ASID_MASK; | 172 | oldpid = ASID_MASK(read_c0_entryhi()); |
173 | write_c0_entryhi(page | newpid); | 173 | write_c0_entryhi(page | newpid); |
174 | BARRIER; | 174 | BARRIER; |
175 | tlb_probe(); | 175 | tlb_probe(); |
@@ -197,10 +197,10 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) | |||
197 | if (current->active_mm != vma->vm_mm) | 197 | if (current->active_mm != vma->vm_mm) |
198 | return; | 198 | return; |
199 | 199 | ||
200 | pid = read_c0_entryhi() & ASID_MASK; | 200 | pid = ASID_MASK(read_c0_entryhi()); |
201 | 201 | ||
202 | #ifdef DEBUG_TLB | 202 | #ifdef DEBUG_TLB |
203 | if ((pid != (cpu_context(cpu, vma->vm_mm) & ASID_MASK)) || (cpu_context(cpu, vma->vm_mm) == 0)) { | 203 | if ((pid != ASID_MASK(cpu_context(cpu, vma->vm_mm))) || (cpu_context(cpu, vma->vm_mm) == 0)) { |
204 | printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n", | 204 | printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n", |
205 | (cpu_context(cpu, vma->vm_mm)), pid); | 205 | (cpu_context(cpu, vma->vm_mm)), pid); |
206 | } | 206 | } |
@@ -241,7 +241,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
241 | 241 | ||
242 | local_irq_save(flags); | 242 | local_irq_save(flags); |
243 | /* Save old context and create impossible VPN2 value */ | 243 | /* Save old context and create impossible VPN2 value */ |
244 | old_ctx = read_c0_entryhi() & ASID_MASK; | 244 | old_ctx = ASID_MASK(read_c0_entryhi()); |
245 | old_pagemask = read_c0_pagemask(); | 245 | old_pagemask = read_c0_pagemask(); |
246 | w = read_c0_wired(); | 246 | w = read_c0_wired(); |
247 | write_c0_wired(w + 1); | 247 | write_c0_wired(w + 1); |
@@ -264,7 +264,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
264 | #endif | 264 | #endif |
265 | 265 | ||
266 | local_irq_save(flags); | 266 | local_irq_save(flags); |
267 | old_ctx = read_c0_entryhi() & ASID_MASK; | 267 | old_ctx = ASID_MASK(read_c0_entryhi()); |
268 | write_c0_entrylo0(entrylo0); | 268 | write_c0_entrylo0(entrylo0); |
269 | write_c0_entryhi(entryhi); | 269 | write_c0_entryhi(entryhi); |
270 | write_c0_index(wired); | 270 | write_c0_index(wired); |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index c643de4c473a..09653b290d53 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -287,7 +287,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
287 | 287 | ||
288 | ENTER_CRITICAL(flags); | 288 | ENTER_CRITICAL(flags); |
289 | 289 | ||
290 | pid = read_c0_entryhi() & ASID_MASK; | 290 | pid = ASID_MASK(read_c0_entryhi()); |
291 | address &= (PAGE_MASK << 1); | 291 | address &= (PAGE_MASK << 1); |
292 | write_c0_entryhi(address | pid); | 292 | write_c0_entryhi(address | pid); |
293 | pgdp = pgd_offset(vma->vm_mm, address); | 293 | pgdp = pgd_offset(vma->vm_mm, address); |
diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c index 91c2499f806a..122f9207f49e 100644 --- a/arch/mips/mm/tlb-r8k.c +++ b/arch/mips/mm/tlb-r8k.c | |||
@@ -195,7 +195,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
195 | if (current->active_mm != vma->vm_mm) | 195 | if (current->active_mm != vma->vm_mm) |
196 | return; | 196 | return; |
197 | 197 | ||
198 | pid = read_c0_entryhi() & ASID_MASK; | 198 | pid = ASID_MASK(read_c0_entryhi()); |
199 | 199 | ||
200 | local_irq_save(flags); | 200 | local_irq_save(flags); |
201 | address &= PAGE_MASK; | 201 | address &= PAGE_MASK; |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 3b3822afb059..4d46d3787576 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/cache.h> | 30 | #include <linux/cache.h> |
31 | 31 | ||
32 | #include <asm/mmu_context.h> | ||
32 | #include <asm/cacheflush.h> | 33 | #include <asm/cacheflush.h> |
33 | #include <asm/pgtable.h> | 34 | #include <asm/pgtable.h> |
34 | #include <asm/war.h> | 35 | #include <asm/war.h> |
@@ -305,6 +306,78 @@ static struct uasm_reloc relocs[128] __cpuinitdata; | |||
305 | static int check_for_high_segbits __cpuinitdata; | 306 | static int check_for_high_segbits __cpuinitdata; |
306 | #endif | 307 | #endif |
307 | 308 | ||
309 | static void __cpuinit insn_fixup(unsigned int **start, unsigned int **stop, | ||
310 | unsigned int i_const) | ||
311 | { | ||
312 | unsigned int **p; | ||
313 | |||
314 | for (p = start; p < stop; p++) { | ||
315 | #ifndef CONFIG_CPU_MICROMIPS | ||
316 | unsigned int *ip; | ||
317 | |||
318 | ip = *p; | ||
319 | *ip = (*ip & 0xffff0000) | i_const; | ||
320 | #else | ||
321 | unsigned short *ip; | ||
322 | |||
323 | ip = ((unsigned short *)((unsigned int)*p - 1)); | ||
324 | if ((*ip & 0xf000) == 0x4000) { | ||
325 | *ip &= 0xfff1; | ||
326 | *ip |= (i_const << 1); | ||
327 | } else if ((*ip & 0xf000) == 0x6000) { | ||
328 | *ip &= 0xfff1; | ||
329 | *ip |= ((i_const >> 2) << 1); | ||
330 | } else { | ||
331 | ip++; | ||
332 | *ip = i_const; | ||
333 | } | ||
334 | #endif | ||
335 | local_flush_icache_range((unsigned long)ip, | ||
336 | (unsigned long)ip + sizeof(*ip)); | ||
337 | } | ||
338 | } | ||
339 | |||
340 | #define asid_insn_fixup(section, const) \ | ||
341 | do { \ | ||
342 | extern unsigned int *__start_ ## section; \ | ||
343 | extern unsigned int *__stop_ ## section; \ | ||
344 | insn_fixup(&__start_ ## section, &__stop_ ## section, const); \ | ||
345 | } while(0) | ||
346 | |||
347 | /* | ||
348 | * Caller is assumed to flush the caches before the first context switch. | ||
349 | */ | ||
350 | static void __cpuinit setup_asid(unsigned int inc, unsigned int mask, | ||
351 | unsigned int version_mask, | ||
352 | unsigned int first_version) | ||
353 | { | ||
354 | extern asmlinkage void handle_ri_rdhwr_vivt(void); | ||
355 | unsigned long *vivt_exc; | ||
356 | |||
357 | #ifdef CONFIG_CPU_MICROMIPS | ||
358 | /* | ||
359 | * Worst case optimised microMIPS addiu instructions support | ||
360 | * only a 3-bit immediate value. | ||
361 | */ | ||
362 | if(inc > 7) | ||
363 | panic("Invalid ASID increment value!"); | ||
364 | #endif | ||
365 | asid_insn_fixup(__asid_inc, inc); | ||
366 | asid_insn_fixup(__asid_mask, mask); | ||
367 | asid_insn_fixup(__asid_version_mask, version_mask); | ||
368 | asid_insn_fixup(__asid_first_version, first_version); | ||
369 | |||
370 | /* Patch up the 'handle_ri_rdhwr_vivt' handler. */ | ||
371 | vivt_exc = (unsigned long *) &handle_ri_rdhwr_vivt; | ||
372 | #ifdef CONFIG_CPU_MICROMIPS | ||
373 | vivt_exc = (unsigned long *)((unsigned long) vivt_exc - 1); | ||
374 | #endif | ||
375 | vivt_exc++; | ||
376 | *vivt_exc = (*vivt_exc & ~mask) | mask; | ||
377 | |||
378 | current_cpu_data.asid_cache = first_version; | ||
379 | } | ||
380 | |||
308 | static int check_for_high_segbits __cpuinitdata; | 381 | static int check_for_high_segbits __cpuinitdata; |
309 | 382 | ||
310 | static unsigned int kscratch_used_mask __cpuinitdata; | 383 | static unsigned int kscratch_used_mask __cpuinitdata; |
@@ -2030,6 +2103,13 @@ static void __cpuinit build_r4000_tlb_load_handler(void) | |||
2030 | 2103 | ||
2031 | uasm_l_nopage_tlbl(&l, p); | 2104 | uasm_l_nopage_tlbl(&l, p); |
2032 | build_restore_work_registers(&p); | 2105 | build_restore_work_registers(&p); |
2106 | #ifdef CONFIG_CPU_MICROMIPS | ||
2107 | if ((unsigned long)tlb_do_page_fault_0 & 1) { | ||
2108 | uasm_i_lui(&p, K0, uasm_rel_hi((long)tlb_do_page_fault_0)); | ||
2109 | uasm_i_addiu(&p, K0, K0, uasm_rel_lo((long)tlb_do_page_fault_0)); | ||
2110 | uasm_i_jr(&p, K0); | ||
2111 | } else | ||
2112 | #endif | ||
2033 | uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); | 2113 | uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); |
2034 | uasm_i_nop(&p); | 2114 | uasm_i_nop(&p); |
2035 | 2115 | ||
@@ -2077,6 +2157,13 @@ static void __cpuinit build_r4000_tlb_store_handler(void) | |||
2077 | 2157 | ||
2078 | uasm_l_nopage_tlbs(&l, p); | 2158 | uasm_l_nopage_tlbs(&l, p); |
2079 | build_restore_work_registers(&p); | 2159 | build_restore_work_registers(&p); |
2160 | #ifdef CONFIG_CPU_MICROMIPS | ||
2161 | if ((unsigned long)tlb_do_page_fault_1 & 1) { | ||
2162 | uasm_i_lui(&p, K0, uasm_rel_hi((long)tlb_do_page_fault_1)); | ||
2163 | uasm_i_addiu(&p, K0, K0, uasm_rel_lo((long)tlb_do_page_fault_1)); | ||
2164 | uasm_i_jr(&p, K0); | ||
2165 | } else | ||
2166 | #endif | ||
2080 | uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); | 2167 | uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); |
2081 | uasm_i_nop(&p); | 2168 | uasm_i_nop(&p); |
2082 | 2169 | ||
@@ -2125,6 +2212,13 @@ static void __cpuinit build_r4000_tlb_modify_handler(void) | |||
2125 | 2212 | ||
2126 | uasm_l_nopage_tlbm(&l, p); | 2213 | uasm_l_nopage_tlbm(&l, p); |
2127 | build_restore_work_registers(&p); | 2214 | build_restore_work_registers(&p); |
2215 | #ifdef CONFIG_CPU_MICROMIPS | ||
2216 | if ((unsigned long)tlb_do_page_fault_1 & 1) { | ||
2217 | uasm_i_lui(&p, K0, uasm_rel_hi((long)tlb_do_page_fault_1)); | ||
2218 | uasm_i_addiu(&p, K0, K0, uasm_rel_lo((long)tlb_do_page_fault_1)); | ||
2219 | uasm_i_jr(&p, K0); | ||
2220 | } else | ||
2221 | #endif | ||
2128 | uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); | 2222 | uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); |
2129 | uasm_i_nop(&p); | 2223 | uasm_i_nop(&p); |
2130 | 2224 | ||
@@ -2162,6 +2256,7 @@ void __cpuinit build_tlb_refill_handler(void) | |||
2162 | case CPU_TX3922: | 2256 | case CPU_TX3922: |
2163 | case CPU_TX3927: | 2257 | case CPU_TX3927: |
2164 | #ifndef CONFIG_MIPS_PGD_C0_CONTEXT | 2258 | #ifndef CONFIG_MIPS_PGD_C0_CONTEXT |
2259 | setup_asid(0x40, 0xfc0, 0xf000, ASID_FIRST_VERSION_R3000); | ||
2165 | if (cpu_has_local_ebase) | 2260 | if (cpu_has_local_ebase) |
2166 | build_r3000_tlb_refill_handler(); | 2261 | build_r3000_tlb_refill_handler(); |
2167 | if (!run_once) { | 2262 | if (!run_once) { |
@@ -2187,6 +2282,11 @@ void __cpuinit build_tlb_refill_handler(void) | |||
2187 | break; | 2282 | break; |
2188 | 2283 | ||
2189 | default: | 2284 | default: |
2285 | #ifndef CONFIG_MIPS_MT_SMTC | ||
2286 | setup_asid(0x1, 0xff, 0xff00, ASID_FIRST_VERSION_R4000); | ||
2287 | #else | ||
2288 | setup_asid(0x1, smtc_asid_mask, 0xff00, ASID_FIRST_VERSION_R4000); | ||
2289 | #endif | ||
2190 | if (!run_once) { | 2290 | if (!run_once) { |
2191 | scratch_reg = allocate_kscratch(); | 2291 | scratch_reg = allocate_kscratch(); |
2192 | #ifdef CONFIG_MIPS_PGD_C0_CONTEXT | 2292 | #ifdef CONFIG_MIPS_PGD_C0_CONTEXT |
diff --git a/arch/mips/mm/uasm-micromips.c b/arch/mips/mm/uasm-micromips.c new file mode 100644 index 000000000000..162ee6d62788 --- /dev/null +++ b/arch/mips/mm/uasm-micromips.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * A small micro-assembler. It is intentionally kept simple, does only | ||
7 | * support a subset of instructions, and does not try to hide pipeline | ||
8 | * effects like branch delay slots. | ||
9 | * | ||
10 | * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer | ||
11 | * Copyright (C) 2005, 2007 Maciej W. Rozycki | ||
12 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | ||
13 | * Copyright (C) 2012, 2013 MIPS Technologies, Inc. All rights reserved. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/init.h> | ||
19 | |||
20 | #include <asm/inst.h> | ||
21 | #include <asm/elf.h> | ||
22 | #include <asm/bugs.h> | ||
23 | #define UASM_ISA _UASM_ISA_MICROMIPS | ||
24 | #include <asm/uasm.h> | ||
25 | |||
26 | #define RS_MASK 0x1f | ||
27 | #define RS_SH 16 | ||
28 | #define RT_MASK 0x1f | ||
29 | #define RT_SH 21 | ||
30 | #define SCIMM_MASK 0x3ff | ||
31 | #define SCIMM_SH 16 | ||
32 | |||
33 | /* This macro sets the non-variable bits of an instruction. */ | ||
34 | #define M(a, b, c, d, e, f) \ | ||
35 | ((a) << OP_SH \ | ||
36 | | (b) << RT_SH \ | ||
37 | | (c) << RS_SH \ | ||
38 | | (d) << RD_SH \ | ||
39 | | (e) << RE_SH \ | ||
40 | | (f) << FUNC_SH) | ||
41 | |||
42 | /* Define these when we are not the ISA the kernel is being compiled with. */ | ||
43 | #ifndef CONFIG_CPU_MICROMIPS | ||
44 | #define MM_uasm_i_b(buf, off) ISAOPC(_beq)(buf, 0, 0, off) | ||
45 | #define MM_uasm_i_beqz(buf, rs, off) ISAOPC(_beq)(buf, rs, 0, off) | ||
46 | #define MM_uasm_i_beqzl(buf, rs, off) ISAOPC(_beql)(buf, rs, 0, off) | ||
47 | #define MM_uasm_i_bnez(buf, rs, off) ISAOPC(_bne)(buf, rs, 0, off) | ||
48 | #endif | ||
49 | |||
50 | #include "uasm.c" | ||
51 | |||
52 | static struct insn insn_table_MM[] __uasminitdata = { | ||
53 | { insn_addu, M(mm_pool32a_op, 0, 0, 0, 0, mm_addu32_op), RT | RS | RD }, | ||
54 | { insn_addiu, M(mm_addiu32_op, 0, 0, 0, 0, 0), RT | RS | SIMM }, | ||
55 | { insn_and, M(mm_pool32a_op, 0, 0, 0, 0, mm_and_op), RT | RS | RD }, | ||
56 | { insn_andi, M(mm_andi32_op, 0, 0, 0, 0, 0), RT | RS | UIMM }, | ||
57 | { insn_beq, M(mm_beq32_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
58 | { insn_beql, 0, 0 }, | ||
59 | { insn_bgez, M(mm_pool32i_op, mm_bgez_op, 0, 0, 0, 0), RS | BIMM }, | ||
60 | { insn_bgezl, 0, 0 }, | ||
61 | { insn_bltz, M(mm_pool32i_op, mm_bltz_op, 0, 0, 0, 0), RS | BIMM }, | ||
62 | { insn_bltzl, 0, 0 }, | ||
63 | { insn_bne, M(mm_bne32_op, 0, 0, 0, 0, 0), RT | RS | BIMM }, | ||
64 | { insn_cache, M(mm_pool32b_op, 0, 0, mm_cache_func, 0, 0), RT | RS | SIMM }, | ||
65 | { insn_daddu, 0, 0 }, | ||
66 | { insn_daddiu, 0, 0 }, | ||
67 | { insn_dmfc0, 0, 0 }, | ||
68 | { insn_dmtc0, 0, 0 }, | ||
69 | { insn_dsll, 0, 0 }, | ||
70 | { insn_dsll32, 0, 0 }, | ||
71 | { insn_dsra, 0, 0 }, | ||
72 | { insn_dsrl, 0, 0 }, | ||
73 | { insn_dsrl32, 0, 0 }, | ||
74 | { insn_drotr, 0, 0 }, | ||
75 | { insn_drotr32, 0, 0 }, | ||
76 | { insn_dsubu, 0, 0 }, | ||
77 | { insn_eret, M(mm_pool32a_op, 0, 0, 0, mm_eret_op, mm_pool32axf_op), 0 }, | ||
78 | { insn_ins, M(mm_pool32a_op, 0, 0, 0, 0, mm_ins_op), RT | RS | RD | RE }, | ||
79 | { insn_ext, M(mm_pool32a_op, 0, 0, 0, 0, mm_ext_op), RT | RS | RD | RE }, | ||
80 | { insn_j, M(mm_j32_op, 0, 0, 0, 0, 0), JIMM }, | ||
81 | { insn_jal, M(mm_jal32_op, 0, 0, 0, 0, 0), JIMM }, | ||
82 | { insn_jr, M(mm_pool32a_op, 0, 0, 0, mm_jalr_op, mm_pool32axf_op), RS }, | ||
83 | { insn_ld, 0, 0 }, | ||
84 | { insn_ll, M(mm_pool32c_op, 0, 0, (mm_ll_func << 1), 0, 0), RS | RT | SIMM }, | ||
85 | { insn_lld, 0, 0 }, | ||
86 | { insn_lui, M(mm_pool32i_op, mm_lui_op, 0, 0, 0, 0), RS | SIMM }, | ||
87 | { insn_lw, M(mm_lw32_op, 0, 0, 0, 0, 0), RT | RS | SIMM }, | ||
88 | { insn_mfc0, M(mm_pool32a_op, 0, 0, 0, mm_mfc0_op, mm_pool32axf_op), RT | RS | RD }, | ||
89 | { insn_mtc0, M(mm_pool32a_op, 0, 0, 0, mm_mtc0_op, mm_pool32axf_op), RT | RS | RD }, | ||
90 | { insn_or, M(mm_pool32a_op, 0, 0, 0, 0, mm_or32_op), RT | RS | RD }, | ||
91 | { insn_ori, M(mm_ori32_op, 0, 0, 0, 0, 0), RT | RS | UIMM }, | ||
92 | { insn_pref, M(mm_pool32c_op, 0, 0, (mm_pref_func << 1), 0, 0), RT | RS | SIMM }, | ||
93 | { insn_rfe, 0, 0 }, | ||
94 | { insn_sc, M(mm_pool32c_op, 0, 0, (mm_sc_func << 1), 0, 0), RT | RS | SIMM }, | ||
95 | { insn_scd, 0, 0 }, | ||
96 | { insn_sd, 0, 0 }, | ||
97 | { insn_sll, M(mm_pool32a_op, 0, 0, 0, 0, mm_sll32_op), RT | RS | RD }, | ||
98 | { insn_sra, M(mm_pool32a_op, 0, 0, 0, 0, mm_sra_op), RT | RS | RD }, | ||
99 | { insn_srl, M(mm_pool32a_op, 0, 0, 0, 0, mm_srl32_op), RT | RS | RD }, | ||
100 | { insn_rotr, M(mm_pool32a_op, 0, 0, 0, 0, mm_rotr_op), RT | RS | RD }, | ||
101 | { insn_subu, M(mm_pool32a_op, 0, 0, 0, 0, mm_subu32_op), RT | RS | RD }, | ||
102 | { insn_sw, M(mm_sw32_op, 0, 0, 0, 0, 0), RT | RS | SIMM }, | ||
103 | { insn_tlbp, M(mm_pool32a_op, 0, 0, 0, mm_tlbp_op, mm_pool32axf_op), 0 }, | ||
104 | { insn_tlbr, M(mm_pool32a_op, 0, 0, 0, mm_tlbr_op, mm_pool32axf_op), 0 }, | ||
105 | { insn_tlbwi, M(mm_pool32a_op, 0, 0, 0, mm_tlbwi_op, mm_pool32axf_op), 0 }, | ||
106 | { insn_tlbwr, M(mm_pool32a_op, 0, 0, 0, mm_tlbwr_op, mm_pool32axf_op), 0 }, | ||
107 | { insn_xor, M(mm_pool32a_op, 0, 0, 0, 0, mm_xor32_op), RT | RS | RD }, | ||
108 | { insn_xori, M(mm_xori32_op, 0, 0, 0, 0, 0), RT | RS | UIMM }, | ||
109 | { insn_dins, 0, 0 }, | ||
110 | { insn_dinsm, 0, 0 }, | ||
111 | { insn_syscall, M(mm_pool32a_op, 0, 0, 0, mm_syscall_op, mm_pool32axf_op), SCIMM}, | ||
112 | { insn_bbit0, 0, 0 }, | ||
113 | { insn_bbit1, 0, 0 }, | ||
114 | { insn_lwx, 0, 0 }, | ||
115 | { insn_ldx, 0, 0 }, | ||
116 | { insn_invalid, 0, 0 } | ||
117 | }; | ||
118 | |||
119 | #undef M | ||
120 | |||
121 | static inline __uasminit u32 build_bimm(s32 arg) | ||
122 | { | ||
123 | WARN(arg > 0xffff || arg < -0x10000, | ||
124 | KERN_WARNING "Micro-assembler field overflow\n"); | ||
125 | |||
126 | WARN(arg & 0x3, KERN_WARNING "Invalid micro-assembler branch target\n"); | ||
127 | |||
128 | return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 1) & 0x7fff); | ||
129 | } | ||
130 | |||
131 | static inline __uasminit u32 build_jimm(u32 arg) | ||
132 | { | ||
133 | |||
134 | WARN(arg & ~((JIMM_MASK << 2) | 1), | ||
135 | KERN_WARNING "Micro-assembler field overflow\n"); | ||
136 | |||
137 | return (arg >> 1) & JIMM_MASK; | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * The order of opcode arguments is implicitly left to right, | ||
142 | * starting with RS and ending with FUNC or IMM. | ||
143 | */ | ||
144 | static void __uasminit build_insn(u32 **buf, enum opcode opc, ...) | ||
145 | { | ||
146 | struct insn *ip = NULL; | ||
147 | unsigned int i; | ||
148 | va_list ap; | ||
149 | u32 op; | ||
150 | |||
151 | for (i = 0; insn_table_MM[i].opcode != insn_invalid; i++) | ||
152 | if (insn_table_MM[i].opcode == opc) { | ||
153 | ip = &insn_table_MM[i]; | ||
154 | break; | ||
155 | } | ||
156 | |||
157 | if (!ip || (opc == insn_daddiu && r4k_daddiu_bug())) | ||
158 | panic("Unsupported Micro-assembler instruction %d", opc); | ||
159 | |||
160 | op = ip->match; | ||
161 | va_start(ap, opc); | ||
162 | if (ip->fields & RS) { | ||
163 | if (opc == insn_mfc0 || opc == insn_mtc0) | ||
164 | op |= build_rt(va_arg(ap, u32)); | ||
165 | else | ||
166 | op |= build_rs(va_arg(ap, u32)); | ||
167 | } | ||
168 | if (ip->fields & RT) { | ||
169 | if (opc == insn_mfc0 || opc == insn_mtc0) | ||
170 | op |= build_rs(va_arg(ap, u32)); | ||
171 | else | ||
172 | op |= build_rt(va_arg(ap, u32)); | ||
173 | } | ||
174 | if (ip->fields & RD) | ||
175 | op |= build_rd(va_arg(ap, u32)); | ||
176 | if (ip->fields & RE) | ||
177 | op |= build_re(va_arg(ap, u32)); | ||
178 | if (ip->fields & SIMM) | ||
179 | op |= build_simm(va_arg(ap, s32)); | ||
180 | if (ip->fields & UIMM) | ||
181 | op |= build_uimm(va_arg(ap, u32)); | ||
182 | if (ip->fields & BIMM) | ||
183 | op |= build_bimm(va_arg(ap, s32)); | ||
184 | if (ip->fields & JIMM) | ||
185 | op |= build_jimm(va_arg(ap, u32)); | ||
186 | if (ip->fields & FUNC) | ||
187 | op |= build_func(va_arg(ap, u32)); | ||
188 | if (ip->fields & SET) | ||
189 | op |= build_set(va_arg(ap, u32)); | ||
190 | if (ip->fields & SCIMM) | ||
191 | op |= build_scimm(va_arg(ap, u32)); | ||
192 | va_end(ap); | ||
193 | |||
194 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
195 | **buf = ((op & 0xffff) << 16) | (op >> 16); | ||
196 | #else | ||
197 | **buf = op; | ||
198 | #endif | ||
199 | (*buf)++; | ||
200 | } | ||
201 | |||
202 | static inline void __uasminit | ||
203 | __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) | ||
204 | { | ||
205 | long laddr = (long)lab->addr; | ||
206 | long raddr = (long)rel->addr; | ||
207 | |||
208 | switch (rel->type) { | ||
209 | case R_MIPS_PC16: | ||
210 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
211 | *rel->addr |= (build_bimm(laddr - (raddr + 4)) << 16); | ||
212 | #else | ||
213 | *rel->addr |= build_bimm(laddr - (raddr + 4)); | ||
214 | #endif | ||
215 | break; | ||
216 | |||
217 | default: | ||
218 | panic("Unsupported Micro-assembler relocation %d", | ||
219 | rel->type); | ||
220 | } | ||
221 | } | ||
diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c new file mode 100644 index 000000000000..5fcdd8fe3e83 --- /dev/null +++ b/arch/mips/mm/uasm-mips.c | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * A small micro-assembler. It is intentionally kept simple, does only | ||
7 | * support a subset of instructions, and does not try to hide pipeline | ||
8 | * effects like branch delay slots. | ||
9 | * | ||
10 | * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer | ||
11 | * Copyright (C) 2005, 2007 Maciej W. Rozycki | ||
12 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | ||
13 | * Copyright (C) 2012, 2013 MIPS Technologies, Inc. All rights reserved. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/init.h> | ||
19 | |||
20 | #include <asm/inst.h> | ||
21 | #include <asm/elf.h> | ||
22 | #include <asm/bugs.h> | ||
23 | #define UASM_ISA _UASM_ISA_CLASSIC | ||
24 | #include <asm/uasm.h> | ||
25 | |||
26 | #define RS_MASK 0x1f | ||
27 | #define RS_SH 21 | ||
28 | #define RT_MASK 0x1f | ||
29 | #define RT_SH 16 | ||
30 | #define SCIMM_MASK 0xfffff | ||
31 | #define SCIMM_SH 6 | ||
32 | |||
33 | /* This macro sets the non-variable bits of an instruction. */ | ||
34 | #define M(a, b, c, d, e, f) \ | ||
35 | ((a) << OP_SH \ | ||
36 | | (b) << RS_SH \ | ||
37 | | (c) << RT_SH \ | ||
38 | | (d) << RD_SH \ | ||
39 | | (e) << RE_SH \ | ||
40 | | (f) << FUNC_SH) | ||
41 | |||
42 | /* Define these when we are not the ISA the kernel is being compiled with. */ | ||
43 | #ifdef CONFIG_CPU_MICROMIPS | ||
44 | #define CL_uasm_i_b(buf, off) ISAOPC(_beq)(buf, 0, 0, off) | ||
45 | #define CL_uasm_i_beqz(buf, rs, off) ISAOPC(_beq)(buf, rs, 0, off) | ||
46 | #define CL_uasm_i_beqzl(buf, rs, off) ISAOPC(_beql)(buf, rs, 0, off) | ||
47 | #define CL_uasm_i_bnez(buf, rs, off) ISAOPC(_bne)(buf, rs, 0, off) | ||
48 | #endif | ||
49 | |||
50 | #include "uasm.c" | ||
51 | |||
52 | static struct insn insn_table[] __uasminitdata = { | ||
53 | { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
54 | { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD }, | ||
55 | { insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | ||
56 | { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD }, | ||
57 | { insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
58 | { insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
59 | { insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
60 | { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
61 | { insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM }, | ||
62 | { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM }, | ||
63 | { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM }, | ||
64 | { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM }, | ||
65 | { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
66 | { insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
67 | { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
68 | { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD }, | ||
69 | { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE }, | ||
70 | { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, | ||
71 | { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
72 | { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
73 | { insn_drotr32, M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE }, | ||
74 | { insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE }, | ||
75 | { insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE }, | ||
76 | { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE }, | ||
77 | { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE }, | ||
78 | { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE }, | ||
79 | { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE }, | ||
80 | { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD }, | ||
81 | { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 }, | ||
82 | { insn_ext, M(spec3_op, 0, 0, 0, 0, ext_op), RS | RT | RD | RE }, | ||
83 | { insn_ins, M(spec3_op, 0, 0, 0, 0, ins_op), RS | RT | RD | RE }, | ||
84 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, | ||
85 | { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM }, | ||
86 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, | ||
87 | { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS }, | ||
88 | { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
89 | { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD }, | ||
90 | { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
91 | { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
92 | { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM }, | ||
93 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
94 | { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, | ||
95 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
96 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
97 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | ||
98 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, | ||
99 | { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
100 | { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, | ||
101 | { insn_rotr, M(spec_op, 1, 0, 0, 0, srl_op), RT | RD | RE }, | ||
102 | { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
103 | { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
104 | { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
105 | { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE }, | ||
106 | { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE }, | ||
107 | { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE }, | ||
108 | { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD }, | ||
109 | { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
110 | { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, | ||
111 | { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 }, | ||
112 | { insn_tlbr, M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0 }, | ||
113 | { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 }, | ||
114 | { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 }, | ||
115 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | ||
116 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, | ||
117 | { insn_invalid, 0, 0 } | ||
118 | }; | ||
119 | |||
120 | #undef M | ||
121 | |||
122 | static inline __uasminit u32 build_bimm(s32 arg) | ||
123 | { | ||
124 | WARN(arg > 0x1ffff || arg < -0x20000, | ||
125 | KERN_WARNING "Micro-assembler field overflow\n"); | ||
126 | |||
127 | WARN(arg & 0x3, KERN_WARNING "Invalid micro-assembler branch target\n"); | ||
128 | |||
129 | return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff); | ||
130 | } | ||
131 | |||
132 | static inline __uasminit u32 build_jimm(u32 arg) | ||
133 | { | ||
134 | WARN(arg & ~(JIMM_MASK << 2), | ||
135 | KERN_WARNING "Micro-assembler field overflow\n"); | ||
136 | |||
137 | return (arg >> 2) & JIMM_MASK; | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * The order of opcode arguments is implicitly left to right, | ||
142 | * starting with RS and ending with FUNC or IMM. | ||
143 | */ | ||
144 | static void __uasminit build_insn(u32 **buf, enum opcode opc, ...) | ||
145 | { | ||
146 | struct insn *ip = NULL; | ||
147 | unsigned int i; | ||
148 | va_list ap; | ||
149 | u32 op; | ||
150 | |||
151 | for (i = 0; insn_table[i].opcode != insn_invalid; i++) | ||
152 | if (insn_table[i].opcode == opc) { | ||
153 | ip = &insn_table[i]; | ||
154 | break; | ||
155 | } | ||
156 | |||
157 | if (!ip || (opc == insn_daddiu && r4k_daddiu_bug())) | ||
158 | panic("Unsupported Micro-assembler instruction %d", opc); | ||
159 | |||
160 | op = ip->match; | ||
161 | va_start(ap, opc); | ||
162 | if (ip->fields & RS) | ||
163 | op |= build_rs(va_arg(ap, u32)); | ||
164 | if (ip->fields & RT) | ||
165 | op |= build_rt(va_arg(ap, u32)); | ||
166 | if (ip->fields & RD) | ||
167 | op |= build_rd(va_arg(ap, u32)); | ||
168 | if (ip->fields & RE) | ||
169 | op |= build_re(va_arg(ap, u32)); | ||
170 | if (ip->fields & SIMM) | ||
171 | op |= build_simm(va_arg(ap, s32)); | ||
172 | if (ip->fields & UIMM) | ||
173 | op |= build_uimm(va_arg(ap, u32)); | ||
174 | if (ip->fields & BIMM) | ||
175 | op |= build_bimm(va_arg(ap, s32)); | ||
176 | if (ip->fields & JIMM) | ||
177 | op |= build_jimm(va_arg(ap, u32)); | ||
178 | if (ip->fields & FUNC) | ||
179 | op |= build_func(va_arg(ap, u32)); | ||
180 | if (ip->fields & SET) | ||
181 | op |= build_set(va_arg(ap, u32)); | ||
182 | if (ip->fields & SCIMM) | ||
183 | op |= build_scimm(va_arg(ap, u32)); | ||
184 | va_end(ap); | ||
185 | |||
186 | **buf = op; | ||
187 | (*buf)++; | ||
188 | } | ||
189 | |||
190 | static inline void __uasminit | ||
191 | __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) | ||
192 | { | ||
193 | long laddr = (long)lab->addr; | ||
194 | long raddr = (long)rel->addr; | ||
195 | |||
196 | switch (rel->type) { | ||
197 | case R_MIPS_PC16: | ||
198 | *rel->addr |= build_bimm(laddr - (raddr + 4)); | ||
199 | break; | ||
200 | |||
201 | default: | ||
202 | panic("Unsupported Micro-assembler relocation %d", | ||
203 | rel->type); | ||
204 | } | ||
205 | } | ||
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index 942ff6c2eba2..7eb5e4355d25 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c | |||
@@ -10,17 +10,9 @@ | |||
10 | * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer | 10 | * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer |
11 | * Copyright (C) 2005, 2007 Maciej W. Rozycki | 11 | * Copyright (C) 2005, 2007 Maciej W. Rozycki |
12 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | 12 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) |
13 | * Copyright (C) 2012, 2013 MIPS Technologies, Inc. All rights reserved. | ||
13 | */ | 14 | */ |
14 | 15 | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/init.h> | ||
18 | |||
19 | #include <asm/inst.h> | ||
20 | #include <asm/elf.h> | ||
21 | #include <asm/bugs.h> | ||
22 | #include <asm/uasm.h> | ||
23 | |||
24 | enum fields { | 16 | enum fields { |
25 | RS = 0x001, | 17 | RS = 0x001, |
26 | RT = 0x002, | 18 | RT = 0x002, |
@@ -37,10 +29,6 @@ enum fields { | |||
37 | 29 | ||
38 | #define OP_MASK 0x3f | 30 | #define OP_MASK 0x3f |
39 | #define OP_SH 26 | 31 | #define OP_SH 26 |
40 | #define RS_MASK 0x1f | ||
41 | #define RS_SH 21 | ||
42 | #define RT_MASK 0x1f | ||
43 | #define RT_SH 16 | ||
44 | #define RD_MASK 0x1f | 32 | #define RD_MASK 0x1f |
45 | #define RD_SH 11 | 33 | #define RD_SH 11 |
46 | #define RE_MASK 0x1f | 34 | #define RE_MASK 0x1f |
@@ -53,8 +41,6 @@ enum fields { | |||
53 | #define FUNC_SH 0 | 41 | #define FUNC_SH 0 |
54 | #define SET_MASK 0x7 | 42 | #define SET_MASK 0x7 |
55 | #define SET_SH 0 | 43 | #define SET_SH 0 |
56 | #define SCIMM_MASK 0xfffff | ||
57 | #define SCIMM_SH 6 | ||
58 | 44 | ||
59 | enum opcode { | 45 | enum opcode { |
60 | insn_invalid, | 46 | insn_invalid, |
@@ -77,85 +63,6 @@ struct insn { | |||
77 | enum fields fields; | 63 | enum fields fields; |
78 | }; | 64 | }; |
79 | 65 | ||
80 | /* This macro sets the non-variable bits of an instruction. */ | ||
81 | #define M(a, b, c, d, e, f) \ | ||
82 | ((a) << OP_SH \ | ||
83 | | (b) << RS_SH \ | ||
84 | | (c) << RT_SH \ | ||
85 | | (d) << RD_SH \ | ||
86 | | (e) << RE_SH \ | ||
87 | | (f) << FUNC_SH) | ||
88 | |||
89 | static struct insn insn_table[] __uasminitdata = { | ||
90 | { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
91 | { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD }, | ||
92 | { insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | ||
93 | { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD }, | ||
94 | { insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
95 | { insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
96 | { insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
97 | { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
98 | { insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM }, | ||
99 | { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM }, | ||
100 | { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM }, | ||
101 | { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM }, | ||
102 | { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
103 | { insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
104 | { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
105 | { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD }, | ||
106 | { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE }, | ||
107 | { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, | ||
108 | { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
109 | { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
110 | { insn_drotr32, M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE }, | ||
111 | { insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE }, | ||
112 | { insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE }, | ||
113 | { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE }, | ||
114 | { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE }, | ||
115 | { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE }, | ||
116 | { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE }, | ||
117 | { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD }, | ||
118 | { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 }, | ||
119 | { insn_ext, M(spec3_op, 0, 0, 0, 0, ext_op), RS | RT | RD | RE }, | ||
120 | { insn_ins, M(spec3_op, 0, 0, 0, 0, ins_op), RS | RT | RD | RE }, | ||
121 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, | ||
122 | { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM }, | ||
123 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, | ||
124 | { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS }, | ||
125 | { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
126 | { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD }, | ||
127 | { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
128 | { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
129 | { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM }, | ||
130 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
131 | { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, | ||
132 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
133 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
134 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | ||
135 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, | ||
136 | { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
137 | { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, | ||
138 | { insn_rotr, M(spec_op, 1, 0, 0, 0, srl_op), RT | RD | RE }, | ||
139 | { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
140 | { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
141 | { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
142 | { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE }, | ||
143 | { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE }, | ||
144 | { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE }, | ||
145 | { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD }, | ||
146 | { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
147 | { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, | ||
148 | { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 }, | ||
149 | { insn_tlbr, M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0 }, | ||
150 | { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 }, | ||
151 | { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 }, | ||
152 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | ||
153 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, | ||
154 | { insn_invalid, 0, 0 } | ||
155 | }; | ||
156 | |||
157 | #undef M | ||
158 | |||
159 | static inline __uasminit u32 build_rs(u32 arg) | 66 | static inline __uasminit u32 build_rs(u32 arg) |
160 | { | 67 | { |
161 | WARN(arg & ~RS_MASK, KERN_WARNING "Micro-assembler field overflow\n"); | 68 | WARN(arg & ~RS_MASK, KERN_WARNING "Micro-assembler field overflow\n"); |
@@ -199,24 +106,6 @@ static inline __uasminit u32 build_uimm(u32 arg) | |||
199 | return arg & IMM_MASK; | 106 | return arg & IMM_MASK; |
200 | } | 107 | } |
201 | 108 | ||
202 | static inline __uasminit u32 build_bimm(s32 arg) | ||
203 | { | ||
204 | WARN(arg > 0x1ffff || arg < -0x20000, | ||
205 | KERN_WARNING "Micro-assembler field overflow\n"); | ||
206 | |||
207 | WARN(arg & 0x3, KERN_WARNING "Invalid micro-assembler branch target\n"); | ||
208 | |||
209 | return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff); | ||
210 | } | ||
211 | |||
212 | static inline __uasminit u32 build_jimm(u32 arg) | ||
213 | { | ||
214 | WARN(arg & ~(JIMM_MASK << 2), | ||
215 | KERN_WARNING "Micro-assembler field overflow\n"); | ||
216 | |||
217 | return (arg >> 2) & JIMM_MASK; | ||
218 | } | ||
219 | |||
220 | static inline __uasminit u32 build_scimm(u32 arg) | 109 | static inline __uasminit u32 build_scimm(u32 arg) |
221 | { | 110 | { |
222 | WARN(arg & ~SCIMM_MASK, | 111 | WARN(arg & ~SCIMM_MASK, |
@@ -239,55 +128,7 @@ static inline __uasminit u32 build_set(u32 arg) | |||
239 | return arg & SET_MASK; | 128 | return arg & SET_MASK; |
240 | } | 129 | } |
241 | 130 | ||
242 | /* | 131 | static void __uasminit build_insn(u32 **buf, enum opcode opc, ...); |
243 | * The order of opcode arguments is implicitly left to right, | ||
244 | * starting with RS and ending with FUNC or IMM. | ||
245 | */ | ||
246 | static void __uasminit build_insn(u32 **buf, enum opcode opc, ...) | ||
247 | { | ||
248 | struct insn *ip = NULL; | ||
249 | unsigned int i; | ||
250 | va_list ap; | ||
251 | u32 op; | ||
252 | |||
253 | for (i = 0; insn_table[i].opcode != insn_invalid; i++) | ||
254 | if (insn_table[i].opcode == opc) { | ||
255 | ip = &insn_table[i]; | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | if (!ip || (opc == insn_daddiu && r4k_daddiu_bug())) | ||
260 | panic("Unsupported Micro-assembler instruction %d", opc); | ||
261 | |||
262 | op = ip->match; | ||
263 | va_start(ap, opc); | ||
264 | if (ip->fields & RS) | ||
265 | op |= build_rs(va_arg(ap, u32)); | ||
266 | if (ip->fields & RT) | ||
267 | op |= build_rt(va_arg(ap, u32)); | ||
268 | if (ip->fields & RD) | ||
269 | op |= build_rd(va_arg(ap, u32)); | ||
270 | if (ip->fields & RE) | ||
271 | op |= build_re(va_arg(ap, u32)); | ||
272 | if (ip->fields & SIMM) | ||
273 | op |= build_simm(va_arg(ap, s32)); | ||
274 | if (ip->fields & UIMM) | ||
275 | op |= build_uimm(va_arg(ap, u32)); | ||
276 | if (ip->fields & BIMM) | ||
277 | op |= build_bimm(va_arg(ap, s32)); | ||
278 | if (ip->fields & JIMM) | ||
279 | op |= build_jimm(va_arg(ap, u32)); | ||
280 | if (ip->fields & FUNC) | ||
281 | op |= build_func(va_arg(ap, u32)); | ||
282 | if (ip->fields & SET) | ||
283 | op |= build_set(va_arg(ap, u32)); | ||
284 | if (ip->fields & SCIMM) | ||
285 | op |= build_scimm(va_arg(ap, u32)); | ||
286 | va_end(ap); | ||
287 | |||
288 | **buf = op; | ||
289 | (*buf)++; | ||
290 | } | ||
291 | 132 | ||
292 | #define I_u1u2u3(op) \ | 133 | #define I_u1u2u3(op) \ |
293 | Ip_u1u2u3(op) \ | 134 | Ip_u1u2u3(op) \ |
@@ -445,7 +286,7 @@ I_u3u1u2(_ldx) | |||
445 | 286 | ||
446 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | 287 | #ifdef CONFIG_CPU_CAVIUM_OCTEON |
447 | #include <asm/octeon/octeon.h> | 288 | #include <asm/octeon/octeon.h> |
448 | void __uasminit uasm_i_pref(u32 **buf, unsigned int a, signed int b, | 289 | void __uasminit ISAFUNC(uasm_i_pref)(u32 **buf, unsigned int a, signed int b, |
449 | unsigned int c) | 290 | unsigned int c) |
450 | { | 291 | { |
451 | if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) && a <= 24 && a != 5) | 292 | if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) && a <= 24 && a != 5) |
@@ -457,21 +298,21 @@ void __uasminit uasm_i_pref(u32 **buf, unsigned int a, signed int b, | |||
457 | else | 298 | else |
458 | build_insn(buf, insn_pref, c, a, b); | 299 | build_insn(buf, insn_pref, c, a, b); |
459 | } | 300 | } |
460 | UASM_EXPORT_SYMBOL(uasm_i_pref); | 301 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_i_pref)); |
461 | #else | 302 | #else |
462 | I_u2s3u1(_pref) | 303 | I_u2s3u1(_pref) |
463 | #endif | 304 | #endif |
464 | 305 | ||
465 | /* Handle labels. */ | 306 | /* Handle labels. */ |
466 | void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) | 307 | void __uasminit ISAFUNC(uasm_build_label)(struct uasm_label **lab, u32 *addr, int lid) |
467 | { | 308 | { |
468 | (*lab)->addr = addr; | 309 | (*lab)->addr = addr; |
469 | (*lab)->lab = lid; | 310 | (*lab)->lab = lid; |
470 | (*lab)++; | 311 | (*lab)++; |
471 | } | 312 | } |
472 | UASM_EXPORT_SYMBOL(uasm_build_label); | 313 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_build_label)); |
473 | 314 | ||
474 | int __uasminit uasm_in_compat_space_p(long addr) | 315 | int __uasminit ISAFUNC(uasm_in_compat_space_p)(long addr) |
475 | { | 316 | { |
476 | /* Is this address in 32bit compat space? */ | 317 | /* Is this address in 32bit compat space? */ |
477 | #ifdef CONFIG_64BIT | 318 | #ifdef CONFIG_64BIT |
@@ -480,7 +321,7 @@ int __uasminit uasm_in_compat_space_p(long addr) | |||
480 | return 1; | 321 | return 1; |
481 | #endif | 322 | #endif |
482 | } | 323 | } |
483 | UASM_EXPORT_SYMBOL(uasm_in_compat_space_p); | 324 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_in_compat_space_p)); |
484 | 325 | ||
485 | static int __uasminit uasm_rel_highest(long val) | 326 | static int __uasminit uasm_rel_highest(long val) |
486 | { | 327 | { |
@@ -500,77 +341,66 @@ static int __uasminit uasm_rel_higher(long val) | |||
500 | #endif | 341 | #endif |
501 | } | 342 | } |
502 | 343 | ||
503 | int __uasminit uasm_rel_hi(long val) | 344 | int __uasminit ISAFUNC(uasm_rel_hi)(long val) |
504 | { | 345 | { |
505 | return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000; | 346 | return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000; |
506 | } | 347 | } |
507 | UASM_EXPORT_SYMBOL(uasm_rel_hi); | 348 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_rel_hi)); |
508 | 349 | ||
509 | int __uasminit uasm_rel_lo(long val) | 350 | int __uasminit ISAFUNC(uasm_rel_lo)(long val) |
510 | { | 351 | { |
511 | return ((val & 0xffff) ^ 0x8000) - 0x8000; | 352 | return ((val & 0xffff) ^ 0x8000) - 0x8000; |
512 | } | 353 | } |
513 | UASM_EXPORT_SYMBOL(uasm_rel_lo); | 354 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_rel_lo)); |
514 | 355 | ||
515 | void __uasminit UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr) | 356 | void __uasminit ISAFUNC(UASM_i_LA_mostly)(u32 **buf, unsigned int rs, long addr) |
516 | { | 357 | { |
517 | if (!uasm_in_compat_space_p(addr)) { | 358 | if (!ISAFUNC(uasm_in_compat_space_p)(addr)) { |
518 | uasm_i_lui(buf, rs, uasm_rel_highest(addr)); | 359 | ISAFUNC(uasm_i_lui)(buf, rs, uasm_rel_highest(addr)); |
519 | if (uasm_rel_higher(addr)) | 360 | if (uasm_rel_higher(addr)) |
520 | uasm_i_daddiu(buf, rs, rs, uasm_rel_higher(addr)); | 361 | ISAFUNC(uasm_i_daddiu)(buf, rs, rs, uasm_rel_higher(addr)); |
521 | if (uasm_rel_hi(addr)) { | 362 | if (ISAFUNC(uasm_rel_hi(addr))) { |
522 | uasm_i_dsll(buf, rs, rs, 16); | 363 | ISAFUNC(uasm_i_dsll)(buf, rs, rs, 16); |
523 | uasm_i_daddiu(buf, rs, rs, uasm_rel_hi(addr)); | 364 | ISAFUNC(uasm_i_daddiu)(buf, rs, rs, |
524 | uasm_i_dsll(buf, rs, rs, 16); | 365 | ISAFUNC(uasm_rel_hi)(addr)); |
366 | ISAFUNC(uasm_i_dsll)(buf, rs, rs, 16); | ||
525 | } else | 367 | } else |
526 | uasm_i_dsll32(buf, rs, rs, 0); | 368 | ISAFUNC(uasm_i_dsll32)(buf, rs, rs, 0); |
527 | } else | 369 | } else |
528 | uasm_i_lui(buf, rs, uasm_rel_hi(addr)); | 370 | ISAFUNC(uasm_i_lui)(buf, rs, ISAFUNC(uasm_rel_hi(addr))); |
529 | } | 371 | } |
530 | UASM_EXPORT_SYMBOL(UASM_i_LA_mostly); | 372 | UASM_EXPORT_SYMBOL(ISAFUNC(UASM_i_LA_mostly)); |
531 | 373 | ||
532 | void __uasminit UASM_i_LA(u32 **buf, unsigned int rs, long addr) | 374 | void __uasminit ISAFUNC(UASM_i_LA)(u32 **buf, unsigned int rs, long addr) |
533 | { | 375 | { |
534 | UASM_i_LA_mostly(buf, rs, addr); | 376 | ISAFUNC(UASM_i_LA_mostly)(buf, rs, addr); |
535 | if (uasm_rel_lo(addr)) { | 377 | if (ISAFUNC(uasm_rel_lo(addr))) { |
536 | if (!uasm_in_compat_space_p(addr)) | 378 | if (!ISAFUNC(uasm_in_compat_space_p)(addr)) |
537 | uasm_i_daddiu(buf, rs, rs, uasm_rel_lo(addr)); | 379 | ISAFUNC(uasm_i_daddiu)(buf, rs, rs, |
380 | ISAFUNC(uasm_rel_lo(addr))); | ||
538 | else | 381 | else |
539 | uasm_i_addiu(buf, rs, rs, uasm_rel_lo(addr)); | 382 | ISAFUNC(uasm_i_addiu)(buf, rs, rs, |
383 | ISAFUNC(uasm_rel_lo(addr))); | ||
540 | } | 384 | } |
541 | } | 385 | } |
542 | UASM_EXPORT_SYMBOL(UASM_i_LA); | 386 | UASM_EXPORT_SYMBOL(ISAFUNC(UASM_i_LA)); |
543 | 387 | ||
544 | /* Handle relocations. */ | 388 | /* Handle relocations. */ |
545 | void __uasminit | 389 | void __uasminit |
546 | uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid) | 390 | ISAFUNC(uasm_r_mips_pc16)(struct uasm_reloc **rel, u32 *addr, int lid) |
547 | { | 391 | { |
548 | (*rel)->addr = addr; | 392 | (*rel)->addr = addr; |
549 | (*rel)->type = R_MIPS_PC16; | 393 | (*rel)->type = R_MIPS_PC16; |
550 | (*rel)->lab = lid; | 394 | (*rel)->lab = lid; |
551 | (*rel)++; | 395 | (*rel)++; |
552 | } | 396 | } |
553 | UASM_EXPORT_SYMBOL(uasm_r_mips_pc16); | 397 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_r_mips_pc16)); |
554 | 398 | ||
555 | static inline void __uasminit | 399 | static inline void __uasminit |
556 | __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) | 400 | __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab); |
557 | { | ||
558 | long laddr = (long)lab->addr; | ||
559 | long raddr = (long)rel->addr; | ||
560 | |||
561 | switch (rel->type) { | ||
562 | case R_MIPS_PC16: | ||
563 | *rel->addr |= build_bimm(laddr - (raddr + 4)); | ||
564 | break; | ||
565 | |||
566 | default: | ||
567 | panic("Unsupported Micro-assembler relocation %d", | ||
568 | rel->type); | ||
569 | } | ||
570 | } | ||
571 | 401 | ||
572 | void __uasminit | 402 | void __uasminit |
573 | uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) | 403 | ISAFUNC(uasm_resolve_relocs)(struct uasm_reloc *rel, struct uasm_label *lab) |
574 | { | 404 | { |
575 | struct uasm_label *l; | 405 | struct uasm_label *l; |
576 | 406 | ||
@@ -579,40 +409,40 @@ uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) | |||
579 | if (rel->lab == l->lab) | 409 | if (rel->lab == l->lab) |
580 | __resolve_relocs(rel, l); | 410 | __resolve_relocs(rel, l); |
581 | } | 411 | } |
582 | UASM_EXPORT_SYMBOL(uasm_resolve_relocs); | 412 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_resolve_relocs)); |
583 | 413 | ||
584 | void __uasminit | 414 | void __uasminit |
585 | uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off) | 415 | ISAFUNC(uasm_move_relocs)(struct uasm_reloc *rel, u32 *first, u32 *end, long off) |
586 | { | 416 | { |
587 | for (; rel->lab != UASM_LABEL_INVALID; rel++) | 417 | for (; rel->lab != UASM_LABEL_INVALID; rel++) |
588 | if (rel->addr >= first && rel->addr < end) | 418 | if (rel->addr >= first && rel->addr < end) |
589 | rel->addr += off; | 419 | rel->addr += off; |
590 | } | 420 | } |
591 | UASM_EXPORT_SYMBOL(uasm_move_relocs); | 421 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_move_relocs)); |
592 | 422 | ||
593 | void __uasminit | 423 | void __uasminit |
594 | uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off) | 424 | ISAFUNC(uasm_move_labels)(struct uasm_label *lab, u32 *first, u32 *end, long off) |
595 | { | 425 | { |
596 | for (; lab->lab != UASM_LABEL_INVALID; lab++) | 426 | for (; lab->lab != UASM_LABEL_INVALID; lab++) |
597 | if (lab->addr >= first && lab->addr < end) | 427 | if (lab->addr >= first && lab->addr < end) |
598 | lab->addr += off; | 428 | lab->addr += off; |
599 | } | 429 | } |
600 | UASM_EXPORT_SYMBOL(uasm_move_labels); | 430 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_move_labels)); |
601 | 431 | ||
602 | void __uasminit | 432 | void __uasminit |
603 | uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first, | 433 | ISAFUNC(uasm_copy_handler)(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first, |
604 | u32 *end, u32 *target) | 434 | u32 *end, u32 *target) |
605 | { | 435 | { |
606 | long off = (long)(target - first); | 436 | long off = (long)(target - first); |
607 | 437 | ||
608 | memcpy(target, first, (end - first) * sizeof(u32)); | 438 | memcpy(target, first, (end - first) * sizeof(u32)); |
609 | 439 | ||
610 | uasm_move_relocs(rel, first, end, off); | 440 | ISAFUNC(uasm_move_relocs(rel, first, end, off)); |
611 | uasm_move_labels(lab, first, end, off); | 441 | ISAFUNC(uasm_move_labels(lab, first, end, off)); |
612 | } | 442 | } |
613 | UASM_EXPORT_SYMBOL(uasm_copy_handler); | 443 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_copy_handler)); |
614 | 444 | ||
615 | int __uasminit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr) | 445 | int __uasminit ISAFUNC(uasm_insn_has_bdelay)(struct uasm_reloc *rel, u32 *addr) |
616 | { | 446 | { |
617 | for (; rel->lab != UASM_LABEL_INVALID; rel++) { | 447 | for (; rel->lab != UASM_LABEL_INVALID; rel++) { |
618 | if (rel->addr == addr | 448 | if (rel->addr == addr |
@@ -623,88 +453,88 @@ int __uasminit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr) | |||
623 | 453 | ||
624 | return 0; | 454 | return 0; |
625 | } | 455 | } |
626 | UASM_EXPORT_SYMBOL(uasm_insn_has_bdelay); | 456 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_insn_has_bdelay)); |
627 | 457 | ||
628 | /* Convenience functions for labeled branches. */ | 458 | /* Convenience functions for labeled branches. */ |
629 | void __uasminit | 459 | void __uasminit |
630 | uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 460 | ISAFUNC(uasm_il_bltz)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
631 | { | 461 | { |
632 | uasm_r_mips_pc16(r, *p, lid); | 462 | uasm_r_mips_pc16(r, *p, lid); |
633 | uasm_i_bltz(p, reg, 0); | 463 | ISAFUNC(uasm_i_bltz)(p, reg, 0); |
634 | } | 464 | } |
635 | UASM_EXPORT_SYMBOL(uasm_il_bltz); | 465 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bltz)); |
636 | 466 | ||
637 | void __uasminit | 467 | void __uasminit |
638 | uasm_il_b(u32 **p, struct uasm_reloc **r, int lid) | 468 | ISAFUNC(uasm_il_b)(u32 **p, struct uasm_reloc **r, int lid) |
639 | { | 469 | { |
640 | uasm_r_mips_pc16(r, *p, lid); | 470 | uasm_r_mips_pc16(r, *p, lid); |
641 | uasm_i_b(p, 0); | 471 | ISAFUNC(uasm_i_b)(p, 0); |
642 | } | 472 | } |
643 | UASM_EXPORT_SYMBOL(uasm_il_b); | 473 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_b)); |
644 | 474 | ||
645 | void __uasminit | 475 | void __uasminit |
646 | uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 476 | ISAFUNC(uasm_il_beqz)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
647 | { | 477 | { |
648 | uasm_r_mips_pc16(r, *p, lid); | 478 | uasm_r_mips_pc16(r, *p, lid); |
649 | uasm_i_beqz(p, reg, 0); | 479 | ISAFUNC(uasm_i_beqz)(p, reg, 0); |
650 | } | 480 | } |
651 | UASM_EXPORT_SYMBOL(uasm_il_beqz); | 481 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_beqz)); |
652 | 482 | ||
653 | void __uasminit | 483 | void __uasminit |
654 | uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 484 | ISAFUNC(uasm_il_beqzl)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
655 | { | 485 | { |
656 | uasm_r_mips_pc16(r, *p, lid); | 486 | uasm_r_mips_pc16(r, *p, lid); |
657 | uasm_i_beqzl(p, reg, 0); | 487 | ISAFUNC(uasm_i_beqzl)(p, reg, 0); |
658 | } | 488 | } |
659 | UASM_EXPORT_SYMBOL(uasm_il_beqzl); | 489 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_beqzl)); |
660 | 490 | ||
661 | void __uasminit | 491 | void __uasminit |
662 | uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1, | 492 | ISAFUNC(uasm_il_bne)(u32 **p, struct uasm_reloc **r, unsigned int reg1, |
663 | unsigned int reg2, int lid) | 493 | unsigned int reg2, int lid) |
664 | { | 494 | { |
665 | uasm_r_mips_pc16(r, *p, lid); | 495 | uasm_r_mips_pc16(r, *p, lid); |
666 | uasm_i_bne(p, reg1, reg2, 0); | 496 | ISAFUNC(uasm_i_bne)(p, reg1, reg2, 0); |
667 | } | 497 | } |
668 | UASM_EXPORT_SYMBOL(uasm_il_bne); | 498 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bne)); |
669 | 499 | ||
670 | void __uasminit | 500 | void __uasminit |
671 | uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 501 | ISAFUNC(uasm_il_bnez)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
672 | { | 502 | { |
673 | uasm_r_mips_pc16(r, *p, lid); | 503 | uasm_r_mips_pc16(r, *p, lid); |
674 | uasm_i_bnez(p, reg, 0); | 504 | ISAFUNC(uasm_i_bnez)(p, reg, 0); |
675 | } | 505 | } |
676 | UASM_EXPORT_SYMBOL(uasm_il_bnez); | 506 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bnez)); |
677 | 507 | ||
678 | void __uasminit | 508 | void __uasminit |
679 | uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 509 | ISAFUNC(uasm_il_bgezl)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
680 | { | 510 | { |
681 | uasm_r_mips_pc16(r, *p, lid); | 511 | uasm_r_mips_pc16(r, *p, lid); |
682 | uasm_i_bgezl(p, reg, 0); | 512 | ISAFUNC(uasm_i_bgezl)(p, reg, 0); |
683 | } | 513 | } |
684 | UASM_EXPORT_SYMBOL(uasm_il_bgezl); | 514 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bgezl)); |
685 | 515 | ||
686 | void __uasminit | 516 | void __uasminit |
687 | uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 517 | ISAFUNC(uasm_il_bgez)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
688 | { | 518 | { |
689 | uasm_r_mips_pc16(r, *p, lid); | 519 | uasm_r_mips_pc16(r, *p, lid); |
690 | uasm_i_bgez(p, reg, 0); | 520 | ISAFUNC(uasm_i_bgez)(p, reg, 0); |
691 | } | 521 | } |
692 | UASM_EXPORT_SYMBOL(uasm_il_bgez); | 522 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bgez)); |
693 | 523 | ||
694 | void __uasminit | 524 | void __uasminit |
695 | uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg, | 525 | ISAFUNC(uasm_il_bbit0)(u32 **p, struct uasm_reloc **r, unsigned int reg, |
696 | unsigned int bit, int lid) | 526 | unsigned int bit, int lid) |
697 | { | 527 | { |
698 | uasm_r_mips_pc16(r, *p, lid); | 528 | uasm_r_mips_pc16(r, *p, lid); |
699 | uasm_i_bbit0(p, reg, bit, 0); | 529 | ISAFUNC(uasm_i_bbit0)(p, reg, bit, 0); |
700 | } | 530 | } |
701 | UASM_EXPORT_SYMBOL(uasm_il_bbit0); | 531 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bbit0)); |
702 | 532 | ||
703 | void __uasminit | 533 | void __uasminit |
704 | uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg, | 534 | ISAFUNC(uasm_il_bbit1)(u32 **p, struct uasm_reloc **r, unsigned int reg, |
705 | unsigned int bit, int lid) | 535 | unsigned int bit, int lid) |
706 | { | 536 | { |
707 | uasm_r_mips_pc16(r, *p, lid); | 537 | uasm_r_mips_pc16(r, *p, lid); |
708 | uasm_i_bbit1(p, reg, bit, 0); | 538 | ISAFUNC(uasm_i_bbit1)(p, reg, bit, 0); |
709 | } | 539 | } |
710 | UASM_EXPORT_SYMBOL(uasm_il_bbit1); | 540 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bbit1)); |
diff --git a/arch/mips/mti-malta/Makefile b/arch/mips/mti-malta/Makefile index 6079ef33b5f0..0388fc8b5613 100644 --- a/arch/mips/mti-malta/Makefile +++ b/arch/mips/mti-malta/Makefile | |||
@@ -5,9 +5,8 @@ | |||
5 | # Copyright (C) 2008 Wind River Systems, Inc. | 5 | # Copyright (C) 2008 Wind River Systems, Inc. |
6 | # written by Ralf Baechle <ralf@linux-mips.org> | 6 | # written by Ralf Baechle <ralf@linux-mips.org> |
7 | # | 7 | # |
8 | obj-y := malta-amon.o malta-cmdline.o \ | 8 | obj-y := malta-amon.o malta-display.o malta-init.o \ |
9 | malta-display.o malta-init.o malta-int.o \ | 9 | malta-int.o malta-memory.o malta-platform.o \ |
10 | malta-memory.o malta-platform.o \ | ||
11 | malta-reset.o malta-setup.o malta-time.o | 10 | malta-reset.o malta-setup.o malta-time.o |
12 | 11 | ||
13 | obj-$(CONFIG_EARLY_PRINTK) += malta-console.o | 12 | obj-$(CONFIG_EARLY_PRINTK) += malta-console.o |
diff --git a/arch/mips/mti-malta/malta-cmdline.c b/arch/mips/mti-malta/malta-cmdline.c deleted file mode 100644 index 5576a306a145..000000000000 --- a/arch/mips/mti-malta/malta-cmdline.c +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Kernel command line creation using the prom monitor (YAMON) argc/argv. | ||
19 | */ | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/string.h> | ||
22 | |||
23 | #include <asm/bootinfo.h> | ||
24 | |||
25 | extern int prom_argc; | ||
26 | extern int *_prom_argv; | ||
27 | |||
28 | /* | ||
29 | * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | ||
30 | * This macro take care of sign extension. | ||
31 | */ | ||
32 | #define prom_argv(index) ((char *)(long)_prom_argv[(index)]) | ||
33 | |||
34 | char * __init prom_getcmdline(void) | ||
35 | { | ||
36 | return &(arcs_cmdline[0]); | ||
37 | } | ||
38 | |||
39 | |||
40 | void __init prom_init_cmdline(void) | ||
41 | { | ||
42 | char *cp; | ||
43 | int actr; | ||
44 | |||
45 | actr = 1; /* Always ignore argv[0] */ | ||
46 | |||
47 | cp = &(arcs_cmdline[0]); | ||
48 | while(actr < prom_argc) { | ||
49 | strcpy(cp, prom_argv(actr)); | ||
50 | cp += strlen(prom_argv(actr)); | ||
51 | *cp++ = ' '; | ||
52 | actr++; | ||
53 | } | ||
54 | if (cp != &(arcs_cmdline[0])) { | ||
55 | /* get rid of trailing space */ | ||
56 | --cp; | ||
57 | *cp = '\0'; | ||
58 | } | ||
59 | } | ||
diff --git a/arch/mips/mti-malta/malta-display.c b/arch/mips/mti-malta/malta-display.c index 9bc58a24e80a..d4f807191ecd 100644 --- a/arch/mips/mti-malta/malta-display.c +++ b/arch/mips/mti-malta/malta-display.c | |||
@@ -1,28 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * Carsten Langgaard, carstenl@mips.com | 2 | * This file is subject to the terms and conditions of the GNU General Public |
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * | 4 | * for more details. |
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | 5 | * |
18 | * Display routines for display messages in MIPS boards ascii display. | 6 | * Display routines for display messages in MIPS boards ascii display. |
7 | * | ||
8 | * Copyright (C) 1999,2000,2012 MIPS Technologies, Inc. | ||
9 | * All rights reserved. | ||
10 | * Authors: Carsten Langgaard <carstenl@mips.com> | ||
11 | * Steven J. Hill <sjhill@mips.com> | ||
19 | */ | 12 | */ |
20 | |||
21 | #include <linux/compiler.h> | 13 | #include <linux/compiler.h> |
22 | #include <linux/timer.h> | 14 | #include <linux/timer.h> |
23 | #include <asm/io.h> | 15 | #include <linux/io.h> |
16 | |||
24 | #include <asm/mips-boards/generic.h> | 17 | #include <asm/mips-boards/generic.h> |
25 | #include <asm/mips-boards/prom.h> | ||
26 | 18 | ||
27 | extern const char display_string[]; | 19 | extern const char display_string[]; |
28 | static unsigned int display_count; | 20 | static unsigned int display_count; |
@@ -36,11 +28,11 @@ void mips_display_message(const char *str) | |||
36 | if (unlikely(display == NULL)) | 28 | if (unlikely(display == NULL)) |
37 | display = ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int)); | 29 | display = ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int)); |
38 | 30 | ||
39 | for (i = 0; i <= 14; i=i+2) { | 31 | for (i = 0; i <= 14; i += 2) { |
40 | if (*str) | 32 | if (*str) |
41 | __raw_writel(*str++, display + i); | 33 | __raw_writel(*str++, display + i); |
42 | else | 34 | else |
43 | __raw_writel(' ', display + i); | 35 | __raw_writel(' ', display + i); |
44 | } | 36 | } |
45 | } | 37 | } |
46 | 38 | ||
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index c2cbce9e435e..ff8caffd3266 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c | |||
@@ -1,54 +1,28 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc. | 2 | * This file is subject to the terms and conditions of the GNU General Public |
3 | * All rights reserved. | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * Authors: Carsten Langgaard <carstenl@mips.com> | 4 | * for more details. |
5 | * Maciej W. Rozycki <macro@mips.com> | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | 5 | * |
20 | * PROM library initialisation code. | 6 | * PROM library initialisation code. |
7 | * | ||
8 | * Copyright (C) 1999,2000,2004,2005,2012 MIPS Technologies, Inc. | ||
9 | * All rights reserved. | ||
10 | * Authors: Carsten Langgaard <carstenl@mips.com> | ||
11 | * Maciej W. Rozycki <macro@mips.com> | ||
12 | * Steven J. Hill <sjhill@mips.com> | ||
21 | */ | 13 | */ |
22 | #include <linux/init.h> | 14 | #include <linux/init.h> |
23 | #include <linux/string.h> | 15 | #include <linux/string.h> |
24 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
25 | 17 | ||
26 | #include <asm/bootinfo.h> | ||
27 | #include <asm/gt64120.h> | ||
28 | #include <asm/io.h> | ||
29 | #include <asm/cacheflush.h> | 18 | #include <asm/cacheflush.h> |
30 | #include <asm/smp-ops.h> | 19 | #include <asm/smp-ops.h> |
31 | #include <asm/traps.h> | 20 | #include <asm/traps.h> |
32 | 21 | #include <asm/fw/fw.h> | |
33 | #include <asm/gcmpregs.h> | 22 | #include <asm/gcmpregs.h> |
34 | #include <asm/mips-boards/prom.h> | ||
35 | #include <asm/mips-boards/generic.h> | 23 | #include <asm/mips-boards/generic.h> |
36 | #include <asm/mips-boards/bonito64.h> | ||
37 | #include <asm/mips-boards/msc01_pci.h> | ||
38 | |||
39 | #include <asm/mips-boards/malta.h> | 24 | #include <asm/mips-boards/malta.h> |
40 | 25 | ||
41 | int prom_argc; | ||
42 | int *_prom_argv, *_prom_envp; | ||
43 | |||
44 | /* | ||
45 | * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | ||
46 | * This macro take care of sign extension, if running in 64-bit mode. | ||
47 | */ | ||
48 | #define prom_envp(index) ((char *)(long)_prom_envp[(index)]) | ||
49 | |||
50 | int init_debug; | ||
51 | |||
52 | static int mips_revision_corid; | 26 | static int mips_revision_corid; |
53 | int mips_revision_sconid; | 27 | int mips_revision_sconid; |
54 | 28 | ||
@@ -62,74 +36,6 @@ unsigned long _pcictrl_gt64120; | |||
62 | /* MIPS System controller register base */ | 36 | /* MIPS System controller register base */ |
63 | unsigned long _pcictrl_msc; | 37 | unsigned long _pcictrl_msc; |
64 | 38 | ||
65 | char *prom_getenv(char *envname) | ||
66 | { | ||
67 | /* | ||
68 | * Return a pointer to the given environment variable. | ||
69 | * In 64-bit mode: we're using 64-bit pointers, but all pointers | ||
70 | * in the PROM structures are only 32-bit, so we need some | ||
71 | * workarounds, if we are running in 64-bit mode. | ||
72 | */ | ||
73 | int i, index=0; | ||
74 | |||
75 | i = strlen(envname); | ||
76 | |||
77 | while (prom_envp(index)) { | ||
78 | if(strncmp(envname, prom_envp(index), i) == 0) { | ||
79 | return(prom_envp(index+1)); | ||
80 | } | ||
81 | index += 2; | ||
82 | } | ||
83 | |||
84 | return NULL; | ||
85 | } | ||
86 | |||
87 | static inline unsigned char str2hexnum(unsigned char c) | ||
88 | { | ||
89 | if (c >= '0' && c <= '9') | ||
90 | return c - '0'; | ||
91 | if (c >= 'a' && c <= 'f') | ||
92 | return c - 'a' + 10; | ||
93 | return 0; /* foo */ | ||
94 | } | ||
95 | |||
96 | static inline void str2eaddr(unsigned char *ea, unsigned char *str) | ||
97 | { | ||
98 | int i; | ||
99 | |||
100 | for (i = 0; i < 6; i++) { | ||
101 | unsigned char num; | ||
102 | |||
103 | if((*str == '.') || (*str == ':')) | ||
104 | str++; | ||
105 | num = str2hexnum(*str++) << 4; | ||
106 | num |= (str2hexnum(*str++)); | ||
107 | ea[i] = num; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | int get_ethernet_addr(char *ethernet_addr) | ||
112 | { | ||
113 | char *ethaddr_str; | ||
114 | |||
115 | ethaddr_str = prom_getenv("ethaddr"); | ||
116 | if (!ethaddr_str) { | ||
117 | printk("ethaddr not set in boot prom\n"); | ||
118 | return -1; | ||
119 | } | ||
120 | str2eaddr(ethernet_addr, ethaddr_str); | ||
121 | |||
122 | if (init_debug > 1) { | ||
123 | int i; | ||
124 | printk("get_ethernet_addr: "); | ||
125 | for (i=0; i<5; i++) | ||
126 | printk("%02x:", (unsigned char)*(ethernet_addr+i)); | ||
127 | printk("%02x\n", *(ethernet_addr+i)); | ||
128 | } | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 39 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
134 | static void __init console_config(void) | 40 | static void __init console_config(void) |
135 | { | 41 | { |
@@ -138,17 +44,23 @@ static void __init console_config(void) | |||
138 | char parity = '\0', bits = '\0', flow = '\0'; | 44 | char parity = '\0', bits = '\0', flow = '\0'; |
139 | char *s; | 45 | char *s; |
140 | 46 | ||
141 | if ((strstr(prom_getcmdline(), "console=")) == NULL) { | 47 | if ((strstr(fw_getcmdline(), "console=")) == NULL) { |
142 | s = prom_getenv("modetty0"); | 48 | s = fw_getenv("modetty0"); |
143 | if (s) { | 49 | if (s) { |
144 | while (*s >= '0' && *s <= '9') | 50 | while (*s >= '0' && *s <= '9') |
145 | baud = baud*10 + *s++ - '0'; | 51 | baud = baud*10 + *s++ - '0'; |
146 | if (*s == ',') s++; | 52 | if (*s == ',') |
147 | if (*s) parity = *s++; | 53 | s++; |
148 | if (*s == ',') s++; | 54 | if (*s) |
149 | if (*s) bits = *s++; | 55 | parity = *s++; |
150 | if (*s == ',') s++; | 56 | if (*s == ',') |
151 | if (*s == 'h') flow = 'r'; | 57 | s++; |
58 | if (*s) | ||
59 | bits = *s++; | ||
60 | if (*s == ',') | ||
61 | s++; | ||
62 | if (*s == 'h') | ||
63 | flow = 'r'; | ||
152 | } | 64 | } |
153 | if (baud == 0) | 65 | if (baud == 0) |
154 | baud = 38400; | 66 | baud = 38400; |
@@ -158,8 +70,9 @@ static void __init console_config(void) | |||
158 | bits = '8'; | 70 | bits = '8'; |
159 | if (flow == '\0') | 71 | if (flow == '\0') |
160 | flow = 'r'; | 72 | flow = 'r'; |
161 | sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow); | 73 | sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, |
162 | strcat(prom_getcmdline(), console_string); | 74 | parity, bits, flow); |
75 | strcat(fw_getcmdline(), console_string); | ||
163 | pr_info("Config serial console:%s\n", console_string); | 76 | pr_info("Config serial console:%s\n", console_string); |
164 | } | 77 | } |
165 | } | 78 | } |
@@ -193,10 +106,6 @@ extern struct plat_smp_ops msmtc_smp_ops; | |||
193 | 106 | ||
194 | void __init prom_init(void) | 107 | void __init prom_init(void) |
195 | { | 108 | { |
196 | prom_argc = fw_arg0; | ||
197 | _prom_argv = (int *) fw_arg1; | ||
198 | _prom_envp = (int *) fw_arg2; | ||
199 | |||
200 | mips_display_message("LINUX"); | 109 | mips_display_message("LINUX"); |
201 | 110 | ||
202 | /* | 111 | /* |
@@ -306,7 +215,7 @@ void __init prom_init(void) | |||
306 | case MIPS_REVISION_SCON_SOCIT: | 215 | case MIPS_REVISION_SCON_SOCIT: |
307 | case MIPS_REVISION_SCON_ROCIT: | 216 | case MIPS_REVISION_SCON_ROCIT: |
308 | _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); | 217 | _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); |
309 | mips_pci_controller: | 218 | mips_pci_controller: |
310 | mb(); | 219 | mb(); |
311 | MSC_READ(MSC01_PCI_CFG, data); | 220 | MSC_READ(MSC01_PCI_CFG, data); |
312 | MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT); | 221 | MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT); |
@@ -348,13 +257,13 @@ void __init prom_init(void) | |||
348 | default: | 257 | default: |
349 | /* Unknown system controller */ | 258 | /* Unknown system controller */ |
350 | mips_display_message("SC Error"); | 259 | mips_display_message("SC Error"); |
351 | while (1); /* We die here... */ | 260 | while (1); /* We die here... */ |
352 | } | 261 | } |
353 | board_nmi_handler_setup = mips_nmi_setup; | 262 | board_nmi_handler_setup = mips_nmi_setup; |
354 | board_ejtag_handler_setup = mips_ejtag_setup; | 263 | board_ejtag_handler_setup = mips_ejtag_setup; |
355 | 264 | ||
356 | prom_init_cmdline(); | 265 | fw_init_cmdline(); |
357 | prom_meminit(); | 266 | fw_meminit(); |
358 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 267 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
359 | console_config(); | 268 | console_config(); |
360 | #endif | 269 | #endif |
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index e364af70e6cf..0a1339ac3ec8 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <asm/setup.h> | 47 | #include <asm/setup.h> |
48 | 48 | ||
49 | int gcmp_present = -1; | 49 | int gcmp_present = -1; |
50 | int gic_present; | ||
51 | static unsigned long _msc01_biu_base; | 50 | static unsigned long _msc01_biu_base; |
52 | static unsigned long _gcmp_base; | 51 | static unsigned long _gcmp_base; |
53 | static unsigned int ipi_map[NR_CPUS]; | 52 | static unsigned int ipi_map[NR_CPUS]; |
@@ -134,6 +133,9 @@ static void malta_ipi_irqdispatch(void) | |||
134 | { | 133 | { |
135 | int irq; | 134 | int irq; |
136 | 135 | ||
136 | if (gic_compare_int()) | ||
137 | do_IRQ(MIPS_GIC_IRQ_BASE); | ||
138 | |||
137 | irq = gic_get_int(); | 139 | irq = gic_get_int(); |
138 | if (irq < 0) | 140 | if (irq < 0) |
139 | return; /* interrupt has already been cleared */ | 141 | return; /* interrupt has already been cleared */ |
diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c index f3d43aa023a9..1f73d63e92a7 100644 --- a/arch/mips/mti-malta/malta-memory.c +++ b/arch/mips/mti-malta/malta-memory.c | |||
@@ -1,73 +1,45 @@ | |||
1 | /* | 1 | /* |
2 | * Carsten Langgaard, carstenl@mips.com | 2 | * This file is subject to the terms and conditions of the GNU General Public |
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * | 4 | * for more details. |
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | 5 | * |
18 | * PROM library functions for acquiring/using memory descriptors given to | 6 | * PROM library functions for acquiring/using memory descriptors given to |
19 | * us from the YAMON. | 7 | * us from the YAMON. |
8 | * | ||
9 | * Copyright (C) 1999,2000,2012 MIPS Technologies, Inc. | ||
10 | * All rights reserved. | ||
11 | * Authors: Carsten Langgaard <carstenl@mips.com> | ||
12 | * Steven J. Hill <sjhill@mips.com> | ||
20 | */ | 13 | */ |
21 | #include <linux/init.h> | 14 | #include <linux/init.h> |
22 | #include <linux/mm.h> | ||
23 | #include <linux/bootmem.h> | 15 | #include <linux/bootmem.h> |
24 | #include <linux/pfn.h> | ||
25 | #include <linux/string.h> | 16 | #include <linux/string.h> |
26 | 17 | ||
27 | #include <asm/bootinfo.h> | 18 | #include <asm/bootinfo.h> |
28 | #include <asm/page.h> | ||
29 | #include <asm/sections.h> | 19 | #include <asm/sections.h> |
20 | #include <asm/fw/fw.h> | ||
30 | 21 | ||
31 | #include <asm/mips-boards/prom.h> | 22 | static fw_memblock_t mdesc[FW_MAX_MEMBLOCKS]; |
32 | |||
33 | /*#define DEBUG*/ | ||
34 | |||
35 | enum yamon_memtypes { | ||
36 | yamon_dontuse, | ||
37 | yamon_prom, | ||
38 | yamon_free, | ||
39 | }; | ||
40 | static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; | ||
41 | |||
42 | #ifdef DEBUG | ||
43 | static char *mtypes[3] = { | ||
44 | "Dont use memory", | ||
45 | "YAMON PROM memory", | ||
46 | "Free memory", | ||
47 | }; | ||
48 | #endif | ||
49 | 23 | ||
50 | /* determined physical memory size, not overridden by command line args */ | 24 | /* determined physical memory size, not overridden by command line args */ |
51 | unsigned long physical_memsize = 0L; | 25 | unsigned long physical_memsize = 0L; |
52 | 26 | ||
53 | static struct prom_pmemblock * __init prom_getmdesc(void) | 27 | fw_memblock_t * __init fw_getmdesc(void) |
54 | { | 28 | { |
55 | char *memsize_str; | 29 | char *memsize_str, *ptr; |
56 | unsigned int memsize; | 30 | unsigned int memsize; |
57 | char *ptr; | ||
58 | static char cmdline[COMMAND_LINE_SIZE] __initdata; | 31 | static char cmdline[COMMAND_LINE_SIZE] __initdata; |
32 | long val; | ||
33 | int tmp; | ||
59 | 34 | ||
60 | /* otherwise look in the environment */ | 35 | /* otherwise look in the environment */ |
61 | memsize_str = prom_getenv("memsize"); | 36 | memsize_str = fw_getenv("memsize"); |
62 | if (!memsize_str) { | 37 | if (!memsize_str) { |
63 | printk(KERN_WARNING | 38 | pr_warn("memsize not set in YAMON, set to default (32Mb)\n"); |
64 | "memsize not set in boot prom, set to default (32Mb)\n"); | ||
65 | physical_memsize = 0x02000000; | 39 | physical_memsize = 0x02000000; |
66 | } else { | 40 | } else { |
67 | #ifdef DEBUG | 41 | tmp = kstrtol(memsize_str, 0, &val); |
68 | pr_debug("prom_memsize = %s\n", memsize_str); | 42 | physical_memsize = (unsigned long)val; |
69 | #endif | ||
70 | physical_memsize = simple_strtol(memsize_str, NULL, 0); | ||
71 | } | 43 | } |
72 | 44 | ||
73 | #ifdef CONFIG_CPU_BIG_ENDIAN | 45 | #ifdef CONFIG_CPU_BIG_ENDIAN |
@@ -90,11 +62,11 @@ static struct prom_pmemblock * __init prom_getmdesc(void) | |||
90 | 62 | ||
91 | memset(mdesc, 0, sizeof(mdesc)); | 63 | memset(mdesc, 0, sizeof(mdesc)); |
92 | 64 | ||
93 | mdesc[0].type = yamon_dontuse; | 65 | mdesc[0].type = fw_dontuse; |
94 | mdesc[0].base = 0x00000000; | 66 | mdesc[0].base = 0x00000000; |
95 | mdesc[0].size = 0x00001000; | 67 | mdesc[0].size = 0x00001000; |
96 | 68 | ||
97 | mdesc[1].type = yamon_prom; | 69 | mdesc[1].type = fw_code; |
98 | mdesc[1].base = 0x00001000; | 70 | mdesc[1].base = 0x00001000; |
99 | mdesc[1].size = 0x000ef000; | 71 | mdesc[1].size = 0x000ef000; |
100 | 72 | ||
@@ -105,55 +77,45 @@ static struct prom_pmemblock * __init prom_getmdesc(void) | |||
105 | * This mean that this area can't be used as DMA memory for PCI | 77 | * This mean that this area can't be used as DMA memory for PCI |
106 | * devices. | 78 | * devices. |
107 | */ | 79 | */ |
108 | mdesc[2].type = yamon_dontuse; | 80 | mdesc[2].type = fw_dontuse; |
109 | mdesc[2].base = 0x000f0000; | 81 | mdesc[2].base = 0x000f0000; |
110 | mdesc[2].size = 0x00010000; | 82 | mdesc[2].size = 0x00010000; |
111 | 83 | ||
112 | mdesc[3].type = yamon_dontuse; | 84 | mdesc[3].type = fw_dontuse; |
113 | mdesc[3].base = 0x00100000; | 85 | mdesc[3].base = 0x00100000; |
114 | mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base; | 86 | mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - |
87 | mdesc[3].base; | ||
115 | 88 | ||
116 | mdesc[4].type = yamon_free; | 89 | mdesc[4].type = fw_free; |
117 | mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); | 90 | mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); |
118 | mdesc[4].size = memsize - mdesc[4].base; | 91 | mdesc[4].size = memsize - mdesc[4].base; |
119 | 92 | ||
120 | return &mdesc[0]; | 93 | return &mdesc[0]; |
121 | } | 94 | } |
122 | 95 | ||
123 | static int __init prom_memtype_classify(unsigned int type) | 96 | static int __init fw_memtype_classify(unsigned int type) |
124 | { | 97 | { |
125 | switch (type) { | 98 | switch (type) { |
126 | case yamon_free: | 99 | case fw_free: |
127 | return BOOT_MEM_RAM; | 100 | return BOOT_MEM_RAM; |
128 | case yamon_prom: | 101 | case fw_code: |
129 | return BOOT_MEM_ROM_DATA; | 102 | return BOOT_MEM_ROM_DATA; |
130 | default: | 103 | default: |
131 | return BOOT_MEM_RESERVED; | 104 | return BOOT_MEM_RESERVED; |
132 | } | 105 | } |
133 | } | 106 | } |
134 | 107 | ||
135 | void __init prom_meminit(void) | 108 | void __init fw_meminit(void) |
136 | { | 109 | { |
137 | struct prom_pmemblock *p; | 110 | fw_memblock_t *p; |
138 | 111 | ||
139 | #ifdef DEBUG | 112 | p = fw_getmdesc(); |
140 | pr_debug("YAMON MEMORY DESCRIPTOR dump:\n"); | ||
141 | p = prom_getmdesc(); | ||
142 | while (p->size) { | ||
143 | int i = 0; | ||
144 | pr_debug("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n", | ||
145 | i, p, p->base, p->size, mtypes[p->type]); | ||
146 | p++; | ||
147 | i++; | ||
148 | } | ||
149 | #endif | ||
150 | p = prom_getmdesc(); | ||
151 | 113 | ||
152 | while (p->size) { | 114 | while (p->size) { |
153 | long type; | 115 | long type; |
154 | unsigned long base, size; | 116 | unsigned long base, size; |
155 | 117 | ||
156 | type = prom_memtype_classify(p->type); | 118 | type = fw_memtype_classify(p->type); |
157 | base = p->base; | 119 | base = p->base; |
158 | size = p->size; | 120 | size = p->size; |
159 | 121 | ||
@@ -172,7 +134,7 @@ void __init prom_free_prom_memory(void) | |||
172 | continue; | 134 | continue; |
173 | 135 | ||
174 | addr = boot_mem_map.map[i].addr; | 136 | addr = boot_mem_map.map[i].addr; |
175 | free_init_pages("prom memory", | 137 | free_init_pages("YAMON memory", |
176 | addr, addr + boot_mem_map.map[i].size); | 138 | addr, addr + boot_mem_map.map[i].size); |
177 | } | 139 | } |
178 | } | 140 | } |
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index 200f64df2c9b..c72a06936781 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c | |||
@@ -25,13 +25,13 @@ | |||
25 | #include <linux/screen_info.h> | 25 | #include <linux/screen_info.h> |
26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
27 | 27 | ||
28 | #include <asm/bootinfo.h> | 28 | #include <asm/fw/fw.h> |
29 | #include <asm/mips-boards/generic.h> | 29 | #include <asm/mips-boards/generic.h> |
30 | #include <asm/mips-boards/prom.h> | ||
31 | #include <asm/mips-boards/malta.h> | 30 | #include <asm/mips-boards/malta.h> |
32 | #include <asm/mips-boards/maltaint.h> | 31 | #include <asm/mips-boards/maltaint.h> |
33 | #include <asm/dma.h> | 32 | #include <asm/dma.h> |
34 | #include <asm/traps.h> | 33 | #include <asm/traps.h> |
34 | #include <asm/gcmpregs.h> | ||
35 | #ifdef CONFIG_VT | 35 | #ifdef CONFIG_VT |
36 | #include <linux/console.h> | 36 | #include <linux/console.h> |
37 | #endif | 37 | #endif |
@@ -105,6 +105,66 @@ static void __init fd_activate(void) | |||
105 | } | 105 | } |
106 | #endif | 106 | #endif |
107 | 107 | ||
108 | static int __init plat_enable_iocoherency(void) | ||
109 | { | ||
110 | int supported = 0; | ||
111 | if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) { | ||
112 | if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) { | ||
113 | BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN; | ||
114 | pr_info("Enabled Bonito CPU coherency\n"); | ||
115 | supported = 1; | ||
116 | } | ||
117 | if (strstr(fw_getcmdline(), "iobcuncached")) { | ||
118 | BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN; | ||
119 | BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & | ||
120 | ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | | ||
121 | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); | ||
122 | pr_info("Disabled Bonito IOBC coherency\n"); | ||
123 | } else { | ||
124 | BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN; | ||
125 | BONITO_PCIMEMBASECFG |= | ||
126 | (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | | ||
127 | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); | ||
128 | pr_info("Enabled Bonito IOBC coherency\n"); | ||
129 | } | ||
130 | } else if (gcmp_niocu() != 0) { | ||
131 | /* Nothing special needs to be done to enable coherency */ | ||
132 | pr_info("CMP IOCU detected\n"); | ||
133 | if ((*(unsigned int *)0xbf403000 & 0x81) != 0x81) { | ||
134 | pr_crit("IOCU OPERATION DISABLED BY SWITCH - DEFAULTING TO SW IO COHERENCY\n"); | ||
135 | return 0; | ||
136 | } | ||
137 | supported = 1; | ||
138 | } | ||
139 | hw_coherentio = supported; | ||
140 | return supported; | ||
141 | } | ||
142 | |||
143 | static void __init plat_setup_iocoherency(void) | ||
144 | { | ||
145 | #ifdef CONFIG_DMA_NONCOHERENT | ||
146 | /* | ||
147 | * Kernel has been configured with software coherency | ||
148 | * but we might choose to turn it off and use hardware | ||
149 | * coherency instead. | ||
150 | */ | ||
151 | if (plat_enable_iocoherency()) { | ||
152 | if (coherentio == 0) | ||
153 | pr_info("Hardware DMA cache coherency disabled\n"); | ||
154 | else | ||
155 | pr_info("Hardware DMA cache coherency enabled\n"); | ||
156 | } else { | ||
157 | if (coherentio == 1) | ||
158 | pr_info("Hardware DMA cache coherency unsupported, but enabled from command line!\n"); | ||
159 | else | ||
160 | pr_info("Software DMA cache coherency enabled\n"); | ||
161 | } | ||
162 | #else | ||
163 | if (!plat_enable_iocoherency()) | ||
164 | panic("Hardware DMA cache coherency not supported!"); | ||
165 | #endif | ||
166 | } | ||
167 | |||
108 | #ifdef CONFIG_BLK_DEV_IDE | 168 | #ifdef CONFIG_BLK_DEV_IDE |
109 | static void __init pci_clock_check(void) | 169 | static void __init pci_clock_check(void) |
110 | { | 170 | { |
@@ -115,16 +175,15 @@ static void __init pci_clock_check(void) | |||
115 | 33, 20, 25, 30, 12, 16, 37, 10 | 175 | 33, 20, 25, 30, 12, 16, 37, 10 |
116 | }; | 176 | }; |
117 | int pciclock = pciclocks[jmpr]; | 177 | int pciclock = pciclocks[jmpr]; |
118 | char *argptr = prom_getcmdline(); | 178 | char *argptr = fw_getcmdline(); |
119 | 179 | ||
120 | if (pciclock != 33 && !strstr(argptr, "idebus=")) { | 180 | if (pciclock != 33 && !strstr(argptr, "idebus=")) { |
121 | printk(KERN_WARNING "WARNING: PCI clock is %dMHz, " | 181 | pr_warn("WARNING: PCI clock is %dMHz, setting idebus\n", |
122 | "setting idebus\n", pciclock); | 182 | pciclock); |
123 | argptr += strlen(argptr); | 183 | argptr += strlen(argptr); |
124 | sprintf(argptr, " idebus=%d", pciclock); | 184 | sprintf(argptr, " idebus=%d", pciclock); |
125 | if (pciclock < 20 || pciclock > 66) | 185 | if (pciclock < 20 || pciclock > 66) |
126 | printk(KERN_WARNING "WARNING: IDE timing " | 186 | pr_warn("WARNING: IDE timing calculations will be incorrect\n"); |
127 | "calculations will be incorrect\n"); | ||
128 | } | 187 | } |
129 | } | 188 | } |
130 | #endif | 189 | #endif |
@@ -153,31 +212,31 @@ static void __init bonito_quirks_setup(void) | |||
153 | { | 212 | { |
154 | char *argptr; | 213 | char *argptr; |
155 | 214 | ||
156 | argptr = prom_getcmdline(); | 215 | argptr = fw_getcmdline(); |
157 | if (strstr(argptr, "debug")) { | 216 | if (strstr(argptr, "debug")) { |
158 | BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE; | 217 | BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE; |
159 | printk(KERN_INFO "Enabled Bonito debug mode\n"); | 218 | pr_info("Enabled Bonito debug mode\n"); |
160 | } else | 219 | } else |
161 | BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE; | 220 | BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE; |
162 | 221 | ||
163 | #ifdef CONFIG_DMA_COHERENT | 222 | #ifdef CONFIG_DMA_COHERENT |
164 | if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) { | 223 | if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) { |
165 | BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN; | 224 | BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN; |
166 | printk(KERN_INFO "Enabled Bonito CPU coherency\n"); | 225 | pr_info("Enabled Bonito CPU coherency\n"); |
167 | 226 | ||
168 | argptr = prom_getcmdline(); | 227 | argptr = fw_getcmdline(); |
169 | if (strstr(argptr, "iobcuncached")) { | 228 | if (strstr(argptr, "iobcuncached")) { |
170 | BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN; | 229 | BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN; |
171 | BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & | 230 | BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & |
172 | ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | | 231 | ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | |
173 | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); | 232 | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); |
174 | printk(KERN_INFO "Disabled Bonito IOBC coherency\n"); | 233 | pr_info("Disabled Bonito IOBC coherency\n"); |
175 | } else { | 234 | } else { |
176 | BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN; | 235 | BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN; |
177 | BONITO_PCIMEMBASECFG |= | 236 | BONITO_PCIMEMBASECFG |= |
178 | (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | | 237 | (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | |
179 | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); | 238 | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); |
180 | printk(KERN_INFO "Enabled Bonito IOBC coherency\n"); | 239 | pr_info("Enabled Bonito IOBC coherency\n"); |
181 | } | 240 | } |
182 | } else | 241 | } else |
183 | panic("Hardware DMA cache coherency not supported"); | 242 | panic("Hardware DMA cache coherency not supported"); |
@@ -207,6 +266,8 @@ void __init plat_mem_setup(void) | |||
207 | if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) | 266 | if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) |
208 | bonito_quirks_setup(); | 267 | bonito_quirks_setup(); |
209 | 268 | ||
269 | plat_setup_iocoherency(); | ||
270 | |||
210 | #ifdef CONFIG_BLK_DEV_IDE | 271 | #ifdef CONFIG_BLK_DEV_IDE |
211 | pci_clock_check(); | 272 | pci_clock_check(); |
212 | #endif | 273 | #endif |
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index bc6ac00c0d57..0ad305f75802 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c | |||
@@ -39,12 +39,9 @@ | |||
39 | #include <asm/gic.h> | 39 | #include <asm/gic.h> |
40 | 40 | ||
41 | #include <asm/mips-boards/generic.h> | 41 | #include <asm/mips-boards/generic.h> |
42 | #include <asm/mips-boards/prom.h> | ||
43 | |||
44 | #include <asm/mips-boards/maltaint.h> | 42 | #include <asm/mips-boards/maltaint.h> |
45 | 43 | ||
46 | unsigned long cpu_khz; | 44 | unsigned long cpu_khz; |
47 | int gic_frequency; | ||
48 | 45 | ||
49 | static int mips_cpu_timer_irq; | 46 | static int mips_cpu_timer_irq; |
50 | static int mips_cpu_perf_irq; | 47 | static int mips_cpu_perf_irq; |
@@ -74,7 +71,9 @@ static void __init estimate_frequencies(void) | |||
74 | { | 71 | { |
75 | unsigned long flags; | 72 | unsigned long flags; |
76 | unsigned int count, start; | 73 | unsigned int count, start; |
74 | #ifdef CONFIG_IRQ_GIC | ||
77 | unsigned int giccount = 0, gicstart = 0; | 75 | unsigned int giccount = 0, gicstart = 0; |
76 | #endif | ||
78 | 77 | ||
79 | #if defined (CONFIG_KVM_GUEST) && defined (CONFIG_KVM_HOST_FREQ) | 78 | #if defined (CONFIG_KVM_GUEST) && defined (CONFIG_KVM_HOST_FREQ) |
80 | unsigned int prid = read_c0_prid() & 0xffff00; | 79 | unsigned int prid = read_c0_prid() & 0xffff00; |
@@ -99,26 +98,32 @@ static void __init estimate_frequencies(void) | |||
99 | 98 | ||
100 | /* Initialize counters. */ | 99 | /* Initialize counters. */ |
101 | start = read_c0_count(); | 100 | start = read_c0_count(); |
101 | #ifdef CONFIG_IRQ_GIC | ||
102 | if (gic_present) | 102 | if (gic_present) |
103 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart); | 103 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart); |
104 | #endif | ||
104 | 105 | ||
105 | /* Read counter exactly on falling edge of update flag. */ | 106 | /* Read counter exactly on falling edge of update flag. */ |
106 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | 107 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); |
107 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | 108 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); |
108 | 109 | ||
109 | count = read_c0_count(); | 110 | count = read_c0_count(); |
111 | #ifdef CONFIG_IRQ_GIC | ||
110 | if (gic_present) | 112 | if (gic_present) |
111 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount); | 113 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount); |
114 | #endif | ||
112 | 115 | ||
113 | local_irq_restore(flags); | 116 | local_irq_restore(flags); |
114 | 117 | ||
115 | count -= start; | 118 | count -= start; |
116 | if (gic_present) | ||
117 | giccount -= gicstart; | ||
118 | |||
119 | mips_hpt_frequency = count; | 119 | mips_hpt_frequency = count; |
120 | if (gic_present) | 120 | |
121 | #ifdef CONFIG_IRQ_GIC | ||
122 | if (gic_present) { | ||
123 | giccount -= gicstart; | ||
121 | gic_frequency = giccount; | 124 | gic_frequency = giccount; |
125 | } | ||
126 | #endif | ||
122 | } | 127 | } |
123 | 128 | ||
124 | void read_persistent_clock(struct timespec *ts) | 129 | void read_persistent_clock(struct timespec *ts) |
@@ -174,24 +179,27 @@ void __init plat_time_init(void) | |||
174 | (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) | 179 | (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) |
175 | freq *= 2; | 180 | freq *= 2; |
176 | freq = freqround(freq, 5000); | 181 | freq = freqround(freq, 5000); |
177 | pr_debug("CPU frequency %d.%02d MHz\n", freq/1000000, | 182 | printk("CPU frequency %d.%02d MHz\n", freq/1000000, |
178 | (freq%1000000)*100/1000000); | 183 | (freq%1000000)*100/1000000); |
179 | cpu_khz = freq / 1000; | 184 | cpu_khz = freq / 1000; |
180 | 185 | ||
181 | if (gic_present) { | 186 | mips_scroll_message(); |
182 | freq = freqround(gic_frequency, 5000); | ||
183 | pr_debug("GIC frequency %d.%02d MHz\n", freq/1000000, | ||
184 | (freq%1000000)*100/1000000); | ||
185 | gic_clocksource_init(gic_frequency); | ||
186 | } else | ||
187 | init_r4k_clocksource(); | ||
188 | 187 | ||
189 | #ifdef CONFIG_I8253 | 188 | #ifdef CONFIG_I8253 |
190 | /* Only Malta has a PIT. */ | 189 | /* Only Malta has a PIT. */ |
191 | setup_pit_timer(); | 190 | setup_pit_timer(); |
192 | #endif | 191 | #endif |
193 | 192 | ||
194 | mips_scroll_message(); | 193 | #ifdef CONFIG_IRQ_GIC |
194 | if (gic_present) { | ||
195 | freq = freqround(gic_frequency, 5000); | ||
196 | printk("GIC frequency %d.%02d MHz\n", freq/1000000, | ||
197 | (freq%1000000)*100/1000000); | ||
198 | #ifdef CONFIG_CSRC_GIC | ||
199 | gic_clocksource_init(gic_frequency); | ||
200 | #endif | ||
201 | } | ||
202 | #endif | ||
195 | 203 | ||
196 | plat_perf_setup(); | 204 | plat_perf_setup(); |
197 | } | 205 | } |
diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile index 10ec701ce6c7..be114209217c 100644 --- a/arch/mips/mti-sead3/Makefile +++ b/arch/mips/mti-sead3/Makefile | |||
@@ -8,10 +8,10 @@ | |||
8 | # Copyright (C) 2012 MIPS Technoligies, Inc. All rights reserved. | 8 | # Copyright (C) 2012 MIPS Technoligies, Inc. All rights reserved. |
9 | # Steven J. Hill <sjhill@mips.com> | 9 | # Steven J. Hill <sjhill@mips.com> |
10 | # | 10 | # |
11 | obj-y := sead3-lcd.o sead3-cmdline.o \ | 11 | obj-y := sead3-lcd.o sead3-display.o sead3-init.o \ |
12 | sead3-display.o sead3-init.o sead3-int.o \ | 12 | sead3-int.o sead3-mtd.o sead3-net.o \ |
13 | sead3-mtd.o sead3-net.o sead3-platform.o \ | 13 | sead3-platform.o sead3-reset.o \ |
14 | sead3-reset.o sead3-setup.o sead3-time.o | 14 | sead3-setup.o sead3-time.o |
15 | 15 | ||
16 | obj-y += sead3-i2c-dev.o sead3-i2c.o \ | 16 | obj-y += sead3-i2c-dev.o sead3-i2c.o \ |
17 | sead3-pic32-i2c-drv.o sead3-pic32-bus.o \ | 17 | sead3-pic32-i2c-drv.o sead3-pic32-bus.o \ |
diff --git a/arch/mips/mti-sead3/leds-sead3.c b/arch/mips/mti-sead3/leds-sead3.c index 322148c353ed..0a168c948b01 100644 --- a/arch/mips/mti-sead3/leds-sead3.c +++ b/arch/mips/mti-sead3/leds-sead3.c | |||
@@ -34,33 +34,15 @@ static void sead3_fled_set(struct led_classdev *led_cdev, | |||
34 | static struct led_classdev sead3_pled = { | 34 | static struct led_classdev sead3_pled = { |
35 | .name = "sead3::pled", | 35 | .name = "sead3::pled", |
36 | .brightness_set = sead3_pled_set, | 36 | .brightness_set = sead3_pled_set, |
37 | .flags = LED_CORE_SUSPENDRESUME, | ||
37 | }; | 38 | }; |
38 | 39 | ||
39 | static struct led_classdev sead3_fled = { | 40 | static struct led_classdev sead3_fled = { |
40 | .name = "sead3::fled", | 41 | .name = "sead3::fled", |
41 | .brightness_set = sead3_fled_set, | 42 | .brightness_set = sead3_fled_set, |
43 | .flags = LED_CORE_SUSPENDRESUME, | ||
42 | }; | 44 | }; |
43 | 45 | ||
44 | #ifdef CONFIG_PM | ||
45 | static int sead3_led_suspend(struct platform_device *dev, | ||
46 | pm_message_t state) | ||
47 | { | ||
48 | led_classdev_suspend(&sead3_pled); | ||
49 | led_classdev_suspend(&sead3_fled); | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static int sead3_led_resume(struct platform_device *dev) | ||
54 | { | ||
55 | led_classdev_resume(&sead3_pled); | ||
56 | led_classdev_resume(&sead3_fled); | ||
57 | return 0; | ||
58 | } | ||
59 | #else | ||
60 | #define sead3_led_suspend NULL | ||
61 | #define sead3_led_resume NULL | ||
62 | #endif | ||
63 | |||
64 | static int sead3_led_probe(struct platform_device *pdev) | 46 | static int sead3_led_probe(struct platform_device *pdev) |
65 | { | 47 | { |
66 | int ret; | 48 | int ret; |
@@ -86,8 +68,6 @@ static int sead3_led_remove(struct platform_device *pdev) | |||
86 | static struct platform_driver sead3_led_driver = { | 68 | static struct platform_driver sead3_led_driver = { |
87 | .probe = sead3_led_probe, | 69 | .probe = sead3_led_probe, |
88 | .remove = sead3_led_remove, | 70 | .remove = sead3_led_remove, |
89 | .suspend = sead3_led_suspend, | ||
90 | .resume = sead3_led_resume, | ||
91 | .driver = { | 71 | .driver = { |
92 | .name = DRVNAME, | 72 | .name = DRVNAME, |
93 | .owner = THIS_MODULE, | 73 | .owner = THIS_MODULE, |
diff --git a/arch/mips/mti-sead3/sead3-cmdline.c b/arch/mips/mti-sead3/sead3-cmdline.c deleted file mode 100644 index a2e6cec67f57..000000000000 --- a/arch/mips/mti-sead3/sead3-cmdline.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
7 | */ | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/string.h> | ||
10 | |||
11 | #include <asm/bootinfo.h> | ||
12 | |||
13 | extern int prom_argc; | ||
14 | extern int *_prom_argv; | ||
15 | |||
16 | /* | ||
17 | * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | ||
18 | * This macro take care of sign extension. | ||
19 | */ | ||
20 | #define prom_argv(index) ((char *)(long)_prom_argv[(index)]) | ||
21 | |||
22 | char * __init prom_getcmdline(void) | ||
23 | { | ||
24 | return &(arcs_cmdline[0]); | ||
25 | } | ||
26 | |||
27 | void __init prom_init_cmdline(void) | ||
28 | { | ||
29 | char *cp; | ||
30 | int actr; | ||
31 | |||
32 | actr = 1; /* Always ignore argv[0] */ | ||
33 | |||
34 | cp = &(arcs_cmdline[0]); | ||
35 | while (actr < prom_argc) { | ||
36 | strcpy(cp, prom_argv(actr)); | ||
37 | cp += strlen(prom_argv(actr)); | ||
38 | *cp++ = ' '; | ||
39 | actr++; | ||
40 | } | ||
41 | if (cp != &(arcs_cmdline[0])) { | ||
42 | /* get rid of trailing space */ | ||
43 | --cp; | ||
44 | *cp = '\0'; | ||
45 | } | ||
46 | } | ||
diff --git a/arch/mips/mti-sead3/sead3-console.c b/arch/mips/mti-sead3/sead3-console.c index 2ddef19a9adc..031f47d69770 100644 --- a/arch/mips/mti-sead3/sead3-console.c +++ b/arch/mips/mti-sead3/sead3-console.c | |||
@@ -26,7 +26,7 @@ static inline void serial_out(int offset, int value, unsigned int base_addr) | |||
26 | __raw_writel(value, PORT(base_addr, offset)); | 26 | __raw_writel(value, PORT(base_addr, offset)); |
27 | } | 27 | } |
28 | 28 | ||
29 | void __init prom_init_early_console(char port) | 29 | void __init fw_init_early_console(char port) |
30 | { | 30 | { |
31 | console_port = port; | 31 | console_port = port; |
32 | } | 32 | } |
diff --git a/arch/mips/mti-sead3/sead3-display.c b/arch/mips/mti-sead3/sead3-display.c index e389326cfa42..94875991907b 100644 --- a/arch/mips/mti-sead3/sead3-display.c +++ b/arch/mips/mti-sead3/sead3-display.c | |||
@@ -8,7 +8,6 @@ | |||
8 | #include <linux/timer.h> | 8 | #include <linux/timer.h> |
9 | #include <linux/io.h> | 9 | #include <linux/io.h> |
10 | #include <asm/mips-boards/generic.h> | 10 | #include <asm/mips-boards/generic.h> |
11 | #include <asm/mips-boards/prom.h> | ||
12 | 11 | ||
13 | static unsigned int display_count; | 12 | static unsigned int display_count; |
14 | static unsigned int max_display_count; | 13 | static unsigned int max_display_count; |
diff --git a/arch/mips/mti-sead3/sead3-init.c b/arch/mips/mti-sead3/sead3-init.c index f95abaa1aa5d..bfbd17b120a2 100644 --- a/arch/mips/mti-sead3/sead3-init.c +++ b/arch/mips/mti-sead3/sead3-init.c | |||
@@ -12,38 +12,51 @@ | |||
12 | #include <asm/cacheflush.h> | 12 | #include <asm/cacheflush.h> |
13 | #include <asm/traps.h> | 13 | #include <asm/traps.h> |
14 | #include <asm/mips-boards/generic.h> | 14 | #include <asm/mips-boards/generic.h> |
15 | #include <asm/mips-boards/prom.h> | 15 | #include <asm/fw/fw.h> |
16 | |||
17 | extern void prom_init_early_console(char port); | ||
18 | 16 | ||
19 | extern char except_vec_nmi; | 17 | extern char except_vec_nmi; |
20 | extern char except_vec_ejtag_debug; | 18 | extern char except_vec_ejtag_debug; |
21 | 19 | ||
22 | int prom_argc; | 20 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
23 | int *_prom_argv, *_prom_envp; | 21 | static void __init console_config(void) |
24 | |||
25 | #define prom_envp(index) ((char *)(long)_prom_envp[(index)]) | ||
26 | |||
27 | char *prom_getenv(char *envname) | ||
28 | { | 22 | { |
29 | /* | 23 | char console_string[40]; |
30 | * Return a pointer to the given environment variable. | 24 | int baud = 0; |
31 | * In 64-bit mode: we're using 64-bit pointers, but all pointers | 25 | char parity = '\0', bits = '\0', flow = '\0'; |
32 | * in the PROM structures are only 32-bit, so we need some | 26 | char *s; |
33 | * workarounds, if we are running in 64-bit mode. | 27 | |
34 | */ | 28 | if ((strstr(fw_getcmdline(), "console=")) == NULL) { |
35 | int i, index = 0; | 29 | s = fw_getenv("modetty0"); |
36 | 30 | if (s) { | |
37 | i = strlen(envname); | 31 | while (*s >= '0' && *s <= '9') |
38 | 32 | baud = baud*10 + *s++ - '0'; | |
39 | while (prom_envp(index)) { | 33 | if (*s == ',') |
40 | if (strncmp(envname, prom_envp(index), i) == 0) | 34 | s++; |
41 | return prom_envp(index+1); | 35 | if (*s) |
42 | index += 2; | 36 | parity = *s++; |
37 | if (*s == ',') | ||
38 | s++; | ||
39 | if (*s) | ||
40 | bits = *s++; | ||
41 | if (*s == ',') | ||
42 | s++; | ||
43 | if (*s == 'h') | ||
44 | flow = 'r'; | ||
45 | } | ||
46 | if (baud == 0) | ||
47 | baud = 38400; | ||
48 | if (parity != 'n' && parity != 'o' && parity != 'e') | ||
49 | parity = 'n'; | ||
50 | if (bits != '7' && bits != '8') | ||
51 | bits = '8'; | ||
52 | if (flow == '\0') | ||
53 | flow = 'r'; | ||
54 | sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, | ||
55 | parity, bits, flow); | ||
56 | strcat(fw_getcmdline(), console_string); | ||
43 | } | 57 | } |
44 | |||
45 | return NULL; | ||
46 | } | 58 | } |
59 | #endif | ||
47 | 60 | ||
48 | static void __init mips_nmi_setup(void) | 61 | static void __init mips_nmi_setup(void) |
49 | { | 62 | { |
@@ -52,7 +65,41 @@ static void __init mips_nmi_setup(void) | |||
52 | base = cpu_has_veic ? | 65 | base = cpu_has_veic ? |
53 | (void *)(CAC_BASE + 0xa80) : | 66 | (void *)(CAC_BASE + 0xa80) : |
54 | (void *)(CAC_BASE + 0x380); | 67 | (void *)(CAC_BASE + 0x380); |
68 | #ifdef CONFIG_CPU_MICROMIPS | ||
69 | /* | ||
70 | * Decrement the exception vector address by one for microMIPS. | ||
71 | */ | ||
72 | memcpy(base, (&except_vec_nmi - 1), 0x80); | ||
73 | |||
74 | /* | ||
75 | * This is a hack. We do not know if the boot loader was built with | ||
76 | * microMIPS instructions or not. If it was not, the NMI exception | ||
77 | * code at 0x80000a80 will be taken in MIPS32 mode. The hand coded | ||
78 | * assembly below forces us into microMIPS mode if we are a pure | ||
79 | * microMIPS kernel. The assembly instructions are: | ||
80 | * | ||
81 | * 3C1A8000 lui k0,0x8000 | ||
82 | * 375A0381 ori k0,k0,0x381 | ||
83 | * 03400008 jr k0 | ||
84 | * 00000000 nop | ||
85 | * | ||
86 | * The mode switch occurs by jumping to the unaligned exception | ||
87 | * vector address at 0x80000381 which would have been 0x80000380 | ||
88 | * in MIPS32 mode. The jump to the unaligned address transitions | ||
89 | * us into microMIPS mode. | ||
90 | */ | ||
91 | if (!cpu_has_veic) { | ||
92 | void *base2 = (void *)(CAC_BASE + 0xa80); | ||
93 | *((unsigned int *)base2) = 0x3c1a8000; | ||
94 | *((unsigned int *)base2 + 1) = 0x375a0381; | ||
95 | *((unsigned int *)base2 + 2) = 0x03400008; | ||
96 | *((unsigned int *)base2 + 3) = 0x00000000; | ||
97 | flush_icache_range((unsigned long)base2, | ||
98 | (unsigned long)base2 + 0x10); | ||
99 | } | ||
100 | #else | ||
55 | memcpy(base, &except_vec_nmi, 0x80); | 101 | memcpy(base, &except_vec_nmi, 0x80); |
102 | #endif | ||
56 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); | 103 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); |
57 | } | 104 | } |
58 | 105 | ||
@@ -63,29 +110,40 @@ static void __init mips_ejtag_setup(void) | |||
63 | base = cpu_has_veic ? | 110 | base = cpu_has_veic ? |
64 | (void *)(CAC_BASE + 0xa00) : | 111 | (void *)(CAC_BASE + 0xa00) : |
65 | (void *)(CAC_BASE + 0x300); | 112 | (void *)(CAC_BASE + 0x300); |
113 | #ifdef CONFIG_CPU_MICROMIPS | ||
114 | /* Deja vu... */ | ||
115 | memcpy(base, (&except_vec_ejtag_debug - 1), 0x80); | ||
116 | if (!cpu_has_veic) { | ||
117 | void *base2 = (void *)(CAC_BASE + 0xa00); | ||
118 | *((unsigned int *)base2) = 0x3c1a8000; | ||
119 | *((unsigned int *)base2 + 1) = 0x375a0301; | ||
120 | *((unsigned int *)base2 + 2) = 0x03400008; | ||
121 | *((unsigned int *)base2 + 3) = 0x00000000; | ||
122 | flush_icache_range((unsigned long)base2, | ||
123 | (unsigned long)base2 + 0x10); | ||
124 | } | ||
125 | #else | ||
66 | memcpy(base, &except_vec_ejtag_debug, 0x80); | 126 | memcpy(base, &except_vec_ejtag_debug, 0x80); |
127 | #endif | ||
67 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); | 128 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); |
68 | } | 129 | } |
69 | 130 | ||
70 | void __init prom_init(void) | 131 | void __init prom_init(void) |
71 | { | 132 | { |
72 | prom_argc = fw_arg0; | ||
73 | _prom_argv = (int *) fw_arg1; | ||
74 | _prom_envp = (int *) fw_arg2; | ||
75 | |||
76 | board_nmi_handler_setup = mips_nmi_setup; | 133 | board_nmi_handler_setup = mips_nmi_setup; |
77 | board_ejtag_handler_setup = mips_ejtag_setup; | 134 | board_ejtag_handler_setup = mips_ejtag_setup; |
78 | 135 | ||
79 | prom_init_cmdline(); | 136 | fw_init_cmdline(); |
80 | #ifdef CONFIG_EARLY_PRINTK | 137 | #ifdef CONFIG_EARLY_PRINTK |
81 | if ((strstr(prom_getcmdline(), "console=ttyS0")) != NULL) | 138 | if ((strstr(fw_getcmdline(), "console=ttyS0")) != NULL) |
82 | prom_init_early_console(0); | 139 | fw_init_early_console(0); |
83 | else if ((strstr(prom_getcmdline(), "console=ttyS1")) != NULL) | 140 | else if ((strstr(fw_getcmdline(), "console=ttyS1")) != NULL) |
84 | prom_init_early_console(1); | 141 | fw_init_early_console(1); |
85 | #endif | 142 | #endif |
86 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 143 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
87 | if ((strstr(prom_getcmdline(), "console=")) == NULL) | 144 | if ((strstr(fw_getcmdline(), "console=")) == NULL) |
88 | strcat(prom_getcmdline(), " console=ttyS0,38400n8r"); | 145 | strcat(fw_getcmdline(), " console=ttyS0,38400n8r"); |
146 | console_config(); | ||
89 | #endif | 147 | #endif |
90 | } | 148 | } |
91 | 149 | ||
diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index e26e08274fc5..6a560ac03def 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #define SEAD_CONFIG_BASE 0x1b100110 | 20 | #define SEAD_CONFIG_BASE 0x1b100110 |
21 | #define SEAD_CONFIG_SIZE 4 | 21 | #define SEAD_CONFIG_SIZE 4 |
22 | 22 | ||
23 | int gic_present; | ||
24 | static unsigned long sead3_config_reg; | 23 | static unsigned long sead3_config_reg; |
25 | 24 | ||
26 | /* | 25 | /* |
diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c index f012fd164cee..b5059dc899f4 100644 --- a/arch/mips/mti-sead3/sead3-setup.c +++ b/arch/mips/mti-sead3/sead3-setup.c | |||
@@ -11,10 +11,6 @@ | |||
11 | #include <linux/bootmem.h> | 11 | #include <linux/bootmem.h> |
12 | 12 | ||
13 | #include <asm/mips-boards/generic.h> | 13 | #include <asm/mips-boards/generic.h> |
14 | #include <asm/prom.h> | ||
15 | |||
16 | int coherentio; /* 0 => no DMA cache coherency (may be set by user) */ | ||
17 | int hw_coherentio; /* 0 => no HW DMA cache coherency (reflects real HW) */ | ||
18 | 14 | ||
19 | const char *get_system_type(void) | 15 | const char *get_system_type(void) |
20 | { | 16 | { |
diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c index 239e4e32757f..96b42eb9b5e2 100644 --- a/arch/mips/mti-sead3/sead3-time.c +++ b/arch/mips/mti-sead3/sead3-time.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <asm/time.h> | 11 | #include <asm/time.h> |
12 | #include <asm/irq.h> | 12 | #include <asm/irq.h> |
13 | #include <asm/mips-boards/generic.h> | 13 | #include <asm/mips-boards/generic.h> |
14 | #include <asm/mips-boards/prom.h> | ||
15 | 14 | ||
16 | unsigned long cpu_khz; | 15 | unsigned long cpu_khz; |
17 | 16 | ||
diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c index 5bd9d8f468cc..a01baff52cae 100644 --- a/arch/mips/powertv/init.c +++ b/arch/mips/powertv/init.c | |||
@@ -29,10 +29,11 @@ | |||
29 | #include <asm/cacheflush.h> | 29 | #include <asm/cacheflush.h> |
30 | #include <asm/traps.h> | 30 | #include <asm/traps.h> |
31 | 31 | ||
32 | #include <asm/mips-boards/prom.h> | ||
33 | #include <asm/mips-boards/generic.h> | 32 | #include <asm/mips-boards/generic.h> |
34 | #include <asm/mach-powertv/asic.h> | 33 | #include <asm/mach-powertv/asic.h> |
35 | 34 | ||
35 | #include "init.h" | ||
36 | |||
36 | static int *_prom_envp; | 37 | static int *_prom_envp; |
37 | unsigned long _prom_memsize; | 38 | unsigned long _prom_memsize; |
38 | 39 | ||
diff --git a/arch/mips/powertv/init.h b/arch/mips/powertv/init.h index b194c34ca966..c1a8bd0dbe4b 100644 --- a/arch/mips/powertv/init.h +++ b/arch/mips/powertv/init.h | |||
@@ -23,4 +23,6 @@ | |||
23 | #ifndef _POWERTV_INIT_H | 23 | #ifndef _POWERTV_INIT_H |
24 | #define _POWERTV_INIT_H | 24 | #define _POWERTV_INIT_H |
25 | extern unsigned long _prom_memsize; | 25 | extern unsigned long _prom_memsize; |
26 | extern void prom_meminit(void); | ||
27 | extern char *prom_getenv(char *name); | ||
26 | #endif | 28 | #endif |
diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c index 6e5f1bdc59b5..bc2f3ca22b41 100644 --- a/arch/mips/powertv/memory.c +++ b/arch/mips/powertv/memory.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
30 | #include <asm/sections.h> | 30 | #include <asm/sections.h> |
31 | 31 | ||
32 | #include <asm/mips-boards/prom.h> | ||
33 | #include <asm/mach-powertv/asic.h> | 32 | #include <asm/mach-powertv/asic.h> |
34 | #include <asm/mach-powertv/ioremap.h> | 33 | #include <asm/mach-powertv/ioremap.h> |
35 | 34 | ||
diff --git a/arch/mips/powertv/powertv_setup.c b/arch/mips/powertv/powertv_setup.c index 820b8480f222..24689bff1039 100644 --- a/arch/mips/powertv/powertv_setup.c +++ b/arch/mips/powertv/powertv_setup.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
32 | #include <asm/irq.h> | 32 | #include <asm/irq.h> |
33 | #include <asm/mips-boards/generic.h> | 33 | #include <asm/mips-boards/generic.h> |
34 | #include <asm/mips-boards/prom.h> | ||
35 | #include <asm/dma.h> | 34 | #include <asm/dma.h> |
36 | #include <asm/asm.h> | 35 | #include <asm/asm.h> |
37 | #include <asm/traps.h> | 36 | #include <asm/traps.h> |