diff options
Diffstat (limited to 'arch')
352 files changed, 8307 insertions, 5466 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 9bef61b30367..8290b69da202 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -549,6 +549,11 @@ config NUMA | |||
549 | Access). This option is for configuring high-end multiprocessor | 549 | Access). This option is for configuring high-end multiprocessor |
550 | server machines. If in doubt, say N. | 550 | server machines. If in doubt, say N. |
551 | 551 | ||
552 | config NODES_SHIFT | ||
553 | int | ||
554 | default "7" | ||
555 | depends on NEED_MULTIPLE_NODES | ||
556 | |||
552 | # LARGE_VMALLOC is racy, if you *really* need it then fix it first | 557 | # LARGE_VMALLOC is racy, if you *really* need it then fix it first |
553 | config ALPHA_LARGE_VMALLOC | 558 | config ALPHA_LARGE_VMALLOC |
554 | bool | 559 | bool |
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index 9d6186d50245..c645c5e14786 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c | |||
@@ -76,7 +76,6 @@ EXPORT_SYMBOL(strncpy); | |||
76 | EXPORT_SYMBOL(strnlen); | 76 | EXPORT_SYMBOL(strnlen); |
77 | EXPORT_SYMBOL(strncat); | 77 | EXPORT_SYMBOL(strncat); |
78 | EXPORT_SYMBOL(strstr); | 78 | EXPORT_SYMBOL(strstr); |
79 | EXPORT_SYMBOL(strpbrk); | ||
80 | EXPORT_SYMBOL(strchr); | 79 | EXPORT_SYMBOL(strchr); |
81 | EXPORT_SYMBOL(strrchr); | 80 | EXPORT_SYMBOL(strrchr); |
82 | EXPORT_SYMBOL(memcmp); | 81 | EXPORT_SYMBOL(memcmp); |
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index a15e18a00258..558b83368559 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/config.h> /* CONFIG_ALPHA_LCA etc */ | 24 | #include <linux/config.h> /* CONFIG_ALPHA_LCA etc */ |
25 | #include <linux/mc146818rtc.h> | 25 | #include <linux/mc146818rtc.h> |
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/cpu.h> | ||
27 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
28 | #include <linux/init.h> | 29 | #include <linux/init.h> |
29 | #include <linux/string.h> | 30 | #include <linux/string.h> |
@@ -471,6 +472,22 @@ page_is_ram(unsigned long pfn) | |||
471 | return 0; | 472 | return 0; |
472 | } | 473 | } |
473 | 474 | ||
475 | static int __init | ||
476 | register_cpus(void) | ||
477 | { | ||
478 | int i; | ||
479 | |||
480 | for_each_possible_cpu(i) { | ||
481 | struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); | ||
482 | if (!p) | ||
483 | return -ENOMEM; | ||
484 | register_cpu(p, i, NULL); | ||
485 | } | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | arch_initcall(register_cpus); | ||
490 | |||
474 | void __init | 491 | void __init |
475 | setup_arch(char **cmdline_p) | 492 | setup_arch(char **cmdline_p) |
476 | { | 493 | { |
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 02c2db08114a..185255416e85 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c | |||
@@ -439,7 +439,7 @@ setup_smp(void) | |||
439 | if ((cpu->flags & 0x1cc) == 0x1cc) { | 439 | if ((cpu->flags & 0x1cc) == 0x1cc) { |
440 | smp_num_probed++; | 440 | smp_num_probed++; |
441 | /* Assume here that "whami" == index */ | 441 | /* Assume here that "whami" == index */ |
442 | cpu_set(i, cpu_possible_map); | 442 | cpu_set(i, cpu_present_mask); |
443 | cpu->pal_revision = boot_cpu_palrev; | 443 | cpu->pal_revision = boot_cpu_palrev; |
444 | } | 444 | } |
445 | 445 | ||
@@ -450,9 +450,8 @@ setup_smp(void) | |||
450 | } | 450 | } |
451 | } else { | 451 | } else { |
452 | smp_num_probed = 1; | 452 | smp_num_probed = 1; |
453 | cpu_set(boot_cpuid, cpu_possible_map); | 453 | cpu_set(boot_cpuid, cpu_present_mask); |
454 | } | 454 | } |
455 | cpu_present_mask = cpumask_of_cpu(boot_cpuid); | ||
456 | 455 | ||
457 | printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", | 456 | printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", |
458 | smp_num_probed, cpu_possible_map.bits[0]); | 457 | smp_num_probed, cpu_possible_map.bits[0]); |
@@ -488,9 +487,8 @@ void __devinit | |||
488 | smp_prepare_boot_cpu(void) | 487 | smp_prepare_boot_cpu(void) |
489 | { | 488 | { |
490 | /* | 489 | /* |
491 | * Mark the boot cpu (current cpu) as both present and online | 490 | * Mark the boot cpu (current cpu) as online |
492 | */ | 491 | */ |
493 | cpu_set(smp_processor_id(), cpu_present_mask); | ||
494 | cpu_set(smp_processor_id(), cpu_online_map); | 492 | cpu_set(smp_processor_id(), cpu_online_map); |
495 | } | 493 | } |
496 | 494 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dc5a9332c915..1dbf6ddb300d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -512,6 +512,12 @@ config ARCH_DISCONTIGMEM_ENABLE | |||
512 | or have huge holes in the physical address space for other reasons. | 512 | or have huge holes in the physical address space for other reasons. |
513 | See <file:Documentation/vm/numa> for more. | 513 | See <file:Documentation/vm/numa> for more. |
514 | 514 | ||
515 | config NODES_SHIFT | ||
516 | int | ||
517 | default "4" if ARCH_LH7A40X | ||
518 | default "2" | ||
519 | depends on NEED_MULTIPLE_NODES | ||
520 | |||
515 | source "mm/Kconfig" | 521 | source "mm/Kconfig" |
516 | 522 | ||
517 | config LEDS | 523 | config LEDS |
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index eed616113e47..153a07e7222b 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in | |||
@@ -18,6 +18,7 @@ SECTIONS | |||
18 | _start = .; | 18 | _start = .; |
19 | *(.start) | 19 | *(.start) |
20 | *(.text) | 20 | *(.text) |
21 | *(.text.*) | ||
21 | *(.fixup) | 22 | *(.fixup) |
22 | *(.gnu.warning) | 23 | *(.gnu.warning) |
23 | *(.rodata) | 24 | *(.rodata) |
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index 5e830f444c6c..314ebd3a1d71 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c | |||
@@ -18,6 +18,18 @@ | |||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | #include <asm/hardware/scoop.h> | 19 | #include <asm/hardware/scoop.h> |
20 | 20 | ||
21 | /* PCMCIA to Scoop linkage | ||
22 | |||
23 | There is no easy way to link multiple scoop devices into one | ||
24 | single entity for the pxa2xx_pcmcia device so this structure | ||
25 | is used which is setup by the platform code. | ||
26 | |||
27 | This file is never modular so this symbol is always | ||
28 | accessile to the board support files. | ||
29 | */ | ||
30 | struct scoop_pcmcia_config *platform_scoop_config; | ||
31 | EXPORT_SYMBOL(platform_scoop_config); | ||
32 | |||
21 | #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) | 33 | #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) |
22 | 34 | ||
23 | struct scoop_dev { | 35 | struct scoop_dev { |
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig index 8dcc8e8ec813..b69e88bbc909 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ep93xx_defconfig | |||
@@ -1,12 +1,14 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16 | 3 | # Linux kernel version: 2.6.17-rc2 |
4 | # Mon Mar 20 14:54:51 2006 | 4 | # Wed Apr 19 21:21:01 2006 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
9 | CONFIG_GENERIC_HWEIGHT=y | ||
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_VECTORS_BASE=0xffff0000 | ||
10 | 12 | ||
11 | # | 13 | # |
12 | # Code maturity level options | 14 | # Code maturity level options |
@@ -28,6 +30,7 @@ CONFIG_SYSCTL=y | |||
28 | # CONFIG_AUDIT is not set | 30 | # CONFIG_AUDIT is not set |
29 | CONFIG_IKCONFIG=y | 31 | CONFIG_IKCONFIG=y |
30 | CONFIG_IKCONFIG_PROC=y | 32 | CONFIG_IKCONFIG_PROC=y |
33 | # CONFIG_RELAY is not set | ||
31 | CONFIG_INITRAMFS_SOURCE="" | 34 | CONFIG_INITRAMFS_SOURCE="" |
32 | CONFIG_UID16=y | 35 | CONFIG_UID16=y |
33 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 36 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
@@ -43,10 +46,6 @@ CONFIG_BASE_FULL=y | |||
43 | CONFIG_FUTEX=y | 46 | CONFIG_FUTEX=y |
44 | CONFIG_EPOLL=y | 47 | CONFIG_EPOLL=y |
45 | CONFIG_SHMEM=y | 48 | CONFIG_SHMEM=y |
46 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
47 | CONFIG_CC_ALIGN_LABELS=0 | ||
48 | CONFIG_CC_ALIGN_LOOPS=0 | ||
49 | CONFIG_CC_ALIGN_JUMPS=0 | ||
50 | CONFIG_SLAB=y | 49 | CONFIG_SLAB=y |
51 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
52 | CONFIG_BASE_SMALL=0 | 51 | CONFIG_BASE_SMALL=0 |
@@ -59,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y | |||
59 | CONFIG_MODULES=y | 58 | CONFIG_MODULES=y |
60 | CONFIG_MODULE_UNLOAD=y | 59 | CONFIG_MODULE_UNLOAD=y |
61 | CONFIG_MODULE_FORCE_UNLOAD=y | 60 | CONFIG_MODULE_FORCE_UNLOAD=y |
62 | CONFIG_OBSOLETE_MODPARM=y | ||
63 | # CONFIG_MODVERSIONS is not set | 61 | # CONFIG_MODVERSIONS is not set |
64 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 62 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
65 | CONFIG_KMOD=y | 63 | CONFIG_KMOD=y |
@@ -67,6 +65,7 @@ CONFIG_KMOD=y | |||
67 | # | 65 | # |
68 | # Block layer | 66 | # Block layer |
69 | # | 67 | # |
68 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
70 | 69 | ||
71 | # | 70 | # |
72 | # IO Schedulers | 71 | # IO Schedulers |
@@ -94,6 +93,7 @@ CONFIG_ARCH_EP93XX=y | |||
94 | # CONFIG_ARCH_IOP3XX is not set | 93 | # CONFIG_ARCH_IOP3XX is not set |
95 | # CONFIG_ARCH_IXP4XX is not set | 94 | # CONFIG_ARCH_IXP4XX is not set |
96 | # CONFIG_ARCH_IXP2000 is not set | 95 | # CONFIG_ARCH_IXP2000 is not set |
96 | # CONFIG_ARCH_IXP23XX is not set | ||
97 | # CONFIG_ARCH_L7200 is not set | 97 | # CONFIG_ARCH_L7200 is not set |
98 | # CONFIG_ARCH_PXA is not set | 98 | # CONFIG_ARCH_PXA is not set |
99 | # CONFIG_ARCH_RPC is not set | 99 | # CONFIG_ARCH_RPC is not set |
@@ -112,7 +112,6 @@ CONFIG_ARCH_EP93XX=y | |||
112 | # | 112 | # |
113 | # Cirrus EP93xx Implementation Options | 113 | # Cirrus EP93xx Implementation Options |
114 | # | 114 | # |
115 | CONFIG_CRUNCH=y | ||
116 | 115 | ||
117 | # | 116 | # |
118 | # EP93xx Platforms | 117 | # EP93xx Platforms |
@@ -232,12 +231,15 @@ CONFIG_SYN_COOKIES=y | |||
232 | # CONFIG_INET_AH is not set | 231 | # CONFIG_INET_AH is not set |
233 | # CONFIG_INET_ESP is not set | 232 | # CONFIG_INET_ESP is not set |
234 | # CONFIG_INET_IPCOMP is not set | 233 | # CONFIG_INET_IPCOMP is not set |
234 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
235 | # CONFIG_INET_TUNNEL is not set | 235 | # CONFIG_INET_TUNNEL is not set |
236 | CONFIG_INET_DIAG=y | 236 | CONFIG_INET_DIAG=y |
237 | CONFIG_INET_TCP_DIAG=y | 237 | CONFIG_INET_TCP_DIAG=y |
238 | # CONFIG_TCP_CONG_ADVANCED is not set | 238 | # CONFIG_TCP_CONG_ADVANCED is not set |
239 | CONFIG_TCP_CONG_BIC=y | 239 | CONFIG_TCP_CONG_BIC=y |
240 | # CONFIG_IPV6 is not set | 240 | # CONFIG_IPV6 is not set |
241 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
242 | # CONFIG_INET6_TUNNEL is not set | ||
241 | # CONFIG_NETFILTER is not set | 243 | # CONFIG_NETFILTER is not set |
242 | 244 | ||
243 | # | 245 | # |
@@ -346,7 +348,6 @@ CONFIG_MTD_CFI_I2=y | |||
346 | # CONFIG_MTD_OTP is not set | 348 | # CONFIG_MTD_OTP is not set |
347 | CONFIG_MTD_CFI_INTELEXT=y | 349 | CONFIG_MTD_CFI_INTELEXT=y |
348 | CONFIG_MTD_CFI_AMDSTD=y | 350 | CONFIG_MTD_CFI_AMDSTD=y |
349 | CONFIG_MTD_CFI_AMDSTD_RETRY=0 | ||
350 | CONFIG_MTD_CFI_STAA=y | 351 | CONFIG_MTD_CFI_STAA=y |
351 | CONFIG_MTD_CFI_UTIL=y | 352 | CONFIG_MTD_CFI_UTIL=y |
352 | # CONFIG_MTD_RAM is not set | 353 | # CONFIG_MTD_RAM is not set |
@@ -371,7 +372,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 | |||
371 | # CONFIG_MTD_SLRAM is not set | 372 | # CONFIG_MTD_SLRAM is not set |
372 | # CONFIG_MTD_PHRAM is not set | 373 | # CONFIG_MTD_PHRAM is not set |
373 | # CONFIG_MTD_MTDRAM is not set | 374 | # CONFIG_MTD_MTDRAM is not set |
374 | # CONFIG_MTD_BLKMTD is not set | ||
375 | # CONFIG_MTD_BLOCK2MTD is not set | 375 | # CONFIG_MTD_BLOCK2MTD is not set |
376 | 376 | ||
377 | # | 377 | # |
@@ -412,7 +412,7 @@ CONFIG_MTD_NAND_IDS=y | |||
412 | # CONFIG_BLK_DEV_NBD is not set | 412 | # CONFIG_BLK_DEV_NBD is not set |
413 | # CONFIG_BLK_DEV_UB is not set | 413 | # CONFIG_BLK_DEV_UB is not set |
414 | # CONFIG_BLK_DEV_RAM is not set | 414 | # CONFIG_BLK_DEV_RAM is not set |
415 | CONFIG_BLK_DEV_RAM_COUNT=16 | 415 | # CONFIG_BLK_DEV_INITRD is not set |
416 | # CONFIG_CDROM_PKTCDVD is not set | 416 | # CONFIG_CDROM_PKTCDVD is not set |
417 | # CONFIG_ATA_OVER_ETH is not set | 417 | # CONFIG_ATA_OVER_ETH is not set |
418 | 418 | ||
@@ -576,13 +576,13 @@ CONFIG_WATCHDOG=y | |||
576 | # Watchdog Device Drivers | 576 | # Watchdog Device Drivers |
577 | # | 577 | # |
578 | # CONFIG_SOFT_WATCHDOG is not set | 578 | # CONFIG_SOFT_WATCHDOG is not set |
579 | CONFIG_EP93XX_WATCHDOG=y | ||
579 | 580 | ||
580 | # | 581 | # |
581 | # USB-based Watchdog Cards | 582 | # USB-based Watchdog Cards |
582 | # | 583 | # |
583 | # CONFIG_USBPCWATCHDOG is not set | 584 | # CONFIG_USBPCWATCHDOG is not set |
584 | # CONFIG_NVRAM is not set | 585 | # CONFIG_NVRAM is not set |
585 | # CONFIG_RTC is not set | ||
586 | # CONFIG_DTLK is not set | 586 | # CONFIG_DTLK is not set |
587 | # CONFIG_R3964 is not set | 587 | # CONFIG_R3964 is not set |
588 | 588 | ||
@@ -626,9 +626,7 @@ CONFIG_I2C_ALGOBIT=y | |||
626 | # CONFIG_SENSORS_PCF8574 is not set | 626 | # CONFIG_SENSORS_PCF8574 is not set |
627 | # CONFIG_SENSORS_PCA9539 is not set | 627 | # CONFIG_SENSORS_PCA9539 is not set |
628 | # CONFIG_SENSORS_PCF8591 is not set | 628 | # CONFIG_SENSORS_PCF8591 is not set |
629 | # CONFIG_SENSORS_RTC8564 is not set | ||
630 | # CONFIG_SENSORS_MAX6875 is not set | 629 | # CONFIG_SENSORS_MAX6875 is not set |
631 | # CONFIG_RTC_X1205_I2C is not set | ||
632 | CONFIG_I2C_DEBUG_CORE=y | 630 | CONFIG_I2C_DEBUG_CORE=y |
633 | CONFIG_I2C_DEBUG_ALGO=y | 631 | CONFIG_I2C_DEBUG_ALGO=y |
634 | CONFIG_I2C_DEBUG_BUS=y | 632 | CONFIG_I2C_DEBUG_BUS=y |
@@ -690,7 +688,16 @@ CONFIG_HWMON=y | |||
690 | # | 688 | # |
691 | 689 | ||
692 | # | 690 | # |
693 | # Multimedia Capabilities Port drivers | 691 | # LED devices |
692 | # | ||
693 | # CONFIG_NEW_LEDS is not set | ||
694 | |||
695 | # | ||
696 | # LED drivers | ||
697 | # | ||
698 | |||
699 | # | ||
700 | # LED Triggers | ||
694 | # | 701 | # |
695 | 702 | ||
696 | # | 703 | # |
@@ -702,6 +709,7 @@ CONFIG_HWMON=y | |||
702 | # Digital Video Broadcasting Devices | 709 | # Digital Video Broadcasting Devices |
703 | # | 710 | # |
704 | # CONFIG_DVB is not set | 711 | # CONFIG_DVB is not set |
712 | # CONFIG_USB_DABUSB is not set | ||
705 | 713 | ||
706 | # | 714 | # |
707 | # Graphics support | 715 | # Graphics support |
@@ -718,6 +726,7 @@ CONFIG_HWMON=y | |||
718 | # | 726 | # |
719 | CONFIG_USB_ARCH_HAS_HCD=y | 727 | CONFIG_USB_ARCH_HAS_HCD=y |
720 | # CONFIG_USB_ARCH_HAS_OHCI is not set | 728 | # CONFIG_USB_ARCH_HAS_OHCI is not set |
729 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
721 | CONFIG_USB=y | 730 | CONFIG_USB=y |
722 | CONFIG_USB_DEBUG=y | 731 | CONFIG_USB_DEBUG=y |
723 | 732 | ||
@@ -776,15 +785,6 @@ CONFIG_USB_STORAGE=y | |||
776 | # CONFIG_USB_MICROTEK is not set | 785 | # CONFIG_USB_MICROTEK is not set |
777 | 786 | ||
778 | # | 787 | # |
779 | # USB Multimedia devices | ||
780 | # | ||
781 | # CONFIG_USB_DABUSB is not set | ||
782 | |||
783 | # | ||
784 | # Video4Linux support is needed for USB Multimedia device support | ||
785 | # | ||
786 | |||
787 | # | ||
788 | # USB Network Adapters | 788 | # USB Network Adapters |
789 | # | 789 | # |
790 | # CONFIG_USB_CATC is not set | 790 | # CONFIG_USB_CATC is not set |
@@ -813,6 +813,7 @@ CONFIG_USB_SERIAL_CONSOLE=y | |||
813 | # CONFIG_USB_SERIAL_CYPRESS_M8 is not set | 813 | # CONFIG_USB_SERIAL_CYPRESS_M8 is not set |
814 | # CONFIG_USB_SERIAL_EMPEG is not set | 814 | # CONFIG_USB_SERIAL_EMPEG is not set |
815 | # CONFIG_USB_SERIAL_FTDI_SIO is not set | 815 | # CONFIG_USB_SERIAL_FTDI_SIO is not set |
816 | # CONFIG_USB_SERIAL_FUNSOFT is not set | ||
816 | # CONFIG_USB_SERIAL_VISOR is not set | 817 | # CONFIG_USB_SERIAL_VISOR is not set |
817 | # CONFIG_USB_SERIAL_IPAQ is not set | 818 | # CONFIG_USB_SERIAL_IPAQ is not set |
818 | # CONFIG_USB_SERIAL_IR is not set | 819 | # CONFIG_USB_SERIAL_IR is not set |
@@ -825,6 +826,7 @@ CONFIG_USB_SERIAL_CONSOLE=y | |||
825 | # CONFIG_USB_SERIAL_KLSI is not set | 826 | # CONFIG_USB_SERIAL_KLSI is not set |
826 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set | 827 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set |
827 | # CONFIG_USB_SERIAL_MCT_U232 is not set | 828 | # CONFIG_USB_SERIAL_MCT_U232 is not set |
829 | # CONFIG_USB_SERIAL_NAVMAN is not set | ||
828 | CONFIG_USB_SERIAL_PL2303=y | 830 | CONFIG_USB_SERIAL_PL2303=y |
829 | # CONFIG_USB_SERIAL_HP4X is not set | 831 | # CONFIG_USB_SERIAL_HP4X is not set |
830 | # CONFIG_USB_SERIAL_SAFE is not set | 832 | # CONFIG_USB_SERIAL_SAFE is not set |
@@ -865,6 +867,32 @@ CONFIG_USB_SERIAL_PL2303=y | |||
865 | # CONFIG_MMC is not set | 867 | # CONFIG_MMC is not set |
866 | 868 | ||
867 | # | 869 | # |
870 | # Real Time Clock | ||
871 | # | ||
872 | CONFIG_RTC_LIB=y | ||
873 | CONFIG_RTC_CLASS=y | ||
874 | CONFIG_RTC_HCTOSYS=y | ||
875 | CONFIG_RTC_HCTOSYS_DEVICE="rtc0" | ||
876 | |||
877 | # | ||
878 | # RTC interfaces | ||
879 | # | ||
880 | CONFIG_RTC_INTF_SYSFS=y | ||
881 | CONFIG_RTC_INTF_PROC=y | ||
882 | CONFIG_RTC_INTF_DEV=y | ||
883 | |||
884 | # | ||
885 | # RTC drivers | ||
886 | # | ||
887 | # CONFIG_RTC_DRV_X1205 is not set | ||
888 | # CONFIG_RTC_DRV_DS1672 is not set | ||
889 | # CONFIG_RTC_DRV_PCF8563 is not set | ||
890 | # CONFIG_RTC_DRV_RS5C372 is not set | ||
891 | CONFIG_RTC_DRV_M48T86=y | ||
892 | CONFIG_RTC_DRV_EP93XX=y | ||
893 | # CONFIG_RTC_DRV_TEST is not set | ||
894 | |||
895 | # | ||
868 | # File systems | 896 | # File systems |
869 | # | 897 | # |
870 | CONFIG_EXT2_FS=y | 898 | CONFIG_EXT2_FS=y |
@@ -912,7 +940,6 @@ CONFIG_SYSFS=y | |||
912 | CONFIG_TMPFS=y | 940 | CONFIG_TMPFS=y |
913 | # CONFIG_HUGETLB_PAGE is not set | 941 | # CONFIG_HUGETLB_PAGE is not set |
914 | CONFIG_RAMFS=y | 942 | CONFIG_RAMFS=y |
915 | # CONFIG_RELAYFS_FS is not set | ||
916 | # CONFIG_CONFIGFS_FS is not set | 943 | # CONFIG_CONFIGFS_FS is not set |
917 | 944 | ||
918 | # | 945 | # |
@@ -1044,6 +1071,7 @@ CONFIG_LOG_BUF_SHIFT=14 | |||
1044 | CONFIG_DETECT_SOFTLOCKUP=y | 1071 | CONFIG_DETECT_SOFTLOCKUP=y |
1045 | # CONFIG_SCHEDSTATS is not set | 1072 | # CONFIG_SCHEDSTATS is not set |
1046 | CONFIG_DEBUG_SLAB=y | 1073 | CONFIG_DEBUG_SLAB=y |
1074 | # CONFIG_DEBUG_SLAB_LEAK is not set | ||
1047 | CONFIG_DEBUG_MUTEXES=y | 1075 | CONFIG_DEBUG_MUTEXES=y |
1048 | CONFIG_DEBUG_SPINLOCK=y | 1076 | CONFIG_DEBUG_SPINLOCK=y |
1049 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1077 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
@@ -1053,6 +1081,7 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
1053 | # CONFIG_DEBUG_FS is not set | 1081 | # CONFIG_DEBUG_FS is not set |
1054 | # CONFIG_DEBUG_VM is not set | 1082 | # CONFIG_DEBUG_VM is not set |
1055 | CONFIG_FRAME_POINTER=y | 1083 | CONFIG_FRAME_POINTER=y |
1084 | # CONFIG_UNWIND_INFO is not set | ||
1056 | CONFIG_FORCED_INLINING=y | 1085 | CONFIG_FORCED_INLINING=y |
1057 | # CONFIG_RCU_TORTURE_TEST is not set | 1086 | # CONFIG_RCU_TORTURE_TEST is not set |
1058 | CONFIG_DEBUG_USER=y | 1087 | CONFIG_DEBUG_USER=y |
diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixp2000_defconfig index 7b02ca04c3ee..e6f3e4873d6c 100644 --- a/arch/arm/configs/ixp2000_defconfig +++ b/arch/arm/configs/ixp2000_defconfig | |||
@@ -1,18 +1,19 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16-rc2 | 3 | # Linux kernel version: 2.6.17-rc2 |
4 | # Wed Feb 8 04:49:11 2006 | 4 | # Wed Apr 19 21:12:49 2006 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
9 | CONFIG_GENERIC_HWEIGHT=y | ||
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_VECTORS_BASE=0xffff0000 | ||
10 | 12 | ||
11 | # | 13 | # |
12 | # Code maturity level options | 14 | # Code maturity level options |
13 | # | 15 | # |
14 | CONFIG_EXPERIMENTAL=y | 16 | CONFIG_EXPERIMENTAL=y |
15 | CONFIG_CLEAN_COMPILE=y | ||
16 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
17 | CONFIG_INIT_ENV_ARG_LIMIT=32 | 18 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
18 | 19 | ||
@@ -29,6 +30,7 @@ CONFIG_BSD_PROCESS_ACCT=y | |||
29 | CONFIG_SYSCTL=y | 30 | CONFIG_SYSCTL=y |
30 | # CONFIG_AUDIT is not set | 31 | # CONFIG_AUDIT is not set |
31 | # CONFIG_IKCONFIG is not set | 32 | # CONFIG_IKCONFIG is not set |
33 | # CONFIG_RELAY is not set | ||
32 | CONFIG_INITRAMFS_SOURCE="" | 34 | CONFIG_INITRAMFS_SOURCE="" |
33 | CONFIG_UID16=y | 35 | CONFIG_UID16=y |
34 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 36 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
@@ -44,10 +46,6 @@ CONFIG_BASE_FULL=y | |||
44 | CONFIG_FUTEX=y | 46 | CONFIG_FUTEX=y |
45 | CONFIG_EPOLL=y | 47 | CONFIG_EPOLL=y |
46 | CONFIG_SHMEM=y | 48 | CONFIG_SHMEM=y |
47 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
48 | CONFIG_CC_ALIGN_LABELS=0 | ||
49 | CONFIG_CC_ALIGN_LOOPS=0 | ||
50 | CONFIG_CC_ALIGN_JUMPS=0 | ||
51 | CONFIG_SLAB=y | 49 | CONFIG_SLAB=y |
52 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
53 | CONFIG_BASE_SMALL=0 | 51 | CONFIG_BASE_SMALL=0 |
@@ -60,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y | |||
60 | CONFIG_MODULES=y | 58 | CONFIG_MODULES=y |
61 | CONFIG_MODULE_UNLOAD=y | 59 | CONFIG_MODULE_UNLOAD=y |
62 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 60 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
63 | CONFIG_OBSOLETE_MODPARM=y | ||
64 | # CONFIG_MODVERSIONS is not set | 61 | # CONFIG_MODVERSIONS is not set |
65 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 62 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
66 | CONFIG_KMOD=y | 63 | CONFIG_KMOD=y |
@@ -68,6 +65,7 @@ CONFIG_KMOD=y | |||
68 | # | 65 | # |
69 | # Block layer | 66 | # Block layer |
70 | # | 67 | # |
68 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
71 | 69 | ||
72 | # | 70 | # |
73 | # IO Schedulers | 71 | # IO Schedulers |
@@ -89,11 +87,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" | |||
89 | # CONFIG_ARCH_CLPS711X is not set | 87 | # CONFIG_ARCH_CLPS711X is not set |
90 | # CONFIG_ARCH_CO285 is not set | 88 | # CONFIG_ARCH_CO285 is not set |
91 | # CONFIG_ARCH_EBSA110 is not set | 89 | # CONFIG_ARCH_EBSA110 is not set |
90 | # CONFIG_ARCH_EP93XX is not set | ||
92 | # CONFIG_ARCH_FOOTBRIDGE is not set | 91 | # CONFIG_ARCH_FOOTBRIDGE is not set |
93 | # CONFIG_ARCH_INTEGRATOR is not set | 92 | # CONFIG_ARCH_INTEGRATOR is not set |
94 | # CONFIG_ARCH_IOP3XX is not set | 93 | # CONFIG_ARCH_IOP3XX is not set |
95 | # CONFIG_ARCH_IXP4XX is not set | 94 | # CONFIG_ARCH_IXP4XX is not set |
96 | CONFIG_ARCH_IXP2000=y | 95 | CONFIG_ARCH_IXP2000=y |
96 | # CONFIG_ARCH_IXP23XX is not set | ||
97 | # CONFIG_ARCH_L7200 is not set | 97 | # CONFIG_ARCH_L7200 is not set |
98 | # CONFIG_ARCH_PXA is not set | 98 | # CONFIG_ARCH_PXA is not set |
99 | # CONFIG_ARCH_RPC is not set | 99 | # CONFIG_ARCH_RPC is not set |
@@ -123,6 +123,7 @@ CONFIG_ARCH_IXDP2800=y | |||
123 | CONFIG_ARCH_IXDP2X00=y | 123 | CONFIG_ARCH_IXDP2X00=y |
124 | CONFIG_ARCH_IXDP2401=y | 124 | CONFIG_ARCH_IXDP2401=y |
125 | CONFIG_ARCH_IXDP2801=y | 125 | CONFIG_ARCH_IXDP2801=y |
126 | CONFIG_MACH_IXDP28X5=y | ||
126 | CONFIG_ARCH_IXDP2X01=y | 127 | CONFIG_ARCH_IXDP2X01=y |
127 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | 128 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set |
128 | 129 | ||
@@ -147,7 +148,6 @@ CONFIG_XSCALE_PMU=y | |||
147 | # Bus support | 148 | # Bus support |
148 | # | 149 | # |
149 | CONFIG_PCI=y | 150 | CONFIG_PCI=y |
150 | CONFIG_PCI_LEGACY_PROC=y | ||
151 | # CONFIG_PCI_DEBUG is not set | 151 | # CONFIG_PCI_DEBUG is not set |
152 | 152 | ||
153 | # | 153 | # |
@@ -160,6 +160,7 @@ CONFIG_PCI_LEGACY_PROC=y | |||
160 | # | 160 | # |
161 | # CONFIG_PREEMPT is not set | 161 | # CONFIG_PREEMPT is not set |
162 | # CONFIG_NO_IDLE_HZ is not set | 162 | # CONFIG_NO_IDLE_HZ is not set |
163 | CONFIG_HZ=100 | ||
163 | # CONFIG_AEABI is not set | 164 | # CONFIG_AEABI is not set |
164 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | 165 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set |
165 | CONFIG_SELECT_MEMORY_MODEL=y | 166 | CONFIG_SELECT_MEMORY_MODEL=y |
@@ -213,6 +214,7 @@ CONFIG_NET=y | |||
213 | # | 214 | # |
214 | # Networking options | 215 | # Networking options |
215 | # | 216 | # |
217 | # CONFIG_NETDEBUG is not set | ||
216 | CONFIG_PACKET=y | 218 | CONFIG_PACKET=y |
217 | CONFIG_PACKET_MMAP=y | 219 | CONFIG_PACKET_MMAP=y |
218 | CONFIG_UNIX=y | 220 | CONFIG_UNIX=y |
@@ -232,12 +234,15 @@ CONFIG_SYN_COOKIES=y | |||
232 | # CONFIG_INET_AH is not set | 234 | # CONFIG_INET_AH is not set |
233 | # CONFIG_INET_ESP is not set | 235 | # CONFIG_INET_ESP is not set |
234 | # CONFIG_INET_IPCOMP is not set | 236 | # CONFIG_INET_IPCOMP is not set |
237 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
235 | # CONFIG_INET_TUNNEL is not set | 238 | # CONFIG_INET_TUNNEL is not set |
236 | CONFIG_INET_DIAG=y | 239 | CONFIG_INET_DIAG=y |
237 | CONFIG_INET_TCP_DIAG=y | 240 | CONFIG_INET_TCP_DIAG=y |
238 | # CONFIG_TCP_CONG_ADVANCED is not set | 241 | # CONFIG_TCP_CONG_ADVANCED is not set |
239 | CONFIG_TCP_CONG_BIC=y | 242 | CONFIG_TCP_CONG_BIC=y |
240 | # CONFIG_IPV6 is not set | 243 | # CONFIG_IPV6 is not set |
244 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
245 | # CONFIG_INET6_TUNNEL is not set | ||
241 | # CONFIG_NETFILTER is not set | 246 | # CONFIG_NETFILTER is not set |
242 | 247 | ||
243 | # | 248 | # |
@@ -347,7 +352,6 @@ CONFIG_MTD_CFI_UTIL=y | |||
347 | # CONFIG_MTD_ROM is not set | 352 | # CONFIG_MTD_ROM is not set |
348 | # CONFIG_MTD_ABSENT is not set | 353 | # CONFIG_MTD_ABSENT is not set |
349 | # CONFIG_MTD_OBSOLETE_CHIPS is not set | 354 | # CONFIG_MTD_OBSOLETE_CHIPS is not set |
350 | # CONFIG_MTD_XIP is not set | ||
351 | 355 | ||
352 | # | 356 | # |
353 | # Mapping drivers for chip access | 357 | # Mapping drivers for chip access |
@@ -366,7 +370,6 @@ CONFIG_MTD_IXP2000=y | |||
366 | # CONFIG_MTD_SLRAM is not set | 370 | # CONFIG_MTD_SLRAM is not set |
367 | # CONFIG_MTD_PHRAM is not set | 371 | # CONFIG_MTD_PHRAM is not set |
368 | # CONFIG_MTD_MTDRAM is not set | 372 | # CONFIG_MTD_MTDRAM is not set |
369 | # CONFIG_MTD_BLKMTD is not set | ||
370 | # CONFIG_MTD_BLOCK2MTD is not set | 373 | # CONFIG_MTD_BLOCK2MTD is not set |
371 | 374 | ||
372 | # | 375 | # |
@@ -614,8 +617,9 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
614 | # | 617 | # |
615 | CONFIG_SERIAL_8250=y | 618 | CONFIG_SERIAL_8250=y |
616 | CONFIG_SERIAL_8250_CONSOLE=y | 619 | CONFIG_SERIAL_8250_CONSOLE=y |
620 | CONFIG_SERIAL_8250_PCI=y | ||
617 | CONFIG_SERIAL_8250_NR_UARTS=3 | 621 | CONFIG_SERIAL_8250_NR_UARTS=3 |
618 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | 622 | CONFIG_SERIAL_8250_RUNTIME_UARTS=3 |
619 | # CONFIG_SERIAL_8250_EXTENDED is not set | 623 | # CONFIG_SERIAL_8250_EXTENDED is not set |
620 | 624 | ||
621 | # | 625 | # |
@@ -623,6 +627,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | |||
623 | # | 627 | # |
624 | CONFIG_SERIAL_CORE=y | 628 | CONFIG_SERIAL_CORE=y |
625 | CONFIG_SERIAL_CORE_CONSOLE=y | 629 | CONFIG_SERIAL_CORE_CONSOLE=y |
630 | # CONFIG_SERIAL_JSM is not set | ||
626 | CONFIG_UNIX98_PTYS=y | 631 | CONFIG_UNIX98_PTYS=y |
627 | CONFIG_LEGACY_PTYS=y | 632 | CONFIG_LEGACY_PTYS=y |
628 | CONFIG_LEGACY_PTY_COUNT=256 | 633 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -650,7 +655,6 @@ CONFIG_IXP2000_WATCHDOG=y | |||
650 | # CONFIG_PCIPCWATCHDOG is not set | 655 | # CONFIG_PCIPCWATCHDOG is not set |
651 | # CONFIG_WDTPCI is not set | 656 | # CONFIG_WDTPCI is not set |
652 | # CONFIG_NVRAM is not set | 657 | # CONFIG_NVRAM is not set |
653 | # CONFIG_RTC is not set | ||
654 | # CONFIG_DTLK is not set | 658 | # CONFIG_DTLK is not set |
655 | # CONFIG_R3964 is not set | 659 | # CONFIG_R3964 is not set |
656 | # CONFIG_APPLICOM is not set | 660 | # CONFIG_APPLICOM is not set |
@@ -696,7 +700,6 @@ CONFIG_I2C_IXP2000=y | |||
696 | # CONFIG_I2C_PARPORT_LIGHT is not set | 700 | # CONFIG_I2C_PARPORT_LIGHT is not set |
697 | # CONFIG_I2C_PROSAVAGE is not set | 701 | # CONFIG_I2C_PROSAVAGE is not set |
698 | # CONFIG_I2C_SAVAGE4 is not set | 702 | # CONFIG_I2C_SAVAGE4 is not set |
699 | # CONFIG_SCx200_ACB is not set | ||
700 | # CONFIG_I2C_SIS5595 is not set | 703 | # CONFIG_I2C_SIS5595 is not set |
701 | # CONFIG_I2C_SIS630 is not set | 704 | # CONFIG_I2C_SIS630 is not set |
702 | # CONFIG_I2C_SIS96X is not set | 705 | # CONFIG_I2C_SIS96X is not set |
@@ -715,9 +718,7 @@ CONFIG_SENSORS_EEPROM=y | |||
715 | # CONFIG_SENSORS_PCF8574 is not set | 718 | # CONFIG_SENSORS_PCF8574 is not set |
716 | # CONFIG_SENSORS_PCA9539 is not set | 719 | # CONFIG_SENSORS_PCA9539 is not set |
717 | # CONFIG_SENSORS_PCF8591 is not set | 720 | # CONFIG_SENSORS_PCF8591 is not set |
718 | # CONFIG_SENSORS_RTC8564 is not set | ||
719 | # CONFIG_SENSORS_MAX6875 is not set | 721 | # CONFIG_SENSORS_MAX6875 is not set |
720 | # CONFIG_RTC_X1205_I2C is not set | ||
721 | # CONFIG_I2C_DEBUG_CORE is not set | 722 | # CONFIG_I2C_DEBUG_CORE is not set |
722 | # CONFIG_I2C_DEBUG_ALGO is not set | 723 | # CONFIG_I2C_DEBUG_ALGO is not set |
723 | # CONFIG_I2C_DEBUG_BUS is not set | 724 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -730,6 +731,11 @@ CONFIG_SENSORS_EEPROM=y | |||
730 | # CONFIG_SPI_MASTER is not set | 731 | # CONFIG_SPI_MASTER is not set |
731 | 732 | ||
732 | # | 733 | # |
734 | # Dallas's 1-wire bus | ||
735 | # | ||
736 | # CONFIG_W1 is not set | ||
737 | |||
738 | # | ||
733 | # Hardware Monitoring support | 739 | # Hardware Monitoring support |
734 | # | 740 | # |
735 | CONFIG_HWMON=y | 741 | CONFIG_HWMON=y |
@@ -742,6 +748,7 @@ CONFIG_HWMON=y | |||
742 | # CONFIG_SENSORS_ASB100 is not set | 748 | # CONFIG_SENSORS_ASB100 is not set |
743 | # CONFIG_SENSORS_ATXP1 is not set | 749 | # CONFIG_SENSORS_ATXP1 is not set |
744 | # CONFIG_SENSORS_DS1621 is not set | 750 | # CONFIG_SENSORS_DS1621 is not set |
751 | # CONFIG_SENSORS_F71805F is not set | ||
745 | # CONFIG_SENSORS_FSCHER is not set | 752 | # CONFIG_SENSORS_FSCHER is not set |
746 | # CONFIG_SENSORS_FSCPOS is not set | 753 | # CONFIG_SENSORS_FSCPOS is not set |
747 | # CONFIG_SENSORS_GL518SM is not set | 754 | # CONFIG_SENSORS_GL518SM is not set |
@@ -776,7 +783,16 @@ CONFIG_HWMON=y | |||
776 | # | 783 | # |
777 | 784 | ||
778 | # | 785 | # |
779 | # Multimedia Capabilities Port drivers | 786 | # LED devices |
787 | # | ||
788 | # CONFIG_NEW_LEDS is not set | ||
789 | |||
790 | # | ||
791 | # LED drivers | ||
792 | # | ||
793 | |||
794 | # | ||
795 | # LED Triggers | ||
780 | # | 796 | # |
781 | 797 | ||
782 | # | 798 | # |
@@ -804,6 +820,7 @@ CONFIG_HWMON=y | |||
804 | # | 820 | # |
805 | CONFIG_USB_ARCH_HAS_HCD=y | 821 | CONFIG_USB_ARCH_HAS_HCD=y |
806 | CONFIG_USB_ARCH_HAS_OHCI=y | 822 | CONFIG_USB_ARCH_HAS_OHCI=y |
823 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
807 | # CONFIG_USB is not set | 824 | # CONFIG_USB is not set |
808 | 825 | ||
809 | # | 826 | # |
@@ -821,6 +838,12 @@ CONFIG_USB_ARCH_HAS_OHCI=y | |||
821 | # CONFIG_MMC is not set | 838 | # CONFIG_MMC is not set |
822 | 839 | ||
823 | # | 840 | # |
841 | # Real Time Clock | ||
842 | # | ||
843 | CONFIG_RTC_LIB=y | ||
844 | # CONFIG_RTC_CLASS is not set | ||
845 | |||
846 | # | ||
824 | # File systems | 847 | # File systems |
825 | # | 848 | # |
826 | CONFIG_EXT2_FS=y | 849 | CONFIG_EXT2_FS=y |
@@ -870,7 +893,6 @@ CONFIG_SYSFS=y | |||
870 | CONFIG_TMPFS=y | 893 | CONFIG_TMPFS=y |
871 | # CONFIG_HUGETLB_PAGE is not set | 894 | # CONFIG_HUGETLB_PAGE is not set |
872 | CONFIG_RAMFS=y | 895 | CONFIG_RAMFS=y |
873 | # CONFIG_RELAYFS_FS is not set | ||
874 | # CONFIG_CONFIGFS_FS is not set | 896 | # CONFIG_CONFIGFS_FS is not set |
875 | 897 | ||
876 | # | 898 | # |
@@ -972,6 +994,7 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
972 | # CONFIG_DEBUG_FS is not set | 994 | # CONFIG_DEBUG_FS is not set |
973 | # CONFIG_DEBUG_VM is not set | 995 | # CONFIG_DEBUG_VM is not set |
974 | CONFIG_FRAME_POINTER=y | 996 | CONFIG_FRAME_POINTER=y |
997 | # CONFIG_UNWIND_INFO is not set | ||
975 | CONFIG_FORCED_INLINING=y | 998 | CONFIG_FORCED_INLINING=y |
976 | # CONFIG_RCU_TORTURE_TEST is not set | 999 | # CONFIG_RCU_TORTURE_TEST is not set |
977 | CONFIG_DEBUG_USER=y | 1000 | CONFIG_DEBUG_USER=y |
diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig index 1a2751e9ab05..9ce898a6cf87 100644 --- a/arch/arm/configs/ixp23xx_defconfig +++ b/arch/arm/configs/ixp23xx_defconfig | |||
@@ -1,12 +1,14 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16 | 3 | # Linux kernel version: 2.6.17-rc2 |
4 | # Tue Mar 21 03:27:20 2006 | 4 | # Wed Apr 19 21:13:50 2006 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
9 | CONFIG_GENERIC_HWEIGHT=y | ||
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_VECTORS_BASE=0xffff0000 | ||
10 | 12 | ||
11 | # | 13 | # |
12 | # Code maturity level options | 14 | # Code maturity level options |
@@ -28,6 +30,7 @@ CONFIG_BSD_PROCESS_ACCT=y | |||
28 | CONFIG_SYSCTL=y | 30 | CONFIG_SYSCTL=y |
29 | # CONFIG_AUDIT is not set | 31 | # CONFIG_AUDIT is not set |
30 | # CONFIG_IKCONFIG is not set | 32 | # CONFIG_IKCONFIG is not set |
33 | # CONFIG_RELAY is not set | ||
31 | CONFIG_INITRAMFS_SOURCE="" | 34 | CONFIG_INITRAMFS_SOURCE="" |
32 | CONFIG_UID16=y | 35 | CONFIG_UID16=y |
33 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 36 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
@@ -43,10 +46,6 @@ CONFIG_BASE_FULL=y | |||
43 | CONFIG_FUTEX=y | 46 | CONFIG_FUTEX=y |
44 | CONFIG_EPOLL=y | 47 | CONFIG_EPOLL=y |
45 | CONFIG_SHMEM=y | 48 | CONFIG_SHMEM=y |
46 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
47 | CONFIG_CC_ALIGN_LABELS=0 | ||
48 | CONFIG_CC_ALIGN_LOOPS=0 | ||
49 | CONFIG_CC_ALIGN_JUMPS=0 | ||
50 | CONFIG_SLAB=y | 49 | CONFIG_SLAB=y |
51 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
52 | CONFIG_BASE_SMALL=0 | 51 | CONFIG_BASE_SMALL=0 |
@@ -59,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y | |||
59 | CONFIG_MODULES=y | 58 | CONFIG_MODULES=y |
60 | CONFIG_MODULE_UNLOAD=y | 59 | CONFIG_MODULE_UNLOAD=y |
61 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 60 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
62 | CONFIG_OBSOLETE_MODPARM=y | ||
63 | # CONFIG_MODVERSIONS is not set | 61 | # CONFIG_MODVERSIONS is not set |
64 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 62 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
65 | CONFIG_KMOD=y | 63 | CONFIG_KMOD=y |
@@ -67,6 +65,7 @@ CONFIG_KMOD=y | |||
67 | # | 65 | # |
68 | # Block layer | 66 | # Block layer |
69 | # | 67 | # |
68 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
70 | 69 | ||
71 | # | 70 | # |
72 | # IO Schedulers | 71 | # IO Schedulers |
@@ -143,7 +142,6 @@ CONFIG_CPU_BIG_ENDIAN=y | |||
143 | # Bus support | 142 | # Bus support |
144 | # | 143 | # |
145 | CONFIG_PCI=y | 144 | CONFIG_PCI=y |
146 | CONFIG_PCI_LEGACY_PROC=y | ||
147 | # CONFIG_PCI_DEBUG is not set | 145 | # CONFIG_PCI_DEBUG is not set |
148 | 146 | ||
149 | # | 147 | # |
@@ -230,12 +228,15 @@ CONFIG_SYN_COOKIES=y | |||
230 | # CONFIG_INET_AH is not set | 228 | # CONFIG_INET_AH is not set |
231 | # CONFIG_INET_ESP is not set | 229 | # CONFIG_INET_ESP is not set |
232 | # CONFIG_INET_IPCOMP is not set | 230 | # CONFIG_INET_IPCOMP is not set |
231 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
233 | # CONFIG_INET_TUNNEL is not set | 232 | # CONFIG_INET_TUNNEL is not set |
234 | CONFIG_INET_DIAG=y | 233 | CONFIG_INET_DIAG=y |
235 | CONFIG_INET_TCP_DIAG=y | 234 | CONFIG_INET_TCP_DIAG=y |
236 | # CONFIG_TCP_CONG_ADVANCED is not set | 235 | # CONFIG_TCP_CONG_ADVANCED is not set |
237 | CONFIG_TCP_CONG_BIC=y | 236 | CONFIG_TCP_CONG_BIC=y |
238 | # CONFIG_IPV6 is not set | 237 | # CONFIG_IPV6 is not set |
238 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
239 | # CONFIG_INET6_TUNNEL is not set | ||
239 | # CONFIG_NETFILTER is not set | 240 | # CONFIG_NETFILTER is not set |
240 | 241 | ||
241 | # | 242 | # |
@@ -365,7 +366,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 | |||
365 | # CONFIG_MTD_SLRAM is not set | 366 | # CONFIG_MTD_SLRAM is not set |
366 | # CONFIG_MTD_PHRAM is not set | 367 | # CONFIG_MTD_PHRAM is not set |
367 | # CONFIG_MTD_MTDRAM is not set | 368 | # CONFIG_MTD_MTDRAM is not set |
368 | # CONFIG_MTD_BLKMTD is not set | ||
369 | # CONFIG_MTD_BLOCK2MTD is not set | 369 | # CONFIG_MTD_BLOCK2MTD is not set |
370 | 370 | ||
371 | # | 371 | # |
@@ -527,7 +527,6 @@ CONFIG_BLK_DEV_SD=y | |||
527 | # CONFIG_SCSI_INIA100 is not set | 527 | # CONFIG_SCSI_INIA100 is not set |
528 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 528 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
529 | # CONFIG_SCSI_IPR is not set | 529 | # CONFIG_SCSI_IPR is not set |
530 | # CONFIG_SCSI_QLOGIC_FC is not set | ||
531 | # CONFIG_SCSI_QLOGIC_1280 is not set | 530 | # CONFIG_SCSI_QLOGIC_1280 is not set |
532 | # CONFIG_SCSI_QLA_FC is not set | 531 | # CONFIG_SCSI_QLA_FC is not set |
533 | # CONFIG_SCSI_LPFC is not set | 532 | # CONFIG_SCSI_LPFC is not set |
@@ -735,6 +734,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
735 | # | 734 | # |
736 | CONFIG_SERIAL_8250=y | 735 | CONFIG_SERIAL_8250=y |
737 | CONFIG_SERIAL_8250_CONSOLE=y | 736 | CONFIG_SERIAL_8250_CONSOLE=y |
737 | CONFIG_SERIAL_8250_PCI=y | ||
738 | CONFIG_SERIAL_8250_NR_UARTS=4 | 738 | CONFIG_SERIAL_8250_NR_UARTS=4 |
739 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | 739 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 |
740 | # CONFIG_SERIAL_8250_EXTENDED is not set | 740 | # CONFIG_SERIAL_8250_EXTENDED is not set |
@@ -776,7 +776,6 @@ CONFIG_WATCHDOG=y | |||
776 | # | 776 | # |
777 | # CONFIG_USBPCWATCHDOG is not set | 777 | # CONFIG_USBPCWATCHDOG is not set |
778 | # CONFIG_NVRAM is not set | 778 | # CONFIG_NVRAM is not set |
779 | # CONFIG_RTC is not set | ||
780 | # CONFIG_DTLK is not set | 779 | # CONFIG_DTLK is not set |
781 | # CONFIG_R3964 is not set | 780 | # CONFIG_R3964 is not set |
782 | # CONFIG_APPLICOM is not set | 781 | # CONFIG_APPLICOM is not set |
@@ -821,7 +820,6 @@ CONFIG_I2C_ALGOBIT=y | |||
821 | # CONFIG_I2C_PARPORT_LIGHT is not set | 820 | # CONFIG_I2C_PARPORT_LIGHT is not set |
822 | # CONFIG_I2C_PROSAVAGE is not set | 821 | # CONFIG_I2C_PROSAVAGE is not set |
823 | # CONFIG_I2C_SAVAGE4 is not set | 822 | # CONFIG_I2C_SAVAGE4 is not set |
824 | # CONFIG_SCx200_ACB is not set | ||
825 | # CONFIG_I2C_SIS5595 is not set | 823 | # CONFIG_I2C_SIS5595 is not set |
826 | # CONFIG_I2C_SIS630 is not set | 824 | # CONFIG_I2C_SIS630 is not set |
827 | # CONFIG_I2C_SIS96X is not set | 825 | # CONFIG_I2C_SIS96X is not set |
@@ -840,9 +838,7 @@ CONFIG_SENSORS_EEPROM=y | |||
840 | # CONFIG_SENSORS_PCF8574 is not set | 838 | # CONFIG_SENSORS_PCF8574 is not set |
841 | # CONFIG_SENSORS_PCA9539 is not set | 839 | # CONFIG_SENSORS_PCA9539 is not set |
842 | # CONFIG_SENSORS_PCF8591 is not set | 840 | # CONFIG_SENSORS_PCF8591 is not set |
843 | # CONFIG_SENSORS_RTC8564 is not set | ||
844 | # CONFIG_SENSORS_MAX6875 is not set | 841 | # CONFIG_SENSORS_MAX6875 is not set |
845 | # CONFIG_RTC_X1205_I2C is not set | ||
846 | # CONFIG_I2C_DEBUG_CORE is not set | 842 | # CONFIG_I2C_DEBUG_CORE is not set |
847 | # CONFIG_I2C_DEBUG_ALGO is not set | 843 | # CONFIG_I2C_DEBUG_ALGO is not set |
848 | # CONFIG_I2C_DEBUG_BUS is not set | 844 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -907,7 +903,16 @@ CONFIG_HWMON=y | |||
907 | # | 903 | # |
908 | 904 | ||
909 | # | 905 | # |
910 | # Multimedia Capabilities Port drivers | 906 | # LED devices |
907 | # | ||
908 | # CONFIG_NEW_LEDS is not set | ||
909 | |||
910 | # | ||
911 | # LED drivers | ||
912 | # | ||
913 | |||
914 | # | ||
915 | # LED Triggers | ||
911 | # | 916 | # |
912 | 917 | ||
913 | # | 918 | # |
@@ -919,6 +924,7 @@ CONFIG_HWMON=y | |||
919 | # Digital Video Broadcasting Devices | 924 | # Digital Video Broadcasting Devices |
920 | # | 925 | # |
921 | # CONFIG_DVB is not set | 926 | # CONFIG_DVB is not set |
927 | # CONFIG_USB_DABUSB is not set | ||
922 | 928 | ||
923 | # | 929 | # |
924 | # Graphics support | 930 | # Graphics support |
@@ -935,6 +941,7 @@ CONFIG_HWMON=y | |||
935 | # | 941 | # |
936 | CONFIG_USB_ARCH_HAS_HCD=y | 942 | CONFIG_USB_ARCH_HAS_HCD=y |
937 | CONFIG_USB_ARCH_HAS_OHCI=y | 943 | CONFIG_USB_ARCH_HAS_OHCI=y |
944 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
938 | CONFIG_USB=y | 945 | CONFIG_USB=y |
939 | # CONFIG_USB_DEBUG is not set | 946 | # CONFIG_USB_DEBUG is not set |
940 | 947 | ||
@@ -1000,9 +1007,7 @@ CONFIG_USB_STORAGE=y | |||
1000 | # CONFIG_USB_ACECAD is not set | 1007 | # CONFIG_USB_ACECAD is not set |
1001 | # CONFIG_USB_KBTAB is not set | 1008 | # CONFIG_USB_KBTAB is not set |
1002 | # CONFIG_USB_POWERMATE is not set | 1009 | # CONFIG_USB_POWERMATE is not set |
1003 | # CONFIG_USB_MTOUCH is not set | 1010 | # CONFIG_USB_TOUCHSCREEN is not set |
1004 | # CONFIG_USB_ITMTOUCH is not set | ||
1005 | # CONFIG_USB_EGALAX is not set | ||
1006 | # CONFIG_USB_YEALINK is not set | 1011 | # CONFIG_USB_YEALINK is not set |
1007 | # CONFIG_USB_XPAD is not set | 1012 | # CONFIG_USB_XPAD is not set |
1008 | # CONFIG_USB_ATI_REMOTE is not set | 1013 | # CONFIG_USB_ATI_REMOTE is not set |
@@ -1017,15 +1022,6 @@ CONFIG_USB_STORAGE=y | |||
1017 | # CONFIG_USB_MICROTEK is not set | 1022 | # CONFIG_USB_MICROTEK is not set |
1018 | 1023 | ||
1019 | # | 1024 | # |
1020 | # USB Multimedia devices | ||
1021 | # | ||
1022 | # CONFIG_USB_DABUSB is not set | ||
1023 | |||
1024 | # | ||
1025 | # Video4Linux support is needed for USB Multimedia device support | ||
1026 | # | ||
1027 | |||
1028 | # | ||
1029 | # USB Network Adapters | 1025 | # USB Network Adapters |
1030 | # | 1026 | # |
1031 | # CONFIG_USB_CATC is not set | 1027 | # CONFIG_USB_CATC is not set |
@@ -1076,6 +1072,12 @@ CONFIG_USB_MON=y | |||
1076 | # CONFIG_MMC is not set | 1072 | # CONFIG_MMC is not set |
1077 | 1073 | ||
1078 | # | 1074 | # |
1075 | # Real Time Clock | ||
1076 | # | ||
1077 | CONFIG_RTC_LIB=y | ||
1078 | # CONFIG_RTC_CLASS is not set | ||
1079 | |||
1080 | # | ||
1079 | # File systems | 1081 | # File systems |
1080 | # | 1082 | # |
1081 | CONFIG_EXT2_FS=y | 1083 | CONFIG_EXT2_FS=y |
@@ -1127,7 +1129,6 @@ CONFIG_SYSFS=y | |||
1127 | CONFIG_TMPFS=y | 1129 | CONFIG_TMPFS=y |
1128 | # CONFIG_HUGETLB_PAGE is not set | 1130 | # CONFIG_HUGETLB_PAGE is not set |
1129 | CONFIG_RAMFS=y | 1131 | CONFIG_RAMFS=y |
1130 | # CONFIG_RELAYFS_FS is not set | ||
1131 | # CONFIG_CONFIGFS_FS is not set | 1132 | # CONFIG_CONFIGFS_FS is not set |
1132 | 1133 | ||
1133 | # | 1134 | # |
@@ -1268,6 +1269,7 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
1268 | # CONFIG_DEBUG_FS is not set | 1269 | # CONFIG_DEBUG_FS is not set |
1269 | # CONFIG_DEBUG_VM is not set | 1270 | # CONFIG_DEBUG_VM is not set |
1270 | CONFIG_FRAME_POINTER=y | 1271 | CONFIG_FRAME_POINTER=y |
1272 | # CONFIG_UNWIND_INFO is not set | ||
1271 | CONFIG_FORCED_INLINING=y | 1273 | CONFIG_FORCED_INLINING=y |
1272 | # CONFIG_RCU_TORTURE_TEST is not set | 1274 | # CONFIG_RCU_TORTURE_TEST is not set |
1273 | CONFIG_DEBUG_USER=y | 1275 | CONFIG_DEBUG_USER=y |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index ee083b3f0522..c49b5d4d7fca 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
@@ -101,7 +101,6 @@ EXPORT_SYMBOL(__raw_writesl); | |||
101 | 101 | ||
102 | /* string / mem functions */ | 102 | /* string / mem functions */ |
103 | EXPORT_SYMBOL(strchr); | 103 | EXPORT_SYMBOL(strchr); |
104 | EXPORT_SYMBOL(strpbrk); | ||
105 | EXPORT_SYMBOL(strrchr); | 104 | EXPORT_SYMBOL(strrchr); |
106 | EXPORT_SYMBOL(memset); | 105 | EXPORT_SYMBOL(memset); |
107 | EXPORT_SYMBOL(memcpy); | 106 | EXPORT_SYMBOL(memcpy); |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 437528403959..9fc9af88c60c 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -322,6 +322,12 @@ static void __init setup_processor(void) | |||
322 | sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); | 322 | sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); |
323 | sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); | 323 | sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); |
324 | elf_hwcap = list->elf_hwcap; | 324 | elf_hwcap = list->elf_hwcap; |
325 | #ifndef CONFIG_ARM_THUMB | ||
326 | elf_hwcap &= ~HWCAP_THUMB; | ||
327 | #endif | ||
328 | #ifndef CONFIG_VFP | ||
329 | elf_hwcap &= ~HWCAP_VFP; | ||
330 | #endif | ||
325 | 331 | ||
326 | cpu_proc_init(); | 332 | cpu_proc_init(); |
327 | } | 333 | } |
@@ -401,7 +407,7 @@ static void __init early_initrd(char **p) | |||
401 | } | 407 | } |
402 | __early_param("initrd=", early_initrd); | 408 | __early_param("initrd=", early_initrd); |
403 | 409 | ||
404 | static void __init add_memory(unsigned long start, unsigned long size) | 410 | static void __init arm_add_memory(unsigned long start, unsigned long size) |
405 | { | 411 | { |
406 | /* | 412 | /* |
407 | * Ensure that start/size are aligned to a page boundary. | 413 | * Ensure that start/size are aligned to a page boundary. |
@@ -439,7 +445,7 @@ static void __init early_mem(char **p) | |||
439 | if (**p == '@') | 445 | if (**p == '@') |
440 | start = memparse(*p + 1, p); | 446 | start = memparse(*p + 1, p); |
441 | 447 | ||
442 | add_memory(start, size); | 448 | arm_add_memory(start, size); |
443 | } | 449 | } |
444 | __early_param("mem=", early_mem); | 450 | __early_param("mem=", early_mem); |
445 | 451 | ||
@@ -581,7 +587,7 @@ static int __init parse_tag_mem32(const struct tag *tag) | |||
581 | tag->u.mem.start, tag->u.mem.size / 1024); | 587 | tag->u.mem.start, tag->u.mem.size / 1024); |
582 | return -EINVAL; | 588 | return -EINVAL; |
583 | } | 589 | } |
584 | add_memory(tag->u.mem.start, tag->u.mem.size); | 590 | arm_add_memory(tag->u.mem.start, tag->u.mem.size); |
585 | return 0; | 591 | return 0; |
586 | } | 592 | } |
587 | 593 | ||
@@ -801,7 +807,7 @@ static int __init topology_init(void) | |||
801 | { | 807 | { |
802 | int cpu; | 808 | int cpu; |
803 | 809 | ||
804 | for_each_cpu(cpu) | 810 | for_each_possible_cpu(cpu) |
805 | register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL); | 811 | register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL); |
806 | 812 | ||
807 | return 0; | 813 | return 0; |
diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c index 1781b8f342c4..bfe47bd6e50c 100644 --- a/arch/arm/mach-at91rm9200/devices.c +++ b/arch/arm/mach-at91rm9200/devices.c | |||
@@ -194,13 +194,23 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {} | |||
194 | #if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) | 194 | #if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) |
195 | static struct at91_cf_data cf_data; | 195 | static struct at91_cf_data cf_data; |
196 | 196 | ||
197 | static struct resource at91_cf_resources[] = { | ||
198 | [0] = { | ||
199 | .start = AT91_CF_BASE, | ||
200 | /* ties up CS4, CS5, and CS6 */ | ||
201 | .end = AT91_CF_BASE + (0x30000000 - 1), | ||
202 | .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, | ||
203 | }, | ||
204 | }; | ||
205 | |||
197 | static struct platform_device at91rm9200_cf_device = { | 206 | static struct platform_device at91rm9200_cf_device = { |
198 | .name = "at91_cf", | 207 | .name = "at91_cf", |
199 | .id = -1, | 208 | .id = -1, |
200 | .dev = { | 209 | .dev = { |
201 | .platform_data = &cf_data, | 210 | .platform_data = &cf_data, |
202 | }, | 211 | }, |
203 | .num_resources = 0, | 212 | .resource = at91_cf_resources, |
213 | .num_resources = ARRAY_SIZE(at91_cf_resources), | ||
204 | }; | 214 | }; |
205 | 215 | ||
206 | void __init at91_add_device_cf(struct at91_cf_data *data) | 216 | void __init at91_add_device_cf(struct at91_cf_data *data) |
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index a0888e160e3b..00b761ff0f9c 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c | |||
@@ -91,7 +91,7 @@ static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type); | |||
91 | /* | 91 | /* |
92 | * IRQ -> GPIO mapping table | 92 | * IRQ -> GPIO mapping table |
93 | */ | 93 | */ |
94 | static char irq2gpio[32] = { | 94 | static signed char irq2gpio[32] = { |
95 | -1, -1, -1, -1, -1, -1, 0, 1, | 95 | -1, -1, -1, -1, -1, -1, 0, 1, |
96 | -1, -1, -1, -1, -1, -1, -1, -1, | 96 | -1, -1, -1, -1, -1, -1, -1, -1, |
97 | -1, -1, -1, 2, 3, 4, 5, 6, | 97 | -1, -1, -1, 2, 3, 4, 5, 6, |
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 876c38da14f7..847329cafc5c 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c | |||
@@ -25,10 +25,6 @@ | |||
25 | #include <asm/arch/mux.h> | 25 | #include <asm/arch/mux.h> |
26 | #include <asm/arch/gpio.h> | 26 | #include <asm/arch/gpio.h> |
27 | 27 | ||
28 | extern void omap_nop_release(struct device *dev); | ||
29 | |||
30 | /*-------------------------------------------------------------------------*/ | ||
31 | |||
32 | #if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE) | 28 | #if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE) |
33 | 29 | ||
34 | static u64 irda_dmamask = 0xffffffff; | 30 | static u64 irda_dmamask = 0xffffffff; |
@@ -37,7 +33,6 @@ static struct platform_device omap1610ir_device = { | |||
37 | .name = "omap1610-ir", | 33 | .name = "omap1610-ir", |
38 | .id = -1, | 34 | .id = -1, |
39 | .dev = { | 35 | .dev = { |
40 | .release = omap_nop_release, | ||
41 | .dma_mask = &irda_dmamask, | 36 | .dma_mask = &irda_dmamask, |
42 | }, | 37 | }, |
43 | }; | 38 | }; |
@@ -84,9 +79,6 @@ static struct resource rtc_resources[] = { | |||
84 | static struct platform_device omap_rtc_device = { | 79 | static struct platform_device omap_rtc_device = { |
85 | .name = "omap_rtc", | 80 | .name = "omap_rtc", |
86 | .id = -1, | 81 | .id = -1, |
87 | .dev = { | ||
88 | .release = omap_nop_release, | ||
89 | }, | ||
90 | .num_resources = ARRAY_SIZE(rtc_resources), | 82 | .num_resources = ARRAY_SIZE(rtc_resources), |
91 | .resource = rtc_resources, | 83 | .resource = rtc_resources, |
92 | }; | 84 | }; |
@@ -124,9 +116,6 @@ static struct resource sti_resources[] = { | |||
124 | static struct platform_device sti_device = { | 116 | static struct platform_device sti_device = { |
125 | .name = "sti", | 117 | .name = "sti", |
126 | .id = -1, | 118 | .id = -1, |
127 | .dev = { | ||
128 | .release = omap_nop_release, | ||
129 | }, | ||
130 | .num_resources = ARRAY_SIZE(sti_resources), | 119 | .num_resources = ARRAY_SIZE(sti_resources), |
131 | .resource = sti_resources, | 120 | .resource = sti_resources, |
132 | }; | 121 | }; |
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index def9e5370edf..fb7f91da1aad 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -25,10 +25,6 @@ | |||
25 | #include <asm/arch/mux.h> | 25 | #include <asm/arch/mux.h> |
26 | #include <asm/arch/gpio.h> | 26 | #include <asm/arch/gpio.h> |
27 | 27 | ||
28 | extern void omap_nop_release(struct device *dev); | ||
29 | |||
30 | /*-------------------------------------------------------------------------*/ | ||
31 | |||
32 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) | 28 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) |
33 | 29 | ||
34 | #define OMAP2_I2C_BASE2 0x48072000 | 30 | #define OMAP2_I2C_BASE2 0x48072000 |
@@ -49,9 +45,6 @@ static struct resource i2c_resources2[] = { | |||
49 | static struct platform_device omap_i2c_device2 = { | 45 | static struct platform_device omap_i2c_device2 = { |
50 | .name = "i2c_omap", | 46 | .name = "i2c_omap", |
51 | .id = 2, | 47 | .id = 2, |
52 | .dev = { | ||
53 | .release = omap_nop_release, | ||
54 | }, | ||
55 | .num_resources = ARRAY_SIZE(i2c_resources2), | 48 | .num_resources = ARRAY_SIZE(i2c_resources2), |
56 | .resource = i2c_resources2, | 49 | .resource = i2c_resources2, |
57 | }; | 50 | }; |
@@ -100,9 +93,6 @@ static struct resource sti_resources[] = { | |||
100 | static struct platform_device sti_device = { | 93 | static struct platform_device sti_device = { |
101 | .name = "sti", | 94 | .name = "sti", |
102 | .id = -1, | 95 | .id = -1, |
103 | .dev = { | ||
104 | .release = omap_nop_release, | ||
105 | }, | ||
106 | .num_resources = ARRAY_SIZE(sti_resources), | 96 | .num_resources = ARRAY_SIZE(sti_resources), |
107 | .resource = sti_resources, | 97 | .resource = sti_resources, |
108 | }; | 98 | }; |
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c index b371d723635f..8a25a1c8019f 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c | |||
@@ -196,12 +196,9 @@ static int __init corgi_ssp_probe(struct platform_device *dev) | |||
196 | int ret; | 196 | int ret; |
197 | 197 | ||
198 | /* Chip Select - Disable All */ | 198 | /* Chip Select - Disable All */ |
199 | GPDR(ssp_machinfo->cs_lcdcon) |= GPIO_bit(ssp_machinfo->cs_lcdcon); /* output */ | 199 | pxa_gpio_mode(ssp_machinfo->cs_lcdcon | GPIO_OUT | GPIO_DFLT_HIGH); |
200 | GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ | 200 | pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH); |
201 | GPDR(ssp_machinfo->cs_max1111) |= GPIO_bit(ssp_machinfo->cs_max1111); /* output */ | 201 | pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH); |
202 | GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ | ||
203 | GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */ | ||
204 | GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ | ||
205 | 202 | ||
206 | ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0); | 203 | ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0); |
207 | 204 | ||
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index b7f85e6d6b76..6de713ad319a 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c | |||
@@ -367,6 +367,8 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent) | |||
367 | source = S3C2410_MISCCR_CLK0_UPLL; | 367 | source = S3C2410_MISCCR_CLK0_UPLL; |
368 | else if (parent == &clk_f) | 368 | else if (parent == &clk_f) |
369 | source = S3C2410_MISCCR_CLK0_FCLK; | 369 | source = S3C2410_MISCCR_CLK0_FCLK; |
370 | else if (parent == &clk_h) | ||
371 | source = S3C2410_MISCCR_CLK0_HCLK; | ||
370 | else if (parent == &clk_p) | 372 | else if (parent == &clk_p) |
371 | source = S3C2410_MISCCR_CLK0_PCLK; | 373 | source = S3C2410_MISCCR_CLK0_PCLK; |
372 | else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0) | 374 | else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0) |
@@ -376,6 +378,8 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent) | |||
376 | else | 378 | else |
377 | return -EINVAL; | 379 | return -EINVAL; |
378 | 380 | ||
381 | clk->parent = parent; | ||
382 | |||
379 | if (clk == &s3c24xx_dclk0) | 383 | if (clk == &s3c24xx_dclk0) |
380 | mask = S3C2410_MISCCR_CLK0_MASK; | 384 | mask = S3C2410_MISCCR_CLK0_MASK; |
381 | else { | 385 | else { |
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/mach-s3c2410/common-smdk.c index 36b8291b5e03..c940890f621f 100644 --- a/arch/arm/mach-s3c2410/common-smdk.c +++ b/arch/arm/mach-s3c2410/common-smdk.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #include <asm/arch/nand.h> | 38 | #include <asm/arch/nand.h> |
39 | 39 | ||
40 | #include "common-smdk.h" | ||
40 | #include "devs.h" | 41 | #include "devs.h" |
41 | #include "pm.h" | 42 | #include "pm.h" |
42 | 43 | ||
@@ -49,7 +50,7 @@ static struct mtd_partition smdk_default_nand_part[] = { | |||
49 | .offset = 0, | 50 | .offset = 0, |
50 | }, | 51 | }, |
51 | [1] = { | 52 | [1] = { |
52 | .name = "S3C2410 flash parition 1", | 53 | .name = "S3C2410 flash partition 1", |
53 | .offset = 0, | 54 | .offset = 0, |
54 | .size = SZ_2M, | 55 | .size = SZ_2M, |
55 | }, | 56 | }, |
diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2410/s3c2440-clock.c index 57a15974d4b5..d7a30ed6c327 100644 --- a/arch/arm/mach-s3c2410/s3c2440-clock.c +++ b/arch/arm/mach-s3c2410/s3c2440-clock.c | |||
@@ -139,7 +139,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev) | |||
139 | 139 | ||
140 | clkdivn = __raw_readl(S3C2410_CLKDIVN); | 140 | clkdivn = __raw_readl(S3C2410_CLKDIVN); |
141 | clkdivn |= S3C2440_CLKDIVN_UCLK; | 141 | clkdivn |= S3C2440_CLKDIVN_UCLK; |
142 | __raw_writel(camdivn, S3C2410_CLKDIVN); | 142 | __raw_writel(clkdivn, S3C2410_CLKDIVN); |
143 | 143 | ||
144 | mutex_unlock(&clocks_mutex); | 144 | mutex_unlock(&clocks_mutex); |
145 | } | 145 | } |
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S index 5c4055b62d97..54e3c5bb5186 100644 --- a/arch/arm/mm/cache-v4wb.S +++ b/arch/arm/mm/cache-v4wb.S | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
11 | #include <linux/linkage.h> | 11 | #include <linux/linkage.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <asm/hardware.h> | 13 | #include <asm/memory.h> |
14 | #include <asm/page.h> | 14 | #include <asm/page.h> |
15 | #include "proc-macros.S" | 15 | #include "proc-macros.S" |
16 | 16 | ||
@@ -46,6 +46,11 @@ | |||
46 | */ | 46 | */ |
47 | #define CACHE_DLIMIT (CACHE_DSIZE * 4) | 47 | #define CACHE_DLIMIT (CACHE_DSIZE * 4) |
48 | 48 | ||
49 | .data | ||
50 | flush_base: | ||
51 | .long FLUSH_BASE | ||
52 | .text | ||
53 | |||
49 | /* | 54 | /* |
50 | * flush_user_cache_all() | 55 | * flush_user_cache_all() |
51 | * | 56 | * |
@@ -63,11 +68,21 @@ ENTRY(v4wb_flush_kern_cache_all) | |||
63 | mov ip, #0 | 68 | mov ip, #0 |
64 | mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache | 69 | mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache |
65 | __flush_whole_cache: | 70 | __flush_whole_cache: |
66 | mov r0, #FLUSH_BASE | 71 | ldr r3, =flush_base |
67 | add r1, r0, #CACHE_DSIZE | 72 | ldr r1, [r3, #0] |
68 | 1: ldr r2, [r0], #32 | 73 | eor r1, r1, #CACHE_DSIZE |
69 | cmp r0, r1 | 74 | str r1, [r3, #0] |
75 | add r2, r1, #CACHE_DSIZE | ||
76 | 1: ldr r3, [r1], #32 | ||
77 | cmp r1, r2 | ||
78 | blo 1b | ||
79 | #ifdef FLUSH_BASE_MINICACHE | ||
80 | add r2, r2, #FLUSH_BASE_MINICACHE - FLUSH_BASE | ||
81 | sub r1, r2, #512 @ only 512 bytes | ||
82 | 1: ldr r3, [r1], #32 | ||
83 | cmp r1, r2 | ||
70 | blo 1b | 84 | blo 1b |
85 | #endif | ||
71 | mcr p15, 0, ip, c7, c10, 4 @ drain write buffer | 86 | mcr p15, 0, ip, c7, c10, 4 @ drain write buffer |
72 | mov pc, lr | 87 | mov pc, lr |
73 | 88 | ||
@@ -82,6 +97,7 @@ __flush_whole_cache: | |||
82 | * - flags - vma_area_struct flags describing address space | 97 | * - flags - vma_area_struct flags describing address space |
83 | */ | 98 | */ |
84 | ENTRY(v4wb_flush_user_cache_range) | 99 | ENTRY(v4wb_flush_user_cache_range) |
100 | mov ip, #0 | ||
85 | sub r3, r1, r0 @ calculate total size | 101 | sub r3, r1, r0 @ calculate total size |
86 | tst r2, #VM_EXEC @ executable region? | 102 | tst r2, #VM_EXEC @ executable region? |
87 | mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache | 103 | mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 88279124317a..9ea1f87a7079 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <asm/mach-types.h> | 21 | #include <asm/mach-types.h> |
22 | #include <asm/setup.h> | 22 | #include <asm/setup.h> |
23 | #include <asm/sizes.h> | ||
23 | #include <asm/tlb.h> | 24 | #include <asm/tlb.h> |
24 | 25 | ||
25 | #include <asm/mach/arch.h> | 26 | #include <asm/mach/arch.h> |
@@ -455,14 +456,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc) | |||
455 | #ifdef FLUSH_BASE | 456 | #ifdef FLUSH_BASE |
456 | map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); | 457 | map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); |
457 | map.virtual = FLUSH_BASE; | 458 | map.virtual = FLUSH_BASE; |
458 | map.length = PGDIR_SIZE; | 459 | map.length = SZ_1M; |
459 | map.type = MT_CACHECLEAN; | 460 | map.type = MT_CACHECLEAN; |
460 | create_mapping(&map); | 461 | create_mapping(&map); |
461 | #endif | 462 | #endif |
462 | #ifdef FLUSH_BASE_MINICACHE | 463 | #ifdef FLUSH_BASE_MINICACHE |
463 | map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + PGDIR_SIZE); | 464 | map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M); |
464 | map.virtual = FLUSH_BASE_MINICACHE; | 465 | map.virtual = FLUSH_BASE_MINICACHE; |
465 | map.length = PGDIR_SIZE; | 466 | map.length = SZ_1M; |
466 | map.type = MT_MINICLEAN; | 467 | map.type = MT_MINICLEAN; |
467 | create_mapping(&map); | 468 | create_mapping(&map); |
468 | #endif | 469 | #endif |
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index c916a6cae404..a2dd5ae1077d 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S | |||
@@ -26,22 +26,7 @@ | |||
26 | * the cache line size of the I and D cache | 26 | * the cache line size of the I and D cache |
27 | */ | 27 | */ |
28 | #define DCACHELINESIZE 32 | 28 | #define DCACHELINESIZE 32 |
29 | #define FLUSH_OFFSET 32768 | ||
30 | 29 | ||
31 | .macro flush_110_dcache rd, ra, re | ||
32 | ldr \rd, =flush_base | ||
33 | ldr \ra, [\rd] | ||
34 | eor \ra, \ra, #FLUSH_OFFSET | ||
35 | str \ra, [\rd] | ||
36 | add \re, \ra, #16384 @ only necessary for 16k | ||
37 | 1001: ldr \rd, [\ra], #DCACHELINESIZE | ||
38 | teq \re, \ra | ||
39 | bne 1001b | ||
40 | .endm | ||
41 | |||
42 | .data | ||
43 | flush_base: | ||
44 | .long FLUSH_BASE | ||
45 | .text | 30 | .text |
46 | 31 | ||
47 | /* | 32 | /* |
@@ -145,13 +130,11 @@ ENTRY(cpu_sa110_dcache_clean_area) | |||
145 | */ | 130 | */ |
146 | .align 5 | 131 | .align 5 |
147 | ENTRY(cpu_sa110_switch_mm) | 132 | ENTRY(cpu_sa110_switch_mm) |
148 | flush_110_dcache r3, ip, r1 | 133 | str lr, [sp, #-4]! |
149 | mov r1, #0 | 134 | bl v4wb_flush_kern_cache_all @ clears IP |
150 | mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache | ||
151 | mcr p15, 0, r1, c7, c10, 4 @ drain WB | ||
152 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer | 135 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer |
153 | mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs | 136 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs |
154 | mov pc, lr | 137 | ldr pc, [sp], #4 |
155 | 138 | ||
156 | /* | 139 | /* |
157 | * cpu_sa110_set_pte(ptep, pte) | 140 | * cpu_sa110_set_pte(ptep, pte) |
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 41f21f2dd8ff..777ad99c1439 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S | |||
@@ -30,30 +30,6 @@ | |||
30 | * the cache line size of the I and D cache | 30 | * the cache line size of the I and D cache |
31 | */ | 31 | */ |
32 | #define DCACHELINESIZE 32 | 32 | #define DCACHELINESIZE 32 |
33 | #define FLUSH_OFFSET 32768 | ||
34 | |||
35 | .macro flush_1100_dcache rd, ra, re | ||
36 | ldr \rd, =flush_base | ||
37 | ldr \ra, [\rd] | ||
38 | eor \ra, \ra, #FLUSH_OFFSET | ||
39 | str \ra, [\rd] | ||
40 | add \re, \ra, #8192 @ only necessary for 8k | ||
41 | 1001: ldr \rd, [\ra], #DCACHELINESIZE | ||
42 | teq \re, \ra | ||
43 | bne 1001b | ||
44 | #ifdef FLUSH_BASE_MINICACHE | ||
45 | add \ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE | ||
46 | add \re, \ra, #512 @ only 512 bytes | ||
47 | 1002: ldr \rd, [\ra], #DCACHELINESIZE | ||
48 | teq \re, \ra | ||
49 | bne 1002b | ||
50 | #endif | ||
51 | .endm | ||
52 | |||
53 | .data | ||
54 | flush_base: | ||
55 | .long FLUSH_BASE | ||
56 | .text | ||
57 | 33 | ||
58 | __INIT | 34 | __INIT |
59 | 35 | ||
@@ -79,9 +55,8 @@ ENTRY(cpu_sa1100_proc_fin) | |||
79 | stmfd sp!, {lr} | 55 | stmfd sp!, {lr} |
80 | mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE | 56 | mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE |
81 | msr cpsr_c, ip | 57 | msr cpsr_c, ip |
82 | flush_1100_dcache r0, r1, r2 @ clean caches | 58 | bl v4wb_flush_kern_cache_all |
83 | mov r0, #0 | 59 | mcr p15, 0, ip, c15, c2, 2 @ Disable clock switching |
84 | mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching | ||
85 | mrc p15, 0, r0, c1, c0, 0 @ ctrl register | 60 | mrc p15, 0, r0, c1, c0, 0 @ ctrl register |
86 | bic r0, r0, #0x1000 @ ...i............ | 61 | bic r0, r0, #0x1000 @ ...i............ |
87 | bic r0, r0, #0x000e @ ............wca. | 62 | bic r0, r0, #0x000e @ ............wca. |
@@ -167,14 +142,12 @@ ENTRY(cpu_sa1100_dcache_clean_area) | |||
167 | */ | 142 | */ |
168 | .align 5 | 143 | .align 5 |
169 | ENTRY(cpu_sa1100_switch_mm) | 144 | ENTRY(cpu_sa1100_switch_mm) |
170 | flush_1100_dcache r3, ip, r1 | 145 | str lr, [sp, #-4]! |
171 | mov ip, #0 | 146 | bl v4wb_flush_kern_cache_all @ clears IP |
172 | mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache | ||
173 | mcr p15, 0, ip, c9, c0, 0 @ invalidate RB | 147 | mcr p15, 0, ip, c9, c0, 0 @ invalidate RB |
174 | mcr p15, 0, ip, c7, c10, 4 @ drain WB | ||
175 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer | 148 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer |
176 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs | 149 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs |
177 | mov pc, lr | 150 | ldr pc, [sp], #4 |
178 | 151 | ||
179 | /* | 152 | /* |
180 | * cpu_sa1100_set_pte(ptep, pte) | 153 | * cpu_sa1100_set_pte(ptep, pte) |
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 06485c193ee3..32ec04c58bcd 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c | |||
@@ -58,7 +58,7 @@ struct clk * clk_get(struct device *dev, const char *id) | |||
58 | if (p->id == idno && | 58 | if (p->id == idno && |
59 | strcmp(id, p->name) == 0 && try_module_get(p->owner)) { | 59 | strcmp(id, p->name) == 0 && try_module_get(p->owner)) { |
60 | clk = p; | 60 | clk = p; |
61 | break; | 61 | goto found; |
62 | } | 62 | } |
63 | } | 63 | } |
64 | 64 | ||
@@ -69,6 +69,7 @@ struct clk * clk_get(struct device *dev, const char *id) | |||
69 | } | 69 | } |
70 | } | 70 | } |
71 | 71 | ||
72 | found: | ||
72 | mutex_unlock(&clocks_mutex); | 73 | mutex_unlock(&clocks_mutex); |
73 | 74 | ||
74 | return clk; | 75 | return clk; |
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 079b67deac0f..5d5d6eb222dd 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c | |||
@@ -26,14 +26,6 @@ | |||
26 | #include <asm/arch/gpio.h> | 26 | #include <asm/arch/gpio.h> |
27 | #include <asm/arch/menelaus.h> | 27 | #include <asm/arch/menelaus.h> |
28 | 28 | ||
29 | |||
30 | void omap_nop_release(struct device *dev) | ||
31 | { | ||
32 | /* Nothing */ | ||
33 | } | ||
34 | |||
35 | /*-------------------------------------------------------------------------*/ | ||
36 | |||
37 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) | 29 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) |
38 | 30 | ||
39 | #define OMAP1_I2C_BASE 0xfffb3800 | 31 | #define OMAP1_I2C_BASE 0xfffb3800 |
@@ -59,9 +51,6 @@ static struct resource i2c_resources1[] = { | |||
59 | static struct platform_device omap_i2c_device1 = { | 51 | static struct platform_device omap_i2c_device1 = { |
60 | .name = "i2c_omap", | 52 | .name = "i2c_omap", |
61 | .id = 1, | 53 | .id = 1, |
62 | .dev = { | ||
63 | .release = omap_nop_release, | ||
64 | }, | ||
65 | .num_resources = ARRAY_SIZE(i2c_resources1), | 54 | .num_resources = ARRAY_SIZE(i2c_resources1), |
66 | .resource = i2c_resources1, | 55 | .resource = i2c_resources1, |
67 | }; | 56 | }; |
@@ -187,7 +176,6 @@ static struct platform_device mmc_omap_device1 = { | |||
187 | .name = "mmci-omap", | 176 | .name = "mmci-omap", |
188 | .id = 1, | 177 | .id = 1, |
189 | .dev = { | 178 | .dev = { |
190 | .release = omap_nop_release, | ||
191 | .dma_mask = &mmc1_dmamask, | 179 | .dma_mask = &mmc1_dmamask, |
192 | .platform_data = &mmc1_conf, | 180 | .platform_data = &mmc1_conf, |
193 | }, | 181 | }, |
@@ -217,7 +205,6 @@ static struct platform_device mmc_omap_device2 = { | |||
217 | .name = "mmci-omap", | 205 | .name = "mmci-omap", |
218 | .id = 2, | 206 | .id = 2, |
219 | .dev = { | 207 | .dev = { |
220 | .release = omap_nop_release, | ||
221 | .dma_mask = &mmc2_dmamask, | 208 | .dma_mask = &mmc2_dmamask, |
222 | .platform_data = &mmc2_conf, | 209 | .platform_data = &mmc2_conf, |
223 | }, | 210 | }, |
@@ -321,9 +308,6 @@ static struct resource uwire_resources[] = { | |||
321 | static struct platform_device omap_uwire_device = { | 308 | static struct platform_device omap_uwire_device = { |
322 | .name = "omap_uwire", | 309 | .name = "omap_uwire", |
323 | .id = -1, | 310 | .id = -1, |
324 | .dev = { | ||
325 | .release = omap_nop_release, | ||
326 | }, | ||
327 | .num_resources = ARRAY_SIZE(uwire_resources), | 311 | .num_resources = ARRAY_SIZE(uwire_resources), |
328 | .resource = uwire_resources, | 312 | .resource = uwire_resources, |
329 | }; | 313 | }; |
@@ -365,9 +349,6 @@ static struct resource wdt_resources[] = { | |||
365 | static struct platform_device omap_wdt_device = { | 349 | static struct platform_device omap_wdt_device = { |
366 | .name = "omap_wdt", | 350 | .name = "omap_wdt", |
367 | .id = -1, | 351 | .id = -1, |
368 | .dev = { | ||
369 | .release = omap_nop_release, | ||
370 | }, | ||
371 | .num_resources = ARRAY_SIZE(wdt_resources), | 352 | .num_resources = ARRAY_SIZE(wdt_resources), |
372 | .resource = wdt_resources, | 353 | .resource = wdt_resources, |
373 | }; | 354 | }; |
@@ -401,9 +382,6 @@ static struct resource rng_resources[] = { | |||
401 | static struct platform_device omap_rng_device = { | 382 | static struct platform_device omap_rng_device = { |
402 | .name = "omap_rng", | 383 | .name = "omap_rng", |
403 | .id = -1, | 384 | .id = -1, |
404 | .dev = { | ||
405 | .release = omap_nop_release, | ||
406 | }, | ||
407 | .num_resources = ARRAY_SIZE(rng_resources), | 385 | .num_resources = ARRAY_SIZE(rng_resources), |
408 | .resource = rng_resources, | 386 | .resource = rng_resources, |
409 | }; | 387 | }; |
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 9b367a65cb4d..febd115dba28 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c | |||
@@ -588,6 +588,7 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr) | |||
588 | struct vfp_double vdm; | 588 | struct vfp_double vdm; |
589 | u32 d, exceptions = 0; | 589 | u32 d, exceptions = 0; |
590 | int rmode = fpscr & FPSCR_RMODE_MASK; | 590 | int rmode = fpscr & FPSCR_RMODE_MASK; |
591 | int tm; | ||
591 | 592 | ||
592 | vfp_double_unpack(&vdm, vfp_get_double(dm)); | 593 | vfp_double_unpack(&vdm, vfp_get_double(dm)); |
593 | vfp_double_dump("VDM", &vdm); | 594 | vfp_double_dump("VDM", &vdm); |
@@ -595,10 +596,14 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr) | |||
595 | /* | 596 | /* |
596 | * Do we have denormalised number? | 597 | * Do we have denormalised number? |
597 | */ | 598 | */ |
598 | if (vfp_double_type(&vdm) & VFP_DENORMAL) | 599 | tm = vfp_double_type(&vdm); |
600 | if (tm & VFP_DENORMAL) | ||
599 | exceptions |= FPSCR_IDC; | 601 | exceptions |= FPSCR_IDC; |
600 | 602 | ||
601 | if (vdm.exponent >= 1023 + 32) { | 603 | if (tm & VFP_NAN) { |
604 | d = 0; | ||
605 | exceptions |= FPSCR_IOC; | ||
606 | } else if (vdm.exponent >= 1023 + 32) { | ||
602 | d = 0x7fffffff; | 607 | d = 0x7fffffff; |
603 | if (vdm.sign) | 608 | if (vdm.sign) |
604 | d = ~d; | 609 | d = ~d; |
@@ -1122,9 +1127,9 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) | |||
1122 | { | 1127 | { |
1123 | u32 op = inst & FOP_MASK; | 1128 | u32 op = inst & FOP_MASK; |
1124 | u32 exceptions = 0; | 1129 | u32 exceptions = 0; |
1125 | unsigned int dd = vfp_get_sd(inst); | 1130 | unsigned int dd = vfp_get_dd(inst); |
1126 | unsigned int dn = vfp_get_sn(inst); | 1131 | unsigned int dn = vfp_get_dn(inst); |
1127 | unsigned int dm = vfp_get_sm(inst); | 1132 | unsigned int dm = vfp_get_dm(inst); |
1128 | unsigned int vecitr, veclen, vecstride; | 1133 | unsigned int vecitr, veclen, vecstride; |
1129 | u32 (*fop)(int, int, s32, u32); | 1134 | u32 (*fop)(int, int, s32, u32); |
1130 | 1135 | ||
@@ -1141,7 +1146,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) | |||
1141 | pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, | 1146 | pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, |
1142 | (veclen >> FPSCR_LENGTH_BIT) + 1); | 1147 | (veclen >> FPSCR_LENGTH_BIT) + 1); |
1143 | 1148 | ||
1144 | fop = (op == FOP_EXT) ? fop_extfns[dn] : fop_fns[FOP_TO_IDX(op)]; | 1149 | fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; |
1145 | if (!fop) | 1150 | if (!fop) |
1146 | goto invalid; | 1151 | goto invalid; |
1147 | 1152 | ||
@@ -1149,17 +1154,13 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) | |||
1149 | u32 except; | 1154 | u32 except; |
1150 | 1155 | ||
1151 | if (op == FOP_EXT) | 1156 | if (op == FOP_EXT) |
1152 | pr_debug("VFP: itr%d (d%u.%u) = op[%u] (d%u.%u)\n", | 1157 | pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n", |
1153 | vecitr >> FPSCR_LENGTH_BIT, | 1158 | vecitr >> FPSCR_LENGTH_BIT, |
1154 | dd >> 1, dd & 1, dn, | 1159 | dd, dn, dm); |
1155 | dm >> 1, dm & 1); | ||
1156 | else | 1160 | else |
1157 | pr_debug("VFP: itr%d (d%u.%u) = (d%u.%u) op[%u] (d%u.%u)\n", | 1161 | pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n", |
1158 | vecitr >> FPSCR_LENGTH_BIT, | 1162 | vecitr >> FPSCR_LENGTH_BIT, |
1159 | dd >> 1, dd & 1, | 1163 | dd, dn, FOP_TO_IDX(op), dm); |
1160 | dn >> 1, dn & 1, | ||
1161 | FOP_TO_IDX(op), | ||
1162 | dm >> 1, dm & 1); | ||
1163 | 1164 | ||
1164 | except = fop(dd, dn, dm, fpscr); | 1165 | except = fop(dd, dn, dm, fpscr); |
1165 | pr_debug("VFP: itr%d: exceptions=%08x\n", | 1166 | pr_debug("VFP: itr%d: exceptions=%08x\n", |
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index b7ed57e00cd4..a3f65b47aea9 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S | |||
@@ -189,11 +189,10 @@ vfp_put_float: | |||
189 | 189 | ||
190 | .globl vfp_get_double | 190 | .globl vfp_get_double |
191 | vfp_get_double: | 191 | vfp_get_double: |
192 | mov r0, r0, lsr #1 | ||
193 | add pc, pc, r0, lsl #3 | 192 | add pc, pc, r0, lsl #3 |
194 | mov r0, r0 | 193 | mov r0, r0 |
195 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | 194 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
196 | mrrc p10, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr | 195 | mrrc p11, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr |
197 | mov pc, lr | 196 | mov pc, lr |
198 | .endr | 197 | .endr |
199 | 198 | ||
@@ -204,10 +203,9 @@ vfp_get_double: | |||
204 | 203 | ||
205 | .globl vfp_put_double | 204 | .globl vfp_put_double |
206 | vfp_put_double: | 205 | vfp_put_double: |
207 | mov r0, r0, lsr #1 | ||
208 | add pc, pc, r0, lsl #3 | 206 | add pc, pc, r0, lsl #3 |
209 | mov r0, r0 | 207 | mov r0, r0 |
210 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | 208 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
211 | mcrr p10, 1, r1, r2, c\dr @ fmrrd r1, r2, d\dr | 209 | mcrr p11, 1, r1, r2, c\dr @ fmdrr r1, r2, d\dr |
212 | mov pc, lr | 210 | mov pc, lr |
213 | .endr | 211 | .endr |
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 14dd696ddeb1..4ac27f193934 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c | |||
@@ -632,6 +632,7 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) | |||
632 | struct vfp_single vsm; | 632 | struct vfp_single vsm; |
633 | u32 d, exceptions = 0; | 633 | u32 d, exceptions = 0; |
634 | int rmode = fpscr & FPSCR_RMODE_MASK; | 634 | int rmode = fpscr & FPSCR_RMODE_MASK; |
635 | int tm; | ||
635 | 636 | ||
636 | vfp_single_unpack(&vsm, m); | 637 | vfp_single_unpack(&vsm, m); |
637 | vfp_single_dump("VSM", &vsm); | 638 | vfp_single_dump("VSM", &vsm); |
@@ -639,10 +640,14 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) | |||
639 | /* | 640 | /* |
640 | * Do we have a denormalised number? | 641 | * Do we have a denormalised number? |
641 | */ | 642 | */ |
643 | tm = vfp_single_type(&vsm); | ||
642 | if (vfp_single_type(&vsm) & VFP_DENORMAL) | 644 | if (vfp_single_type(&vsm) & VFP_DENORMAL) |
643 | exceptions |= FPSCR_IDC; | 645 | exceptions |= FPSCR_IDC; |
644 | 646 | ||
645 | if (vsm.exponent >= 127 + 32) { | 647 | if (tm & VFP_NAN) { |
648 | d = 0; | ||
649 | exceptions |= FPSCR_IOC; | ||
650 | } else if (vsm.exponent >= 127 + 32) { | ||
646 | /* | 651 | /* |
647 | * m >= 2^31-2^7: invalid | 652 | * m >= 2^31-2^7: invalid |
648 | */ | 653 | */ |
@@ -1188,7 +1193,7 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) | |||
1188 | pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, | 1193 | pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, |
1189 | (veclen >> FPSCR_LENGTH_BIT) + 1); | 1194 | (veclen >> FPSCR_LENGTH_BIT) + 1); |
1190 | 1195 | ||
1191 | fop = (op == FOP_EXT) ? fop_extfns[sn] : fop_fns[FOP_TO_IDX(op)]; | 1196 | fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; |
1192 | if (!fop) | 1197 | if (!fop) |
1193 | goto invalid; | 1198 | goto invalid; |
1194 | 1199 | ||
diff --git a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c index a6a1b3373444..9d66c27f2724 100644 --- a/arch/arm26/kernel/armksyms.c +++ b/arch/arm26/kernel/armksyms.c | |||
@@ -152,7 +152,6 @@ EXPORT_SYMBOL(strncmp); | |||
152 | EXPORT_SYMBOL(strchr); | 152 | EXPORT_SYMBOL(strchr); |
153 | EXPORT_SYMBOL(strlen); | 153 | EXPORT_SYMBOL(strlen); |
154 | EXPORT_SYMBOL(strnlen); | 154 | EXPORT_SYMBOL(strnlen); |
155 | EXPORT_SYMBOL(strpbrk); | ||
156 | EXPORT_SYMBOL(strrchr); | 155 | EXPORT_SYMBOL(strrchr); |
157 | EXPORT_SYMBOL(strstr); | 156 | EXPORT_SYMBOL(strstr); |
158 | EXPORT_SYMBOL(memset); | 157 | EXPORT_SYMBOL(memset); |
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c index de39725da920..d57859053ce7 100644 --- a/arch/cris/kernel/crisksyms.c +++ b/arch/cris/kernel/crisksyms.c | |||
@@ -39,7 +39,6 @@ EXPORT_SYMBOL(loops_per_usec); | |||
39 | /* String functions */ | 39 | /* String functions */ |
40 | EXPORT_SYMBOL(memcmp); | 40 | EXPORT_SYMBOL(memcmp); |
41 | EXPORT_SYMBOL(memmove); | 41 | EXPORT_SYMBOL(memmove); |
42 | EXPORT_SYMBOL(strpbrk); | ||
43 | EXPORT_SYMBOL(strstr); | 42 | EXPORT_SYMBOL(strstr); |
44 | EXPORT_SYMBOL(strcpy); | 43 | EXPORT_SYMBOL(strcpy); |
45 | EXPORT_SYMBOL(strchr); | 44 | EXPORT_SYMBOL(strchr); |
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 1d21c8d34d8a..a9b59527a741 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S | |||
@@ -1170,12 +1170,6 @@ __syscall_badsys: | |||
1170 | # syscall vector table | 1170 | # syscall vector table |
1171 | # | 1171 | # |
1172 | ############################################################################### | 1172 | ############################################################################### |
1173 | #ifdef CONFIG_MMU | ||
1174 | #define __MMU(X) X | ||
1175 | #else | ||
1176 | #define __MMU(X) sys_ni_syscall | ||
1177 | #endif | ||
1178 | |||
1179 | .section .rodata | 1173 | .section .rodata |
1180 | ALIGN | 1174 | ALIGN |
1181 | .globl sys_call_table | 1175 | .globl sys_call_table |
@@ -1305,7 +1299,7 @@ sys_call_table: | |||
1305 | .long sys_newuname | 1299 | .long sys_newuname |
1306 | .long sys_ni_syscall /* old "cacheflush" */ | 1300 | .long sys_ni_syscall /* old "cacheflush" */ |
1307 | .long sys_adjtimex | 1301 | .long sys_adjtimex |
1308 | .long __MMU(sys_mprotect) /* 125 */ | 1302 | .long sys_mprotect /* 125 */ |
1309 | .long sys_sigprocmask | 1303 | .long sys_sigprocmask |
1310 | .long sys_ni_syscall /* old "create_module" */ | 1304 | .long sys_ni_syscall /* old "create_module" */ |
1311 | .long sys_init_module | 1305 | .long sys_init_module |
@@ -1324,16 +1318,16 @@ sys_call_table: | |||
1324 | .long sys_getdents | 1318 | .long sys_getdents |
1325 | .long sys_select | 1319 | .long sys_select |
1326 | .long sys_flock | 1320 | .long sys_flock |
1327 | .long __MMU(sys_msync) | 1321 | .long sys_msync |
1328 | .long sys_readv /* 145 */ | 1322 | .long sys_readv /* 145 */ |
1329 | .long sys_writev | 1323 | .long sys_writev |
1330 | .long sys_getsid | 1324 | .long sys_getsid |
1331 | .long sys_fdatasync | 1325 | .long sys_fdatasync |
1332 | .long sys_sysctl | 1326 | .long sys_sysctl |
1333 | .long __MMU(sys_mlock) /* 150 */ | 1327 | .long sys_mlock /* 150 */ |
1334 | .long __MMU(sys_munlock) | 1328 | .long sys_munlock |
1335 | .long __MMU(sys_mlockall) | 1329 | .long sys_mlockall |
1336 | .long __MMU(sys_munlockall) | 1330 | .long sys_munlockall |
1337 | .long sys_sched_setparam | 1331 | .long sys_sched_setparam |
1338 | .long sys_sched_getparam /* 155 */ | 1332 | .long sys_sched_getparam /* 155 */ |
1339 | .long sys_sched_setscheduler | 1333 | .long sys_sched_setscheduler |
@@ -1343,7 +1337,7 @@ sys_call_table: | |||
1343 | .long sys_sched_get_priority_min /* 160 */ | 1337 | .long sys_sched_get_priority_min /* 160 */ |
1344 | .long sys_sched_rr_get_interval | 1338 | .long sys_sched_rr_get_interval |
1345 | .long sys_nanosleep | 1339 | .long sys_nanosleep |
1346 | .long __MMU(sys_mremap) | 1340 | .long sys_mremap |
1347 | .long sys_setresuid16 | 1341 | .long sys_setresuid16 |
1348 | .long sys_getresuid16 /* 165 */ | 1342 | .long sys_getresuid16 /* 165 */ |
1349 | .long sys_ni_syscall /* for vm86 */ | 1343 | .long sys_ni_syscall /* for vm86 */ |
@@ -1398,8 +1392,8 @@ sys_call_table: | |||
1398 | .long sys_setfsuid /* 215 */ | 1392 | .long sys_setfsuid /* 215 */ |
1399 | .long sys_setfsgid | 1393 | .long sys_setfsgid |
1400 | .long sys_pivot_root | 1394 | .long sys_pivot_root |
1401 | .long __MMU(sys_mincore) | 1395 | .long sys_mincore |
1402 | .long __MMU(sys_madvise) | 1396 | .long sys_madvise |
1403 | .long sys_getdents64 /* 220 */ | 1397 | .long sys_getdents64 /* 220 */ |
1404 | .long sys_fcntl64 | 1398 | .long sys_fcntl64 |
1405 | .long sys_ni_syscall /* reserved for TUX */ | 1399 | .long sys_ni_syscall /* reserved for TUX */ |
@@ -1437,7 +1431,7 @@ sys_call_table: | |||
1437 | .long sys_epoll_create | 1431 | .long sys_epoll_create |
1438 | .long sys_epoll_ctl /* 255 */ | 1432 | .long sys_epoll_ctl /* 255 */ |
1439 | .long sys_epoll_wait | 1433 | .long sys_epoll_wait |
1440 | .long __MMU(sys_remap_file_pages) | 1434 | .long sys_remap_file_pages |
1441 | .long sys_set_tid_address | 1435 | .long sys_set_tid_address |
1442 | .long sys_timer_create | 1436 | .long sys_timer_create |
1443 | .long sys_timer_settime /* 260 */ | 1437 | .long sys_timer_settime /* 260 */ |
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c index 07c8ffa0dd39..0f273a7aca5a 100644 --- a/arch/frv/kernel/frv_ksyms.c +++ b/arch/frv/kernel/frv_ksyms.c | |||
@@ -27,7 +27,6 @@ EXPORT_SYMBOL(__ioremap); | |||
27 | EXPORT_SYMBOL(iounmap); | 27 | EXPORT_SYMBOL(iounmap); |
28 | 28 | ||
29 | EXPORT_SYMBOL(strnlen); | 29 | EXPORT_SYMBOL(strnlen); |
30 | EXPORT_SYMBOL(strpbrk); | ||
31 | EXPORT_SYMBOL(strrchr); | 30 | EXPORT_SYMBOL(strrchr); |
32 | EXPORT_SYMBOL(strstr); | 31 | EXPORT_SYMBOL(strstr); |
33 | EXPORT_SYMBOL(strchr); | 32 | EXPORT_SYMBOL(strchr); |
diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c index b6cd78c972bb..f8d6dee84781 100644 --- a/arch/h8300/kernel/h8300_ksyms.c +++ b/arch/h8300/kernel/h8300_ksyms.c | |||
@@ -25,7 +25,6 @@ extern char h8300_debug_device[]; | |||
25 | /* platform dependent support */ | 25 | /* platform dependent support */ |
26 | 26 | ||
27 | EXPORT_SYMBOL(strnlen); | 27 | EXPORT_SYMBOL(strnlen); |
28 | EXPORT_SYMBOL(strpbrk); | ||
29 | EXPORT_SYMBOL(strrchr); | 28 | EXPORT_SYMBOL(strrchr); |
30 | EXPORT_SYMBOL(strstr); | 29 | EXPORT_SYMBOL(strstr); |
31 | EXPORT_SYMBOL(strchr); | 30 | EXPORT_SYMBOL(strchr); |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index f17bd1d2707e..18ec9fe6deb6 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -53,6 +53,35 @@ source "init/Kconfig" | |||
53 | 53 | ||
54 | menu "Processor type and features" | 54 | menu "Processor type and features" |
55 | 55 | ||
56 | config SMP | ||
57 | bool "Symmetric multi-processing support" | ||
58 | ---help--- | ||
59 | This enables support for systems with more than one CPU. If you have | ||
60 | a system with only one CPU, like most personal computers, say N. If | ||
61 | you have a system with more than one CPU, say Y. | ||
62 | |||
63 | If you say N here, the kernel will run on single and multiprocessor | ||
64 | machines, but will use only one CPU of a multiprocessor machine. If | ||
65 | you say Y here, the kernel will run on many, but not all, | ||
66 | singleprocessor machines. On a singleprocessor machine, the kernel | ||
67 | will run faster if you say N here. | ||
68 | |||
69 | Note that if you say Y here and choose architecture "586" or | ||
70 | "Pentium" under "Processor family", the kernel will not work on 486 | ||
71 | architectures. Similarly, multiprocessor kernels for the "PPro" | ||
72 | architecture may not work on all Pentium based boards. | ||
73 | |||
74 | People using multiprocessor machines who say Y here should also say | ||
75 | Y to "Enhanced Real Time Clock Support", below. The "Advanced Power | ||
76 | Management" code will be disabled if you say Y here. | ||
77 | |||
78 | See also the <file:Documentation/smp.txt>, | ||
79 | <file:Documentation/i386/IO-APIC.txt>, | ||
80 | <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at | ||
81 | <http://www.tldp.org/docs.html#howto>. | ||
82 | |||
83 | If you don't know what to do here, say N. | ||
84 | |||
56 | choice | 85 | choice |
57 | prompt "Subarchitecture Type" | 86 | prompt "Subarchitecture Type" |
58 | default X86_PC | 87 | default X86_PC |
@@ -178,35 +207,6 @@ config HPET_EMULATE_RTC | |||
178 | depends on HPET_TIMER && RTC=y | 207 | depends on HPET_TIMER && RTC=y |
179 | default y | 208 | default y |
180 | 209 | ||
181 | config SMP | ||
182 | bool "Symmetric multi-processing support" | ||
183 | ---help--- | ||
184 | This enables support for systems with more than one CPU. If you have | ||
185 | a system with only one CPU, like most personal computers, say N. If | ||
186 | you have a system with more than one CPU, say Y. | ||
187 | |||
188 | If you say N here, the kernel will run on single and multiprocessor | ||
189 | machines, but will use only one CPU of a multiprocessor machine. If | ||
190 | you say Y here, the kernel will run on many, but not all, | ||
191 | singleprocessor machines. On a singleprocessor machine, the kernel | ||
192 | will run faster if you say N here. | ||
193 | |||
194 | Note that if you say Y here and choose architecture "586" or | ||
195 | "Pentium" under "Processor family", the kernel will not work on 486 | ||
196 | architectures. Similarly, multiprocessor kernels for the "PPro" | ||
197 | architecture may not work on all Pentium based boards. | ||
198 | |||
199 | People using multiprocessor machines who say Y here should also say | ||
200 | Y to "Enhanced Real Time Clock Support", below. The "Advanced Power | ||
201 | Management" code will be disabled if you say Y here. | ||
202 | |||
203 | See also the <file:Documentation/smp.txt>, | ||
204 | <file:Documentation/i386/IO-APIC.txt>, | ||
205 | <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at | ||
206 | <http://www.tldp.org/docs.html#howto>. | ||
207 | |||
208 | If you don't know what to do here, say N. | ||
209 | |||
210 | config NR_CPUS | 210 | config NR_CPUS |
211 | int "Maximum number of CPUs (2-255)" | 211 | int "Maximum number of CPUs (2-255)" |
212 | range 2 255 | 212 | range 2 255 |
@@ -522,6 +522,12 @@ config NUMA | |||
522 | comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" | 522 | comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" |
523 | depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) | 523 | depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) |
524 | 524 | ||
525 | config NODES_SHIFT | ||
526 | int | ||
527 | default "4" if X86_NUMAQ | ||
528 | default "3" | ||
529 | depends on NEED_MULTIPLE_NODES | ||
530 | |||
525 | config HAVE_ARCH_BOOTMEM_NODE | 531 | config HAVE_ARCH_BOOTMEM_NODE |
526 | bool | 532 | bool |
527 | depends on NUMA | 533 | depends on NUMA |
@@ -757,15 +763,6 @@ config HOTPLUG_CPU | |||
757 | 763 | ||
758 | Say N. | 764 | Say N. |
759 | 765 | ||
760 | config DOUBLEFAULT | ||
761 | default y | ||
762 | bool "Enable doublefault exception handler" if EMBEDDED | ||
763 | help | ||
764 | This option allows trapping of rare doublefault exceptions that | ||
765 | would otherwise cause a system to silently reboot. Disabling this | ||
766 | option saves about 4k and might cause you much additional grey | ||
767 | hair. | ||
768 | |||
769 | endmenu | 766 | endmenu |
770 | 767 | ||
771 | 768 | ||
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index 79603b3471f9..eb130482ba18 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu | |||
@@ -311,5 +311,5 @@ config X86_OOSTORE | |||
311 | 311 | ||
312 | config X86_TSC | 312 | config X86_TSC |
313 | bool | 313 | bool |
314 | depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ | 314 | depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ |
315 | default y | 315 | default y |
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug index 6e97df6979e8..c92191b1fb67 100644 --- a/arch/i386/Kconfig.debug +++ b/arch/i386/Kconfig.debug | |||
@@ -81,4 +81,13 @@ config X86_MPPARSE | |||
81 | depends on X86_LOCAL_APIC && !X86_VISWS | 81 | depends on X86_LOCAL_APIC && !X86_VISWS |
82 | default y | 82 | default y |
83 | 83 | ||
84 | config DOUBLEFAULT | ||
85 | default y | ||
86 | bool "Enable doublefault exception handler" if EMBEDDED | ||
87 | help | ||
88 | This option allows trapping of rare doublefault exceptions that | ||
89 | would otherwise cause a system to silently reboot. Disabling this | ||
90 | option saves about 4k and might cause you much additional grey | ||
91 | hair. | ||
92 | |||
84 | endmenu | 93 | endmenu |
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S index 0000a2674537..c9343c3a8082 100644 --- a/arch/i386/boot/video.S +++ b/arch/i386/boot/video.S | |||
@@ -97,6 +97,7 @@ | |||
97 | #define PARAM_VESAPM_OFF 0x30 | 97 | #define PARAM_VESAPM_OFF 0x30 |
98 | #define PARAM_LFB_PAGES 0x32 | 98 | #define PARAM_LFB_PAGES 0x32 |
99 | #define PARAM_VESA_ATTRIB 0x34 | 99 | #define PARAM_VESA_ATTRIB 0x34 |
100 | #define PARAM_CAPABILITIES 0x36 | ||
100 | 101 | ||
101 | /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ | 102 | /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ |
102 | #ifdef CONFIG_VIDEO_RETAIN | 103 | #ifdef CONFIG_VIDEO_RETAIN |
@@ -233,6 +234,10 @@ mopar_gr: | |||
233 | movw 18(%di), %ax | 234 | movw 18(%di), %ax |
234 | movl %eax, %fs:(PARAM_LFB_SIZE) | 235 | movl %eax, %fs:(PARAM_LFB_SIZE) |
235 | 236 | ||
237 | # store mode capabilities | ||
238 | movl 10(%di), %eax | ||
239 | movl %eax, %fs:(PARAM_CAPABILITIES) | ||
240 | |||
236 | # switching the DAC to 8-bit is for <= 8 bpp only | 241 | # switching the DAC to 8-bit is for <= 8 bpp only |
237 | movw %fs:(PARAM_LFB_DEPTH), %ax | 242 | movw %fs:(PARAM_LFB_DEPTH), %ax |
238 | cmpw $8, %ax | 243 | cmpw $8, %ax |
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 5b9ed21216cf..96fb8a020af2 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile | |||
@@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds | |||
6 | 6 | ||
7 | obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ | 7 | obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ |
8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ | 8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ |
9 | pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ | 9 | pci-dma.o i386_ksyms.o i387.o bootflag.o \ |
10 | quirks.o i8237.o topology.o alternative.o | 10 | quirks.o i8237.o topology.o alternative.o |
11 | 11 | ||
12 | obj-y += cpu/ | 12 | obj-y += cpu/ |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 033066176b3e..049a25583793 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -215,7 +215,7 @@ static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) | |||
215 | { | 215 | { |
216 | struct acpi_table_madt *madt = NULL; | 216 | struct acpi_table_madt *madt = NULL; |
217 | 217 | ||
218 | if (!phys_addr || !size) | 218 | if (!phys_addr || !size || !cpu_has_apic) |
219 | return -EINVAL; | 219 | return -EINVAL; |
220 | 220 | ||
221 | madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); | 221 | madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); |
@@ -693,6 +693,9 @@ static int __init acpi_parse_madt_lapic_entries(void) | |||
693 | { | 693 | { |
694 | int count; | 694 | int count; |
695 | 695 | ||
696 | if (!cpu_has_apic) | ||
697 | return -ENODEV; | ||
698 | |||
696 | /* | 699 | /* |
697 | * Note that the LAPIC address is obtained from the MADT (32-bit value) | 700 | * Note that the LAPIC address is obtained from the MADT (32-bit value) |
698 | * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). | 701 | * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). |
@@ -751,6 +754,9 @@ static int __init acpi_parse_madt_ioapic_entries(void) | |||
751 | return -ENODEV; | 754 | return -ENODEV; |
752 | } | 755 | } |
753 | 756 | ||
757 | if (!cpu_has_apic) | ||
758 | return -ENODEV; | ||
759 | |||
754 | /* | 760 | /* |
755 | * if "noapic" boot option, don't look for IO-APICs | 761 | * if "noapic" boot option, don't look for IO-APICs |
756 | */ | 762 | */ |
@@ -1096,6 +1102,9 @@ int __init acpi_boot_table_init(void) | |||
1096 | dmi_check_system(acpi_dmi_table); | 1102 | dmi_check_system(acpi_dmi_table); |
1097 | #endif | 1103 | #endif |
1098 | 1104 | ||
1105 | if (!cpu_has_apic) | ||
1106 | return -ENODEV; | ||
1107 | |||
1099 | /* | 1108 | /* |
1100 | * If acpi_disabled, bail out | 1109 | * If acpi_disabled, bail out |
1101 | * One exception: acpi=ht continues far enough to enumerate LAPICs | 1110 | * One exception: acpi=ht continues far enough to enumerate LAPICs |
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 6273bf74c203..254cee9f0b7b 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -62,6 +62,18 @@ int apic_verbosity; | |||
62 | 62 | ||
63 | static void apic_pm_activate(void); | 63 | static void apic_pm_activate(void); |
64 | 64 | ||
65 | int modern_apic(void) | ||
66 | { | ||
67 | unsigned int lvr, version; | ||
68 | /* AMD systems use old APIC versions, so check the CPU */ | ||
69 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && | ||
70 | boot_cpu_data.x86 >= 0xf) | ||
71 | return 1; | ||
72 | lvr = apic_read(APIC_LVR); | ||
73 | version = GET_APIC_VERSION(lvr); | ||
74 | return version >= 0x14; | ||
75 | } | ||
76 | |||
65 | /* | 77 | /* |
66 | * 'what should we do if we get a hw irq event on an illegal vector'. | 78 | * 'what should we do if we get a hw irq event on an illegal vector'. |
67 | * each architecture has to answer this themselves. | 79 | * each architecture has to answer this themselves. |
@@ -119,10 +131,7 @@ void enable_NMI_through_LVT0 (void * dummy) | |||
119 | 131 | ||
120 | int get_physical_broadcast(void) | 132 | int get_physical_broadcast(void) |
121 | { | 133 | { |
122 | unsigned int lvr, version; | 134 | if (modern_apic()) |
123 | lvr = apic_read(APIC_LVR); | ||
124 | version = GET_APIC_VERSION(lvr); | ||
125 | if (!APIC_INTEGRATED(version) || version >= 0x14) | ||
126 | return 0xff; | 135 | return 0xff; |
127 | else | 136 | else |
128 | return 0xf; | 137 | return 0xf; |
@@ -349,9 +358,9 @@ int __init verify_local_APIC(void) | |||
349 | 358 | ||
350 | void __init sync_Arb_IDs(void) | 359 | void __init sync_Arb_IDs(void) |
351 | { | 360 | { |
352 | /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */ | 361 | /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 |
353 | unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); | 362 | And not needed on AMD */ |
354 | if (ver >= 0x14) /* P4 or higher */ | 363 | if (modern_apic()) |
355 | return; | 364 | return; |
356 | /* | 365 | /* |
357 | * Wait for idle. | 366 | * Wait for idle. |
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index da30a374dd4e..df0e1745f189 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c | |||
@@ -1079,7 +1079,7 @@ static int apm_console_blank(int blank) | |||
1079 | break; | 1079 | break; |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) { | 1082 | if (error == APM_NOT_ENGAGED) { |
1083 | static int tried; | 1083 | static int tried; |
1084 | int eng_error; | 1084 | int eng_error; |
1085 | if (tried++ == 0) { | 1085 | if (tried++ == 0) { |
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 0810f81f2a05..786d1a57048b 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
@@ -207,13 +207,13 @@ static void __init init_amd(struct cpuinfo_x86 *c) | |||
207 | set_bit(X86_FEATURE_K7, c->x86_capability); | 207 | set_bit(X86_FEATURE_K7, c->x86_capability); |
208 | break; | 208 | break; |
209 | } | 209 | } |
210 | if (c->x86 >= 6) | ||
211 | set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability); | ||
210 | 212 | ||
211 | display_cacheinfo(c); | 213 | display_cacheinfo(c); |
212 | 214 | ||
213 | if (cpuid_eax(0x80000000) >= 0x80000008) { | 215 | if (cpuid_eax(0x80000000) >= 0x80000008) { |
214 | c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; | 216 | c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; |
215 | if (c->x86_max_cores & (c->x86_max_cores - 1)) | ||
216 | c->x86_max_cores = 1; | ||
217 | } | 217 | } |
218 | 218 | ||
219 | if (cpuid_eax(0x80000000) >= 0x80000007) { | 219 | if (cpuid_eax(0x80000000) >= 0x80000007) { |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 712a26bd4457..71fffa174425 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | #define PFX "powernow-k8: " | 47 | #define PFX "powernow-k8: " |
48 | #define BFX PFX "BIOS error: " | 48 | #define BFX PFX "BIOS error: " |
49 | #define VERSION "version 1.60.1" | 49 | #define VERSION "version 1.60.2" |
50 | #include "powernow-k8.h" | 50 | #include "powernow-k8.h" |
51 | 51 | ||
52 | /* serialize freq changes */ | 52 | /* serialize freq changes */ |
@@ -55,7 +55,7 @@ static DEFINE_MUTEX(fidvid_mutex); | |||
55 | static struct powernow_k8_data *powernow_data[NR_CPUS]; | 55 | static struct powernow_k8_data *powernow_data[NR_CPUS]; |
56 | 56 | ||
57 | #ifndef CONFIG_SMP | 57 | #ifndef CONFIG_SMP |
58 | static cpumask_t cpu_core_map[1] = { CPU_MASK_ALL }; | 58 | static cpumask_t cpu_core_map[1]; |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | /* Return a frequency in MHz, given an input fid */ | 61 | /* Return a frequency in MHz, given an input fid */ |
@@ -905,11 +905,17 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
905 | { | 905 | { |
906 | cpumask_t oldmask = CPU_MASK_ALL; | 906 | cpumask_t oldmask = CPU_MASK_ALL; |
907 | struct powernow_k8_data *data = powernow_data[pol->cpu]; | 907 | struct powernow_k8_data *data = powernow_data[pol->cpu]; |
908 | u32 checkfid = data->currfid; | 908 | u32 checkfid; |
909 | u32 checkvid = data->currvid; | 909 | u32 checkvid; |
910 | unsigned int newstate; | 910 | unsigned int newstate; |
911 | int ret = -EIO; | 911 | int ret = -EIO; |
912 | 912 | ||
913 | if (!data) | ||
914 | return -EINVAL; | ||
915 | |||
916 | checkfid = data->currfid; | ||
917 | checkvid = data->currvid; | ||
918 | |||
913 | /* only run on specific CPU from here on */ | 919 | /* only run on specific CPU from here on */ |
914 | oldmask = current->cpus_allowed; | 920 | oldmask = current->cpus_allowed; |
915 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); | 921 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); |
@@ -969,6 +975,9 @@ static int powernowk8_verify(struct cpufreq_policy *pol) | |||
969 | { | 975 | { |
970 | struct powernow_k8_data *data = powernow_data[pol->cpu]; | 976 | struct powernow_k8_data *data = powernow_data[pol->cpu]; |
971 | 977 | ||
978 | if (!data) | ||
979 | return -EINVAL; | ||
980 | |||
972 | return cpufreq_frequency_table_verify(pol, data->powernow_table); | 981 | return cpufreq_frequency_table_verify(pol, data->powernow_table); |
973 | } | 982 | } |
974 | 983 | ||
@@ -977,7 +986,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
977 | { | 986 | { |
978 | struct powernow_k8_data *data; | 987 | struct powernow_k8_data *data; |
979 | cpumask_t oldmask = CPU_MASK_ALL; | 988 | cpumask_t oldmask = CPU_MASK_ALL; |
980 | int rc, i; | 989 | int rc; |
981 | 990 | ||
982 | if (!cpu_online(pol->cpu)) | 991 | if (!cpu_online(pol->cpu)) |
983 | return -ENODEV; | 992 | return -ENODEV; |
@@ -1063,8 +1072,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1063 | printk("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1072 | printk("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1064 | data->currfid, data->currvid); | 1073 | data->currfid, data->currvid); |
1065 | 1074 | ||
1066 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) | 1075 | powernow_data[pol->cpu] = data; |
1067 | powernow_data[i] = data; | ||
1068 | 1076 | ||
1069 | return 0; | 1077 | return 0; |
1070 | 1078 | ||
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index 006141d1c12a..1d9a4abcdfc7 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c | |||
@@ -168,7 +168,7 @@ static int cpuid_class_device_create(int i) | |||
168 | return err; | 168 | return err; |
169 | } | 169 | } |
170 | 170 | ||
171 | static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 171 | static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
172 | { | 172 | { |
173 | unsigned int cpu = (unsigned long)hcpu; | 173 | unsigned int cpu = (unsigned long)hcpu; |
174 | 174 | ||
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c deleted file mode 100644 index 5efceebc48dc..000000000000 --- a/arch/i386/kernel/dmi_scan.c +++ /dev/null | |||
@@ -1,358 +0,0 @@ | |||
1 | #include <linux/types.h> | ||
2 | #include <linux/string.h> | ||
3 | #include <linux/init.h> | ||
4 | #include <linux/module.h> | ||
5 | #include <linux/dmi.h> | ||
6 | #include <linux/efi.h> | ||
7 | #include <linux/bootmem.h> | ||
8 | #include <linux/slab.h> | ||
9 | #include <asm/dmi.h> | ||
10 | |||
11 | static char * __init dmi_string(struct dmi_header *dm, u8 s) | ||
12 | { | ||
13 | u8 *bp = ((u8 *) dm) + dm->length; | ||
14 | char *str = ""; | ||
15 | |||
16 | if (s) { | ||
17 | s--; | ||
18 | while (s > 0 && *bp) { | ||
19 | bp += strlen(bp) + 1; | ||
20 | s--; | ||
21 | } | ||
22 | |||
23 | if (*bp != 0) { | ||
24 | str = dmi_alloc(strlen(bp) + 1); | ||
25 | if (str != NULL) | ||
26 | strcpy(str, bp); | ||
27 | else | ||
28 | printk(KERN_ERR "dmi_string: out of memory.\n"); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | return str; | ||
33 | } | ||
34 | |||
35 | /* | ||
36 | * We have to be cautious here. We have seen BIOSes with DMI pointers | ||
37 | * pointing to completely the wrong place for example | ||
38 | */ | ||
39 | static int __init dmi_table(u32 base, int len, int num, | ||
40 | void (*decode)(struct dmi_header *)) | ||
41 | { | ||
42 | u8 *buf, *data; | ||
43 | int i = 0; | ||
44 | |||
45 | buf = dmi_ioremap(base, len); | ||
46 | if (buf == NULL) | ||
47 | return -1; | ||
48 | |||
49 | data = buf; | ||
50 | |||
51 | /* | ||
52 | * Stop when we see all the items the table claimed to have | ||
53 | * OR we run off the end of the table (also happens) | ||
54 | */ | ||
55 | while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { | ||
56 | struct dmi_header *dm = (struct dmi_header *)data; | ||
57 | /* | ||
58 | * We want to know the total length (formated area and strings) | ||
59 | * before decoding to make sure we won't run off the table in | ||
60 | * dmi_decode or dmi_string | ||
61 | */ | ||
62 | data += dm->length; | ||
63 | while ((data - buf < len - 1) && (data[0] || data[1])) | ||
64 | data++; | ||
65 | if (data - buf < len - 1) | ||
66 | decode(dm); | ||
67 | data += 2; | ||
68 | i++; | ||
69 | } | ||
70 | dmi_iounmap(buf, len); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int __init dmi_checksum(u8 *buf) | ||
75 | { | ||
76 | u8 sum = 0; | ||
77 | int a; | ||
78 | |||
79 | for (a = 0; a < 15; a++) | ||
80 | sum += buf[a]; | ||
81 | |||
82 | return sum == 0; | ||
83 | } | ||
84 | |||
85 | static char *dmi_ident[DMI_STRING_MAX]; | ||
86 | static LIST_HEAD(dmi_devices); | ||
87 | |||
88 | /* | ||
89 | * Save a DMI string | ||
90 | */ | ||
91 | static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) | ||
92 | { | ||
93 | char *p, *d = (char*) dm; | ||
94 | |||
95 | if (dmi_ident[slot]) | ||
96 | return; | ||
97 | |||
98 | p = dmi_string(dm, d[string]); | ||
99 | if (p == NULL) | ||
100 | return; | ||
101 | |||
102 | dmi_ident[slot] = p; | ||
103 | } | ||
104 | |||
105 | static void __init dmi_save_devices(struct dmi_header *dm) | ||
106 | { | ||
107 | int i, count = (dm->length - sizeof(struct dmi_header)) / 2; | ||
108 | struct dmi_device *dev; | ||
109 | |||
110 | for (i = 0; i < count; i++) { | ||
111 | char *d = (char *)(dm + 1) + (i * 2); | ||
112 | |||
113 | /* Skip disabled device */ | ||
114 | if ((*d & 0x80) == 0) | ||
115 | continue; | ||
116 | |||
117 | dev = dmi_alloc(sizeof(*dev)); | ||
118 | if (!dev) { | ||
119 | printk(KERN_ERR "dmi_save_devices: out of memory.\n"); | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | dev->type = *d++ & 0x7f; | ||
124 | dev->name = dmi_string(dm, *d); | ||
125 | dev->device_data = NULL; | ||
126 | |||
127 | list_add(&dev->list, &dmi_devices); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static void __init dmi_save_ipmi_device(struct dmi_header *dm) | ||
132 | { | ||
133 | struct dmi_device *dev; | ||
134 | void * data; | ||
135 | |||
136 | data = dmi_alloc(dm->length); | ||
137 | if (data == NULL) { | ||
138 | printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | memcpy(data, dm, dm->length); | ||
143 | |||
144 | dev = dmi_alloc(sizeof(*dev)); | ||
145 | if (!dev) { | ||
146 | printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); | ||
147 | return; | ||
148 | } | ||
149 | |||
150 | dev->type = DMI_DEV_TYPE_IPMI; | ||
151 | dev->name = "IPMI controller"; | ||
152 | dev->device_data = data; | ||
153 | |||
154 | list_add(&dev->list, &dmi_devices); | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Process a DMI table entry. Right now all we care about are the BIOS | ||
159 | * and machine entries. For 2.5 we should pull the smbus controller info | ||
160 | * out of here. | ||
161 | */ | ||
162 | static void __init dmi_decode(struct dmi_header *dm) | ||
163 | { | ||
164 | switch(dm->type) { | ||
165 | case 0: /* BIOS Information */ | ||
166 | dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); | ||
167 | dmi_save_ident(dm, DMI_BIOS_VERSION, 5); | ||
168 | dmi_save_ident(dm, DMI_BIOS_DATE, 8); | ||
169 | break; | ||
170 | case 1: /* System Information */ | ||
171 | dmi_save_ident(dm, DMI_SYS_VENDOR, 4); | ||
172 | dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); | ||
173 | dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); | ||
174 | dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); | ||
175 | break; | ||
176 | case 2: /* Base Board Information */ | ||
177 | dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); | ||
178 | dmi_save_ident(dm, DMI_BOARD_NAME, 5); | ||
179 | dmi_save_ident(dm, DMI_BOARD_VERSION, 6); | ||
180 | break; | ||
181 | case 10: /* Onboard Devices Information */ | ||
182 | dmi_save_devices(dm); | ||
183 | break; | ||
184 | case 38: /* IPMI Device Information */ | ||
185 | dmi_save_ipmi_device(dm); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | static int __init dmi_present(char __iomem *p) | ||
190 | { | ||
191 | u8 buf[15]; | ||
192 | memcpy_fromio(buf, p, 15); | ||
193 | if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { | ||
194 | u16 num = (buf[13] << 8) | buf[12]; | ||
195 | u16 len = (buf[7] << 8) | buf[6]; | ||
196 | u32 base = (buf[11] << 24) | (buf[10] << 16) | | ||
197 | (buf[9] << 8) | buf[8]; | ||
198 | |||
199 | /* | ||
200 | * DMI version 0.0 means that the real version is taken from | ||
201 | * the SMBIOS version, which we don't know at this point. | ||
202 | */ | ||
203 | if (buf[14] != 0) | ||
204 | printk(KERN_INFO "DMI %d.%d present.\n", | ||
205 | buf[14] >> 4, buf[14] & 0xF); | ||
206 | else | ||
207 | printk(KERN_INFO "DMI present.\n"); | ||
208 | if (dmi_table(base,len, num, dmi_decode) == 0) | ||
209 | return 0; | ||
210 | } | ||
211 | return 1; | ||
212 | } | ||
213 | |||
214 | void __init dmi_scan_machine(void) | ||
215 | { | ||
216 | char __iomem *p, *q; | ||
217 | int rc; | ||
218 | |||
219 | if (efi_enabled) { | ||
220 | if (efi.smbios == EFI_INVALID_TABLE_ADDR) | ||
221 | goto out; | ||
222 | |||
223 | /* This is called as a core_initcall() because it isn't | ||
224 | * needed during early boot. This also means we can | ||
225 | * iounmap the space when we're done with it. | ||
226 | */ | ||
227 | p = dmi_ioremap(efi.smbios, 32); | ||
228 | if (p == NULL) | ||
229 | goto out; | ||
230 | |||
231 | rc = dmi_present(p + 0x10); /* offset of _DMI_ string */ | ||
232 | dmi_iounmap(p, 32); | ||
233 | if (!rc) | ||
234 | return; | ||
235 | } | ||
236 | else { | ||
237 | /* | ||
238 | * no iounmap() for that ioremap(); it would be a no-op, but | ||
239 | * it's so early in setup that sucker gets confused into doing | ||
240 | * what it shouldn't if we actually call it. | ||
241 | */ | ||
242 | p = dmi_ioremap(0xF0000, 0x10000); | ||
243 | if (p == NULL) | ||
244 | goto out; | ||
245 | |||
246 | for (q = p; q < p + 0x10000; q += 16) { | ||
247 | rc = dmi_present(q); | ||
248 | if (!rc) | ||
249 | return; | ||
250 | } | ||
251 | } | ||
252 | out: printk(KERN_INFO "DMI not present or invalid.\n"); | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * dmi_check_system - check system DMI data | ||
257 | * @list: array of dmi_system_id structures to match against | ||
258 | * | ||
259 | * Walk the blacklist table running matching functions until someone | ||
260 | * returns non zero or we hit the end. Callback function is called for | ||
261 | * each successfull match. Returns the number of matches. | ||
262 | */ | ||
263 | int dmi_check_system(struct dmi_system_id *list) | ||
264 | { | ||
265 | int i, count = 0; | ||
266 | struct dmi_system_id *d = list; | ||
267 | |||
268 | while (d->ident) { | ||
269 | for (i = 0; i < ARRAY_SIZE(d->matches); i++) { | ||
270 | int s = d->matches[i].slot; | ||
271 | if (s == DMI_NONE) | ||
272 | continue; | ||
273 | if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr)) | ||
274 | continue; | ||
275 | /* No match */ | ||
276 | goto fail; | ||
277 | } | ||
278 | count++; | ||
279 | if (d->callback && d->callback(d)) | ||
280 | break; | ||
281 | fail: d++; | ||
282 | } | ||
283 | |||
284 | return count; | ||
285 | } | ||
286 | EXPORT_SYMBOL(dmi_check_system); | ||
287 | |||
288 | /** | ||
289 | * dmi_get_system_info - return DMI data value | ||
290 | * @field: data index (see enum dmi_filed) | ||
291 | * | ||
292 | * Returns one DMI data value, can be used to perform | ||
293 | * complex DMI data checks. | ||
294 | */ | ||
295 | char *dmi_get_system_info(int field) | ||
296 | { | ||
297 | return dmi_ident[field]; | ||
298 | } | ||
299 | EXPORT_SYMBOL(dmi_get_system_info); | ||
300 | |||
301 | /** | ||
302 | * dmi_find_device - find onboard device by type/name | ||
303 | * @type: device type or %DMI_DEV_TYPE_ANY to match all device types | ||
304 | * @desc: device name string or %NULL to match all | ||
305 | * @from: previous device found in search, or %NULL for new search. | ||
306 | * | ||
307 | * Iterates through the list of known onboard devices. If a device is | ||
308 | * found with a matching @vendor and @device, a pointer to its device | ||
309 | * structure is returned. Otherwise, %NULL is returned. | ||
310 | * A new search is initiated by passing %NULL to the @from argument. | ||
311 | * If @from is not %NULL, searches continue from next device. | ||
312 | */ | ||
313 | struct dmi_device * dmi_find_device(int type, const char *name, | ||
314 | struct dmi_device *from) | ||
315 | { | ||
316 | struct list_head *d, *head = from ? &from->list : &dmi_devices; | ||
317 | |||
318 | for(d = head->next; d != &dmi_devices; d = d->next) { | ||
319 | struct dmi_device *dev = list_entry(d, struct dmi_device, list); | ||
320 | |||
321 | if (((type == DMI_DEV_TYPE_ANY) || (dev->type == type)) && | ||
322 | ((name == NULL) || (strcmp(dev->name, name) == 0))) | ||
323 | return dev; | ||
324 | } | ||
325 | |||
326 | return NULL; | ||
327 | } | ||
328 | EXPORT_SYMBOL(dmi_find_device); | ||
329 | |||
330 | /** | ||
331 | * dmi_get_year - Return year of a DMI date | ||
332 | * @field: data index (like dmi_get_system_info) | ||
333 | * | ||
334 | * Returns -1 when the field doesn't exist. 0 when it is broken. | ||
335 | */ | ||
336 | int dmi_get_year(int field) | ||
337 | { | ||
338 | int year; | ||
339 | char *s = dmi_get_system_info(field); | ||
340 | |||
341 | if (!s) | ||
342 | return -1; | ||
343 | if (*s == '\0') | ||
344 | return 0; | ||
345 | s = strrchr(s, '/'); | ||
346 | if (!s) | ||
347 | return 0; | ||
348 | |||
349 | s += 1; | ||
350 | year = simple_strtoul(s, NULL, 0); | ||
351 | if (year && year < 100) { /* 2-digit year */ | ||
352 | year += 1900; | ||
353 | if (year < 1996) /* no dates < spec 1.0 */ | ||
354 | year += 100; | ||
355 | } | ||
356 | |||
357 | return year; | ||
358 | } | ||
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 055325056a74..036a9857936f 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c | |||
@@ -19,7 +19,6 @@ EXPORT_SYMBOL(__put_user_2); | |||
19 | EXPORT_SYMBOL(__put_user_4); | 19 | EXPORT_SYMBOL(__put_user_4); |
20 | EXPORT_SYMBOL(__put_user_8); | 20 | EXPORT_SYMBOL(__put_user_8); |
21 | 21 | ||
22 | EXPORT_SYMBOL(strpbrk); | ||
23 | EXPORT_SYMBOL(strstr); | 22 | EXPORT_SYMBOL(strstr); |
24 | 23 | ||
25 | #ifdef CONFIG_SMP | 24 | #ifdef CONFIG_SMP |
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index f19768789e8a..043f5292e70a 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c | |||
@@ -43,7 +43,7 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; | |||
43 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | 43 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
44 | 44 | ||
45 | /* insert a jmp code */ | 45 | /* insert a jmp code */ |
46 | static inline void set_jmp_op(void *from, void *to) | 46 | static __always_inline void set_jmp_op(void *from, void *to) |
47 | { | 47 | { |
48 | struct __arch_jmp_op { | 48 | struct __arch_jmp_op { |
49 | char op; | 49 | char op; |
@@ -57,7 +57,7 @@ static inline void set_jmp_op(void *from, void *to) | |||
57 | /* | 57 | /* |
58 | * returns non-zero if opcodes can be boosted. | 58 | * returns non-zero if opcodes can be boosted. |
59 | */ | 59 | */ |
60 | static inline int can_boost(kprobe_opcode_t opcode) | 60 | static __always_inline int can_boost(kprobe_opcode_t opcode) |
61 | { | 61 | { |
62 | switch (opcode & 0xf0 ) { | 62 | switch (opcode & 0xf0 ) { |
63 | case 0x70: | 63 | case 0x70: |
@@ -88,7 +88,7 @@ static inline int can_boost(kprobe_opcode_t opcode) | |||
88 | /* | 88 | /* |
89 | * returns non-zero if opcode modifies the interrupt flag. | 89 | * returns non-zero if opcode modifies the interrupt flag. |
90 | */ | 90 | */ |
91 | static inline int is_IF_modifier(kprobe_opcode_t opcode) | 91 | static int __kprobes is_IF_modifier(kprobe_opcode_t opcode) |
92 | { | 92 | { |
93 | switch (opcode) { | 93 | switch (opcode) { |
94 | case 0xfa: /* cli */ | 94 | case 0xfa: /* cli */ |
@@ -138,7 +138,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) | |||
138 | mutex_unlock(&kprobe_mutex); | 138 | mutex_unlock(&kprobe_mutex); |
139 | } | 139 | } |
140 | 140 | ||
141 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 141 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
142 | { | 142 | { |
143 | kcb->prev_kprobe.kp = kprobe_running(); | 143 | kcb->prev_kprobe.kp = kprobe_running(); |
144 | kcb->prev_kprobe.status = kcb->kprobe_status; | 144 | kcb->prev_kprobe.status = kcb->kprobe_status; |
@@ -146,7 +146,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
146 | kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags; | 146 | kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags; |
147 | } | 147 | } |
148 | 148 | ||
149 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 149 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
150 | { | 150 | { |
151 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | 151 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
152 | kcb->kprobe_status = kcb->prev_kprobe.status; | 152 | kcb->kprobe_status = kcb->prev_kprobe.status; |
@@ -154,7 +154,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
154 | kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags; | 154 | kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags; |
155 | } | 155 | } |
156 | 156 | ||
157 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | 157 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
158 | struct kprobe_ctlblk *kcb) | 158 | struct kprobe_ctlblk *kcb) |
159 | { | 159 | { |
160 | __get_cpu_var(current_kprobe) = p; | 160 | __get_cpu_var(current_kprobe) = p; |
@@ -164,7 +164,7 @@ static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | |||
164 | kcb->kprobe_saved_eflags &= ~IF_MASK; | 164 | kcb->kprobe_saved_eflags &= ~IF_MASK; |
165 | } | 165 | } |
166 | 166 | ||
167 | static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 167 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) |
168 | { | 168 | { |
169 | regs->eflags |= TF_MASK; | 169 | regs->eflags |= TF_MASK; |
170 | regs->eflags &= ~IF_MASK; | 170 | regs->eflags &= ~IF_MASK; |
@@ -507,7 +507,7 @@ no_change: | |||
507 | * Interrupts are disabled on entry as trap1 is an interrupt gate and they | 507 | * Interrupts are disabled on entry as trap1 is an interrupt gate and they |
508 | * remain disabled thoroughout this function. | 508 | * remain disabled thoroughout this function. |
509 | */ | 509 | */ |
510 | static inline int post_kprobe_handler(struct pt_regs *regs) | 510 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) |
511 | { | 511 | { |
512 | struct kprobe *cur = kprobe_running(); | 512 | struct kprobe *cur = kprobe_running(); |
513 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 513 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -543,7 +543,7 @@ out: | |||
543 | return 1; | 543 | return 1; |
544 | } | 544 | } |
545 | 545 | ||
546 | static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 546 | static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
547 | { | 547 | { |
548 | struct kprobe *cur = kprobe_running(); | 548 | struct kprobe *cur = kprobe_running(); |
549 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 549 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 8d8aa9d1796d..34d21e21e012 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c | |||
@@ -38,12 +38,6 @@ | |||
38 | int smp_found_config; | 38 | int smp_found_config; |
39 | unsigned int __initdata maxcpus = NR_CPUS; | 39 | unsigned int __initdata maxcpus = NR_CPUS; |
40 | 40 | ||
41 | #ifdef CONFIG_HOTPLUG_CPU | ||
42 | #define CPU_HOTPLUG_ENABLED (1) | ||
43 | #else | ||
44 | #define CPU_HOTPLUG_ENABLED (0) | ||
45 | #endif | ||
46 | |||
47 | /* | 41 | /* |
48 | * Various Linux-internal data structures created from the | 42 | * Various Linux-internal data structures created from the |
49 | * MP-table. | 43 | * MP-table. |
@@ -110,21 +104,6 @@ static int __init mpf_checksum(unsigned char *mp, int len) | |||
110 | static int mpc_record; | 104 | static int mpc_record; |
111 | static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; | 105 | static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; |
112 | 106 | ||
113 | #ifdef CONFIG_X86_NUMAQ | ||
114 | static int MP_valid_apicid(int apicid, int version) | ||
115 | { | ||
116 | return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf; | ||
117 | } | ||
118 | #else | ||
119 | static int MP_valid_apicid(int apicid, int version) | ||
120 | { | ||
121 | if (version >= 0x14) | ||
122 | return apicid < 0xff; | ||
123 | else | ||
124 | return apicid < 0xf; | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | static void __devinit MP_processor_info (struct mpc_config_processor *m) | 107 | static void __devinit MP_processor_info (struct mpc_config_processor *m) |
129 | { | 108 | { |
130 | int ver, apicid; | 109 | int ver, apicid; |
@@ -190,12 +169,6 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m) | |||
190 | 169 | ||
191 | ver = m->mpc_apicver; | 170 | ver = m->mpc_apicver; |
192 | 171 | ||
193 | if (!MP_valid_apicid(apicid, ver)) { | ||
194 | printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n", | ||
195 | m->mpc_apicid, MAX_APICS); | ||
196 | return; | ||
197 | } | ||
198 | |||
199 | /* | 172 | /* |
200 | * Validate version | 173 | * Validate version |
201 | */ | 174 | */ |
@@ -225,7 +198,14 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m) | |||
225 | cpu_set(num_processors, cpu_possible_map); | 198 | cpu_set(num_processors, cpu_possible_map); |
226 | num_processors++; | 199 | num_processors++; |
227 | 200 | ||
228 | if (CPU_HOTPLUG_ENABLED || (num_processors > 8)) { | 201 | /* |
202 | * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y | ||
203 | * but we need to work other dependencies like SMP_SUSPEND etc | ||
204 | * before this can be done without some confusion. | ||
205 | * if (CPU_HOTPLUG_ENABLED || num_processors > 8) | ||
206 | * - Ashok Raj <ashok.raj@intel.com> | ||
207 | */ | ||
208 | if (num_processors > 8) { | ||
229 | switch (boot_cpu_data.x86_vendor) { | 209 | switch (boot_cpu_data.x86_vendor) { |
230 | case X86_VENDOR_INTEL: | 210 | case X86_VENDOR_INTEL: |
231 | if (!APIC_XAPIC(ver)) { | 211 | if (!APIC_XAPIC(ver)) { |
@@ -249,6 +229,13 @@ static void __init MP_bus_info (struct mpc_config_bus *m) | |||
249 | 229 | ||
250 | mpc_oem_bus_info(m, str, translation_table[mpc_record]); | 230 | mpc_oem_bus_info(m, str, translation_table[mpc_record]); |
251 | 231 | ||
232 | if (m->mpc_busid >= MAX_MP_BUSSES) { | ||
233 | printk(KERN_WARNING "MP table busid value (%d) for bustype %s " | ||
234 | " is too large, max. supported is %d\n", | ||
235 | m->mpc_busid, str, MAX_MP_BUSSES - 1); | ||
236 | return; | ||
237 | } | ||
238 | |||
252 | if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { | 239 | if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { |
253 | mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; | 240 | mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; |
254 | } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { | 241 | } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { |
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index 1d0a55e68760..7a328230e540 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c | |||
@@ -251,7 +251,7 @@ static int msr_class_device_create(int i) | |||
251 | return err; | 251 | return err; |
252 | } | 252 | } |
253 | 253 | ||
254 | static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 254 | static int msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
255 | { | 255 | { |
256 | unsigned int cpu = (unsigned long)hcpu; | 256 | unsigned int cpu = (unsigned long)hcpu; |
257 | 257 | ||
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c index 10e21a4773dd..99aab41a05b0 100644 --- a/arch/i386/kernel/reboot_fixups.c +++ b/arch/i386/kernel/reboot_fixups.c | |||
@@ -51,7 +51,5 @@ void mach_reboot_fixups(void) | |||
51 | 51 | ||
52 | cur->reboot_fixup(dev); | 52 | cur->reboot_fixup(dev); |
53 | } | 53 | } |
54 | |||
55 | printk(KERN_WARNING "No reboot fixup found for your hardware\n"); | ||
56 | } | 54 | } |
57 | 55 | ||
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index eacc3f0a2ea4..80cb3b2d0997 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -963,6 +963,36 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) | |||
963 | return 0; | 963 | return 0; |
964 | } | 964 | } |
965 | 965 | ||
966 | /* | ||
967 | * This function checks if the entire range <start,end> is mapped with type. | ||
968 | * | ||
969 | * Note: this function only works correct if the e820 table is sorted and | ||
970 | * not-overlapping, which is the case | ||
971 | */ | ||
972 | int __init | ||
973 | e820_all_mapped(unsigned long start, unsigned long end, unsigned type) | ||
974 | { | ||
975 | int i; | ||
976 | for (i = 0; i < e820.nr_map; i++) { | ||
977 | struct e820entry *ei = &e820.map[i]; | ||
978 | if (type && ei->type != type) | ||
979 | continue; | ||
980 | /* is the region (part) in overlap with the current region ?*/ | ||
981 | if (ei->addr >= end || ei->addr + ei->size <= start) | ||
982 | continue; | ||
983 | /* if the region is at the beginning of <start,end> we move | ||
984 | * start to the end of the region since it's ok until there | ||
985 | */ | ||
986 | if (ei->addr <= start) | ||
987 | start = ei->addr + ei->size; | ||
988 | /* if start is now at or beyond end, we're done, full | ||
989 | * coverage */ | ||
990 | if (start >= end) | ||
991 | return 1; /* we're done */ | ||
992 | } | ||
993 | return 0; | ||
994 | } | ||
995 | |||
966 | /* | 996 | /* |
967 | * Find the highest page frame number we have available | 997 | * Find the highest page frame number we have available |
968 | */ | 998 | */ |
@@ -1317,8 +1347,8 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat | |||
1317 | /* | 1347 | /* |
1318 | * Request address space for all standard resources | 1348 | * Request address space for all standard resources |
1319 | * | 1349 | * |
1320 | * This is called just before pcibios_assign_resources(), which is also | 1350 | * This is called just before pcibios_init(), which is also a |
1321 | * an fs_initcall, but is linked in later (in arch/i386/pci/i386.c). | 1351 | * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). |
1322 | */ | 1352 | */ |
1323 | static int __init request_standard_resources(void) | 1353 | static int __init request_standard_resources(void) |
1324 | { | 1354 | { |
@@ -1339,7 +1369,7 @@ static int __init request_standard_resources(void) | |||
1339 | return 0; | 1369 | return 0; |
1340 | } | 1370 | } |
1341 | 1371 | ||
1342 | fs_initcall(request_standard_resources); | 1372 | subsys_initcall(request_standard_resources); |
1343 | 1373 | ||
1344 | static void __init register_memory(void) | 1374 | static void __init register_memory(void) |
1345 | { | 1375 | { |
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index 4f58b9c0efe3..f48bef15b4f0 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S | |||
@@ -314,3 +314,4 @@ ENTRY(sys_call_table) | |||
314 | .long sys_get_robust_list | 314 | .long sys_get_robust_list |
315 | .long sys_splice | 315 | .long sys_splice |
316 | .long sys_sync_file_range | 316 | .long sys_sync_file_range |
317 | .long sys_tee /* 315 */ | ||
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index e38527994590..2d22f5761b1d 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -365,6 +365,9 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
365 | 365 | ||
366 | if (++die.lock_owner_depth < 3) { | 366 | if (++die.lock_owner_depth < 3) { |
367 | int nl = 0; | 367 | int nl = 0; |
368 | unsigned long esp; | ||
369 | unsigned short ss; | ||
370 | |||
368 | handle_BUG(regs); | 371 | handle_BUG(regs); |
369 | printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); | 372 | printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); |
370 | #ifdef CONFIG_PREEMPT | 373 | #ifdef CONFIG_PREEMPT |
@@ -387,8 +390,19 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
387 | printk("\n"); | 390 | printk("\n"); |
388 | if (notify_die(DIE_OOPS, str, regs, err, | 391 | if (notify_die(DIE_OOPS, str, regs, err, |
389 | current->thread.trap_no, SIGSEGV) != | 392 | current->thread.trap_no, SIGSEGV) != |
390 | NOTIFY_STOP) | 393 | NOTIFY_STOP) { |
391 | show_registers(regs); | 394 | show_registers(regs); |
395 | /* Executive summary in case the oops scrolled away */ | ||
396 | esp = (unsigned long) (®s->esp); | ||
397 | savesegment(ss, ss); | ||
398 | if (user_mode(regs)) { | ||
399 | esp = regs->esp; | ||
400 | ss = regs->xss & 0xffff; | ||
401 | } | ||
402 | printk(KERN_EMERG "EIP: [<%08lx>] ", regs->eip); | ||
403 | print_symbol("%s", regs->eip); | ||
404 | printk(" SS:ESP %04x:%08lx\n", ss, esp); | ||
405 | } | ||
392 | else | 406 | else |
393 | regs = NULL; | 407 | regs = NULL; |
394 | } else | 408 | } else |
diff --git a/arch/i386/mach-voyager/voyager_cat.c b/arch/i386/mach-voyager/voyager_cat.c index 23967fe658d3..10d21df14531 100644 --- a/arch/i386/mach-voyager/voyager_cat.c +++ b/arch/i386/mach-voyager/voyager_cat.c | |||
@@ -106,15 +106,20 @@ voyager_module_t *voyager_cat_list; | |||
106 | 106 | ||
107 | /* the I/O port assignments for the VIC and QIC */ | 107 | /* the I/O port assignments for the VIC and QIC */ |
108 | static struct resource vic_res = { | 108 | static struct resource vic_res = { |
109 | "Voyager Interrupt Controller", 0xFC00, 0xFC6F }; | 109 | .name = "Voyager Interrupt Controller", |
110 | .start = 0xFC00, | ||
111 | .end = 0xFC6F | ||
112 | }; | ||
110 | static struct resource qic_res = { | 113 | static struct resource qic_res = { |
111 | "Quad Interrupt Controller", 0xFC70, 0xFCFF }; | 114 | .name = "Quad Interrupt Controller", |
115 | .start = 0xFC70, | ||
116 | .end = 0xFCFF | ||
117 | }; | ||
112 | 118 | ||
113 | /* This function is used to pack a data bit stream inside a message. | 119 | /* This function is used to pack a data bit stream inside a message. |
114 | * It writes num_bits of the data buffer in msg starting at start_bit. | 120 | * It writes num_bits of the data buffer in msg starting at start_bit. |
115 | * Note: This function assumes that any unused bit in the data stream | 121 | * Note: This function assumes that any unused bit in the data stream |
116 | * is set to zero so that the ors will work correctly */ | 122 | * is set to zero so that the ors will work correctly */ |
117 | #define BITS_PER_BYTE 8 | ||
118 | static void | 123 | static void |
119 | cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits) | 124 | cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits) |
120 | { | 125 | { |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 9f66ac582a8b..ae6534ad8161 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -651,6 +651,7 @@ void __init mem_init(void) | |||
651 | * Specifically, in the case of x86, we will always add | 651 | * Specifically, in the case of x86, we will always add |
652 | * memory to the highmem for now. | 652 | * memory to the highmem for now. |
653 | */ | 653 | */ |
654 | #ifdef CONFIG_HOTPLUG_MEMORY | ||
654 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 655 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
655 | int add_memory(u64 start, u64 size) | 656 | int add_memory(u64 start, u64 size) |
656 | { | 657 | { |
@@ -667,6 +668,7 @@ int remove_memory(u64 start, u64 size) | |||
667 | return -EINVAL; | 668 | return -EINVAL; |
668 | } | 669 | } |
669 | #endif | 670 | #endif |
671 | #endif | ||
670 | 672 | ||
671 | kmem_cache_t *pgd_cache; | 673 | kmem_cache_t *pgd_cache; |
672 | kmem_cache_t *pmd_cache; | 674 | kmem_cache_t *pmd_cache; |
diff --git a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c index 99012b93bd12..5d81fb510375 100644 --- a/arch/i386/pci/direct.c +++ b/arch/i386/pci/direct.c | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/dmi.h> | ||
7 | #include "pci.h" | 8 | #include "pci.h" |
8 | 9 | ||
9 | /* | 10 | /* |
@@ -18,8 +19,10 @@ int pci_conf1_read(unsigned int seg, unsigned int bus, | |||
18 | { | 19 | { |
19 | unsigned long flags; | 20 | unsigned long flags; |
20 | 21 | ||
21 | if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) | 22 | if ((bus > 255) || (devfn > 255) || (reg > 255)) { |
23 | *value = -1; | ||
22 | return -EINVAL; | 24 | return -EINVAL; |
25 | } | ||
23 | 26 | ||
24 | spin_lock_irqsave(&pci_config_lock, flags); | 27 | spin_lock_irqsave(&pci_config_lock, flags); |
25 | 28 | ||
@@ -91,8 +94,10 @@ static int pci_conf2_read(unsigned int seg, unsigned int bus, | |||
91 | unsigned long flags; | 94 | unsigned long flags; |
92 | int dev, fn; | 95 | int dev, fn; |
93 | 96 | ||
94 | if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) | 97 | if ((bus > 255) || (devfn > 255) || (reg > 255)) { |
98 | *value = -1; | ||
95 | return -EINVAL; | 99 | return -EINVAL; |
100 | } | ||
96 | 101 | ||
97 | dev = PCI_SLOT(devfn); | 102 | dev = PCI_SLOT(devfn); |
98 | fn = PCI_FUNC(devfn); | 103 | fn = PCI_FUNC(devfn); |
@@ -188,6 +193,10 @@ static int __init pci_sanity_check(struct pci_raw_ops *o) | |||
188 | 193 | ||
189 | if (pci_probe & PCI_NO_CHECKS) | 194 | if (pci_probe & PCI_NO_CHECKS) |
190 | return 1; | 195 | return 1; |
196 | /* Assume Type 1 works for newer systems. | ||
197 | This handles machines that don't have anything on PCI Bus 0. */ | ||
198 | if (dmi_get_year(DMI_BIOS_DATE) >= 2001) | ||
199 | return 1; | ||
191 | 200 | ||
192 | for (devfn = 0; devfn < 0x100; devfn++) { | 201 | for (devfn = 0; devfn < 0x100; devfn++) { |
193 | if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x)) | 202 | if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x)) |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 3ca59cad05f3..73235443fda7 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -588,7 +588,10 @@ static __init int via_router_probe(struct irq_router *r, | |||
588 | case PCI_DEVICE_ID_VIA_82C596: | 588 | case PCI_DEVICE_ID_VIA_82C596: |
589 | case PCI_DEVICE_ID_VIA_82C686: | 589 | case PCI_DEVICE_ID_VIA_82C686: |
590 | case PCI_DEVICE_ID_VIA_8231: | 590 | case PCI_DEVICE_ID_VIA_8231: |
591 | case PCI_DEVICE_ID_VIA_8233A: | ||
591 | case PCI_DEVICE_ID_VIA_8235: | 592 | case PCI_DEVICE_ID_VIA_8235: |
593 | case PCI_DEVICE_ID_VIA_8237: | ||
594 | case PCI_DEVICE_ID_VIA_8237_SATA: | ||
592 | /* FIXME: add new ones for 8233/5 */ | 595 | /* FIXME: add new ones for 8233/5 */ |
593 | r->name = "VIA"; | 596 | r->name = "VIA"; |
594 | r->get = pirq_via_get; | 597 | r->get = pirq_via_get; |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 613789071f30..6b1ea0c9a570 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -12,14 +12,20 @@ | |||
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
15 | #include <asm/e820.h> | ||
15 | #include "pci.h" | 16 | #include "pci.h" |
16 | 17 | ||
18 | #define MMCONFIG_APER_SIZE (256*1024*1024) | ||
19 | |||
20 | /* Assume systems with more busses have correct MCFG */ | ||
21 | #define MAX_CHECK_BUS 16 | ||
22 | |||
17 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) | 23 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) |
18 | 24 | ||
19 | /* The base address of the last MMCONFIG device accessed */ | 25 | /* The base address of the last MMCONFIG device accessed */ |
20 | static u32 mmcfg_last_accessed_device; | 26 | static u32 mmcfg_last_accessed_device; |
21 | 27 | ||
22 | static DECLARE_BITMAP(fallback_slots, 32); | 28 | static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32); |
23 | 29 | ||
24 | /* | 30 | /* |
25 | * Functions for accessing PCI configuration space with MMCONFIG accesses | 31 | * Functions for accessing PCI configuration space with MMCONFIG accesses |
@@ -29,8 +35,8 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | |||
29 | int cfg_num = -1; | 35 | int cfg_num = -1; |
30 | struct acpi_table_mcfg_config *cfg; | 36 | struct acpi_table_mcfg_config *cfg; |
31 | 37 | ||
32 | if (seg == 0 && bus == 0 && | 38 | if (seg == 0 && bus < MAX_CHECK_BUS && |
33 | test_bit(PCI_SLOT(devfn), fallback_slots)) | 39 | test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots)) |
34 | return 0; | 40 | return 0; |
35 | 41 | ||
36 | while (1) { | 42 | while (1) { |
@@ -74,8 +80,10 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
74 | unsigned long flags; | 80 | unsigned long flags; |
75 | u32 base; | 81 | u32 base; |
76 | 82 | ||
77 | if (!value || (bus > 255) || (devfn > 255) || (reg > 4095)) | 83 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) { |
84 | *value = -1; | ||
78 | return -EINVAL; | 85 | return -EINVAL; |
86 | } | ||
79 | 87 | ||
80 | base = get_base_addr(seg, bus, devfn); | 88 | base = get_base_addr(seg, bus, devfn); |
81 | if (!base) | 89 | if (!base) |
@@ -146,29 +154,34 @@ static struct pci_raw_ops pci_mmcfg = { | |||
146 | Normally this can be expressed in the MCFG by not listing them | 154 | Normally this can be expressed in the MCFG by not listing them |
147 | and assigning suitable _SEGs, but this isn't implemented in some BIOS. | 155 | and assigning suitable _SEGs, but this isn't implemented in some BIOS. |
148 | Instead try to discover all devices on bus 0 that are unreachable using MM | 156 | Instead try to discover all devices on bus 0 that are unreachable using MM |
149 | and fallback for them. | 157 | and fallback for them. */ |
150 | We only do this for bus 0/seg 0 */ | ||
151 | static __init void unreachable_devices(void) | 158 | static __init void unreachable_devices(void) |
152 | { | 159 | { |
153 | int i; | 160 | int i, k; |
154 | unsigned long flags; | 161 | unsigned long flags; |
155 | 162 | ||
156 | for (i = 0; i < 32; i++) { | 163 | for (k = 0; k < MAX_CHECK_BUS; k++) { |
157 | u32 val1; | 164 | for (i = 0; i < 32; i++) { |
158 | u32 addr; | 165 | u32 val1; |
159 | 166 | u32 addr; | |
160 | pci_conf1_read(0, 0, PCI_DEVFN(i, 0), 0, 4, &val1); | 167 | |
161 | if (val1 == 0xffffffff) | 168 | pci_conf1_read(0, k, PCI_DEVFN(i, 0), 0, 4, &val1); |
162 | continue; | 169 | if (val1 == 0xffffffff) |
163 | 170 | continue; | |
164 | /* Locking probably not needed, but safer */ | 171 | |
165 | spin_lock_irqsave(&pci_config_lock, flags); | 172 | /* Locking probably not needed, but safer */ |
166 | addr = get_base_addr(0, 0, PCI_DEVFN(i, 0)); | 173 | spin_lock_irqsave(&pci_config_lock, flags); |
167 | if (addr != 0) | 174 | addr = get_base_addr(0, k, PCI_DEVFN(i, 0)); |
168 | pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0)); | 175 | if (addr != 0) |
169 | if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1) | 176 | pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0)); |
170 | set_bit(i, fallback_slots); | 177 | if (addr == 0 || |
171 | spin_unlock_irqrestore(&pci_config_lock, flags); | 178 | readl((u32 __iomem *)mmcfg_virt_addr) != val1) { |
179 | set_bit(i, fallback_slots); | ||
180 | printk(KERN_NOTICE | ||
181 | "PCI: No mmconfig possible on %x:%x\n", k, i); | ||
182 | } | ||
183 | spin_unlock_irqrestore(&pci_config_lock, flags); | ||
184 | } | ||
172 | } | 185 | } |
173 | } | 186 | } |
174 | 187 | ||
@@ -183,6 +196,14 @@ void __init pci_mmcfg_init(void) | |||
183 | (pci_mmcfg_config[0].base_address == 0)) | 196 | (pci_mmcfg_config[0].base_address == 0)) |
184 | return; | 197 | return; |
185 | 198 | ||
199 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||
200 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | ||
201 | E820_RESERVED)) { | ||
202 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | ||
203 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||
204 | return; | ||
205 | } | ||
206 | |||
186 | printk(KERN_INFO "PCI: Using MMCONFIG\n"); | 207 | printk(KERN_INFO "PCI: Using MMCONFIG\n"); |
187 | raw_pci_ops = &pci_mmcfg; | 208 | raw_pci_ops = &pci_mmcfg; |
188 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | 209 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index edffe25a477a..9f40eeff0b5c 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -260,15 +260,6 @@ config NR_CPUS | |||
260 | than 64 will cause the use of a CPU mask array, causing a small | 260 | than 64 will cause the use of a CPU mask array, causing a small |
261 | performance hit. | 261 | performance hit. |
262 | 262 | ||
263 | config IA64_NR_NODES | ||
264 | int "Maximum number of NODEs (256-1024)" if (IA64_SGI_SN2 || IA64_GENERIC) | ||
265 | range 256 1024 | ||
266 | depends on IA64_SGI_SN2 || IA64_GENERIC | ||
267 | default "256" | ||
268 | help | ||
269 | This option specifies the maximum number of nodes in your SSI system. | ||
270 | If in doubt, use the default. | ||
271 | |||
272 | config HOTPLUG_CPU | 263 | config HOTPLUG_CPU |
273 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | 264 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" |
274 | depends on SMP && EXPERIMENTAL | 265 | depends on SMP && EXPERIMENTAL |
@@ -352,6 +343,16 @@ config NUMA | |||
352 | Access). This option is for configuring high-end multiprocessor | 343 | Access). This option is for configuring high-end multiprocessor |
353 | server systems. If in doubt, say N. | 344 | server systems. If in doubt, say N. |
354 | 345 | ||
346 | config NODES_SHIFT | ||
347 | int "Max num nodes shift(3-10)" | ||
348 | range 3 10 | ||
349 | default "8" | ||
350 | depends on NEED_MULTIPLE_NODES | ||
351 | help | ||
352 | This option specifies the maximum number of nodes in your SSI system. | ||
353 | MAX_NUMNODES will be 2^(This value). | ||
354 | If in doubt, use the default. | ||
355 | |||
355 | # VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent. | 356 | # VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent. |
356 | # VIRTUAL_MEM_MAP has been retained for historical reasons. | 357 | # VIRTUAL_MEM_MAP has been retained for historical reasons. |
357 | config VIRTUAL_MEM_MAP | 358 | config VIRTUAL_MEM_MAP |
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 59e871dae742..09a0dbc17fb6 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile | |||
@@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.lds | |||
7 | obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ | 7 | obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ |
8 | irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ | 8 | irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ |
9 | salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ | 9 | salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ |
10 | unwind.o mca.o mca_asm.o topology.o dmi_scan.o | 10 | unwind.o mca.o mca_asm.o topology.o |
11 | 11 | ||
12 | obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o | 12 | obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o |
13 | obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o | 13 | obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o |
@@ -30,7 +30,6 @@ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o | |||
30 | obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o | 30 | obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o |
31 | obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o | 31 | obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o |
32 | mca_recovery-y += mca_drv.o mca_drv_asm.o | 32 | mca_recovery-y += mca_drv.o mca_drv_asm.o |
33 | dmi_scan-y += ../../i386/kernel/dmi_scan.o | ||
34 | 33 | ||
35 | # The gate DSO image is built using a special linker script. | 34 | # The gate DSO image is built using a special linker script. |
36 | targets += gate.so gate-syms.o | 35 | targets += gate.so gate-syms.o |
diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c index 4a5574ff007b..fff82929d225 100644 --- a/arch/ia64/kernel/acpi-ext.c +++ b/arch/ia64/kernel/acpi-ext.c | |||
@@ -1,105 +1,104 @@ | |||
1 | /* | 1 | /* |
2 | * arch/ia64/kernel/acpi-ext.c | 2 | * (c) Copyright 2003, 2006 Hewlett-Packard Development Company, L.P. |
3 | * Alex Williamson <alex.williamson@hp.com> | ||
4 | * Bjorn Helgaas <bjorn.helgaas@hp.com> | ||
3 | * | 5 | * |
4 | * Copyright (C) 2003 Hewlett-Packard | 6 | * This program is free software; you can redistribute it and/or modify |
5 | * Copyright (C) Alex Williamson | 7 | * it under the terms of the GNU General Public License version 2 as |
6 | * Copyright (C) Bjorn Helgaas | 8 | * published by the Free Software Foundation. |
7 | * | ||
8 | * Vendor specific extensions to ACPI. | ||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
15 | #include <linux/efi.h> | ||
16 | 15 | ||
17 | #include <asm/acpi-ext.h> | 16 | #include <asm/acpi-ext.h> |
18 | 17 | ||
19 | struct acpi_vendor_descriptor { | 18 | /* |
20 | u8 guid_id; | 19 | * Device CSRs that do not appear in PCI config space should be described |
21 | efi_guid_t guid; | 20 | * via ACPI. This would normally be done with Address Space Descriptors |
22 | }; | 21 | * marked as "consumer-only," but old versions of Windows and Linux ignore |
22 | * the producer/consumer flag, so HP invented a vendor-defined resource to | ||
23 | * describe the location and size of CSR space. | ||
24 | */ | ||
23 | 25 | ||
24 | struct acpi_vendor_info { | 26 | struct acpi_vendor_uuid hp_ccsr_uuid = { |
25 | struct acpi_vendor_descriptor *descriptor; | 27 | .subtype = 2, |
26 | u8 *data; | 28 | .data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a, |
27 | u32 length; | 29 | 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad }, |
28 | }; | 30 | }; |
29 | 31 | ||
30 | acpi_status | 32 | static acpi_status hp_ccsr_locate(acpi_handle obj, u64 *base, u64 *length) |
31 | acpi_vendor_resource_match(struct acpi_resource *resource, void *context) | ||
32 | { | 33 | { |
33 | struct acpi_vendor_info *info = (struct acpi_vendor_info *)context; | 34 | acpi_status status; |
34 | struct acpi_resource_vendor *vendor; | 35 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
35 | struct acpi_vendor_descriptor *descriptor; | 36 | struct acpi_resource *resource; |
36 | u32 byte_length; | 37 | struct acpi_resource_vendor_typed *vendor; |
37 | |||
38 | if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) | ||
39 | return AE_OK; | ||
40 | |||
41 | vendor = (struct acpi_resource_vendor *)&resource->data; | ||
42 | descriptor = (struct acpi_vendor_descriptor *)vendor->byte_data; | ||
43 | if (vendor->byte_length <= sizeof(*info->descriptor) || | ||
44 | descriptor->guid_id != info->descriptor->guid_id || | ||
45 | efi_guidcmp(descriptor->guid, info->descriptor->guid)) | ||
46 | return AE_OK; | ||
47 | |||
48 | byte_length = vendor->byte_length - sizeof(struct acpi_vendor_descriptor); | ||
49 | info->data = acpi_os_allocate(byte_length); | ||
50 | if (!info->data) | ||
51 | return AE_NO_MEMORY; | ||
52 | |||
53 | memcpy(info->data, | ||
54 | vendor->byte_data + sizeof(struct acpi_vendor_descriptor), | ||
55 | byte_length); | ||
56 | info->length = byte_length; | ||
57 | return AE_CTRL_TERMINATE; | ||
58 | } | ||
59 | 38 | ||
60 | acpi_status | 39 | status = acpi_get_vendor_resource(obj, METHOD_NAME__CRS, &hp_ccsr_uuid, |
61 | acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, | 40 | &buffer); |
62 | u8 ** data, u32 * byte_length) | ||
63 | { | ||
64 | struct acpi_vendor_info info; | ||
65 | 41 | ||
66 | info.descriptor = id; | 42 | resource = buffer.pointer; |
67 | info.data = NULL; | 43 | vendor = &resource->data.vendor_typed; |
68 | 44 | ||
69 | acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, | 45 | if (ACPI_FAILURE(status) || vendor->byte_length < 16) { |
70 | &info); | 46 | status = AE_NOT_FOUND; |
71 | if (!info.data) | 47 | goto exit; |
72 | return AE_NOT_FOUND; | 48 | } |
73 | 49 | ||
74 | *data = info.data; | 50 | memcpy(base, vendor->byte_data, sizeof(*base)); |
75 | *byte_length = info.length; | 51 | memcpy(length, vendor->byte_data + 8, sizeof(*length)); |
76 | return AE_OK; | 52 | |
53 | exit: | ||
54 | acpi_os_free(buffer.pointer); | ||
55 | return status; | ||
77 | } | 56 | } |
78 | 57 | ||
79 | struct acpi_vendor_descriptor hp_ccsr_descriptor = { | 58 | struct csr_space { |
80 | .guid_id = 2, | 59 | u64 base; |
81 | .guid = | 60 | u64 length; |
82 | EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01, | ||
83 | 0x37, 0x0e, 0xad) | ||
84 | }; | 61 | }; |
85 | 62 | ||
86 | acpi_status hp_acpi_csr_space(acpi_handle obj, u64 * csr_base, u64 * csr_length) | 63 | static acpi_status find_csr_space(struct acpi_resource *resource, void *data) |
87 | { | 64 | { |
65 | struct csr_space *space = data; | ||
66 | struct acpi_resource_address64 addr; | ||
88 | acpi_status status; | 67 | acpi_status status; |
89 | u8 *data; | ||
90 | u32 length; | ||
91 | 68 | ||
92 | status = | 69 | status = acpi_resource_to_address64(resource, &addr); |
93 | acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length); | 70 | if (ACPI_SUCCESS(status) && |
71 | addr.resource_type == ACPI_MEMORY_RANGE && | ||
72 | addr.address_length && | ||
73 | addr.producer_consumer == ACPI_CONSUMER) { | ||
74 | space->base = addr.minimum; | ||
75 | space->length = addr.address_length; | ||
76 | return AE_CTRL_TERMINATE; | ||
77 | } | ||
78 | return AE_OK; /* keep looking */ | ||
79 | } | ||
94 | 80 | ||
95 | if (ACPI_FAILURE(status) || length != 16) | 81 | static acpi_status hp_crs_locate(acpi_handle obj, u64 *base, u64 *length) |
96 | return AE_NOT_FOUND; | 82 | { |
83 | struct csr_space space = { 0, 0 }; | ||
97 | 84 | ||
98 | memcpy(csr_base, data, sizeof(*csr_base)); | 85 | acpi_walk_resources(obj, METHOD_NAME__CRS, find_csr_space, &space); |
99 | memcpy(csr_length, data + 8, sizeof(*csr_length)); | 86 | if (!space.length) |
100 | acpi_os_free(data); | 87 | return AE_NOT_FOUND; |
101 | 88 | ||
89 | *base = space.base; | ||
90 | *length = space.length; | ||
102 | return AE_OK; | 91 | return AE_OK; |
103 | } | 92 | } |
104 | 93 | ||
94 | acpi_status hp_acpi_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length) | ||
95 | { | ||
96 | acpi_status status; | ||
97 | |||
98 | status = hp_ccsr_locate(obj, csr_base, csr_length); | ||
99 | if (ACPI_SUCCESS(status)) | ||
100 | return status; | ||
101 | |||
102 | return hp_crs_locate(obj, csr_base, csr_length); | ||
103 | } | ||
105 | EXPORT_SYMBOL(hp_acpi_csr_space); | 104 | EXPORT_SYMBOL(hp_acpi_csr_space); |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 750e8e7fbdc3..e30798811216 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1606,5 +1606,9 @@ sys_call_table: | |||
1606 | data8 sys_ni_syscall // 1295 reserved for ppoll | 1606 | data8 sys_ni_syscall // 1295 reserved for ppoll |
1607 | data8 sys_unshare | 1607 | data8 sys_unshare |
1608 | data8 sys_splice | 1608 | data8 sys_splice |
1609 | data8 sys_set_robust_list | ||
1610 | data8 sys_get_robust_list | ||
1611 | data8 sys_sync_file_range // 1300 | ||
1612 | data8 sys_tee | ||
1609 | 1613 | ||
1610 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls | 1614 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls |
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 789881ca83d4..f9039f88d01d 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c | |||
@@ -251,7 +251,7 @@ static void __kprobes prepare_break_inst(uint template, uint slot, | |||
251 | update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p); | 251 | update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p); |
252 | } | 252 | } |
253 | 253 | ||
254 | static inline void get_kprobe_inst(bundle_t *bundle, uint slot, | 254 | static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot, |
255 | unsigned long *kprobe_inst, uint *major_opcode) | 255 | unsigned long *kprobe_inst, uint *major_opcode) |
256 | { | 256 | { |
257 | unsigned long kprobe_inst_p0, kprobe_inst_p1; | 257 | unsigned long kprobe_inst_p0, kprobe_inst_p1; |
@@ -278,7 +278,7 @@ static inline void get_kprobe_inst(bundle_t *bundle, uint slot, | |||
278 | } | 278 | } |
279 | 279 | ||
280 | /* Returns non-zero if the addr is in the Interrupt Vector Table */ | 280 | /* Returns non-zero if the addr is in the Interrupt Vector Table */ |
281 | static inline int in_ivt_functions(unsigned long addr) | 281 | static int __kprobes in_ivt_functions(unsigned long addr) |
282 | { | 282 | { |
283 | return (addr >= (unsigned long)__start_ivt_text | 283 | return (addr >= (unsigned long)__start_ivt_text |
284 | && addr < (unsigned long)__end_ivt_text); | 284 | && addr < (unsigned long)__end_ivt_text); |
@@ -308,19 +308,19 @@ static int __kprobes valid_kprobe_addr(int template, int slot, | |||
308 | return 0; | 308 | return 0; |
309 | } | 309 | } |
310 | 310 | ||
311 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 311 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
312 | { | 312 | { |
313 | kcb->prev_kprobe.kp = kprobe_running(); | 313 | kcb->prev_kprobe.kp = kprobe_running(); |
314 | kcb->prev_kprobe.status = kcb->kprobe_status; | 314 | kcb->prev_kprobe.status = kcb->kprobe_status; |
315 | } | 315 | } |
316 | 316 | ||
317 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 317 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
318 | { | 318 | { |
319 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | 319 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
320 | kcb->kprobe_status = kcb->prev_kprobe.status; | 320 | kcb->kprobe_status = kcb->prev_kprobe.status; |
321 | } | 321 | } |
322 | 322 | ||
323 | static inline void set_current_kprobe(struct kprobe *p, | 323 | static void __kprobes set_current_kprobe(struct kprobe *p, |
324 | struct kprobe_ctlblk *kcb) | 324 | struct kprobe_ctlblk *kcb) |
325 | { | 325 | { |
326 | __get_cpu_var(current_kprobe) = p; | 326 | __get_cpu_var(current_kprobe) = p; |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 8963171788d5..6a0880639bc9 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -581,10 +581,12 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs) | |||
581 | { | 581 | { |
582 | unsigned long flags; | 582 | unsigned long flags; |
583 | int cpu = smp_processor_id(); | 583 | int cpu = smp_processor_id(); |
584 | struct ia64_mca_notify_die nd = | ||
585 | { .sos = NULL, .monarch_cpu = &monarch_cpu }; | ||
584 | 586 | ||
585 | /* Mask all interrupts */ | 587 | /* Mask all interrupts */ |
586 | local_irq_save(flags); | 588 | local_irq_save(flags); |
587 | if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0) | 589 | if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, (long)&nd, 0, 0) |
588 | == NOTIFY_STOP) | 590 | == NOTIFY_STOP) |
589 | ia64_mca_spin(__FUNCTION__); | 591 | ia64_mca_spin(__FUNCTION__); |
590 | 592 | ||
@@ -594,7 +596,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs) | |||
594 | */ | 596 | */ |
595 | ia64_sal_mc_rendez(); | 597 | ia64_sal_mc_rendez(); |
596 | 598 | ||
597 | if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0) | 599 | if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, (long)&nd, 0, 0) |
598 | == NOTIFY_STOP) | 600 | == NOTIFY_STOP) |
599 | ia64_mca_spin(__FUNCTION__); | 601 | ia64_mca_spin(__FUNCTION__); |
600 | 602 | ||
@@ -602,7 +604,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs) | |||
602 | while (monarch_cpu != -1) | 604 | while (monarch_cpu != -1) |
603 | cpu_relax(); /* spin until monarch leaves */ | 605 | cpu_relax(); /* spin until monarch leaves */ |
604 | 606 | ||
605 | if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0) | 607 | if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, (long)&nd, 0, 0) |
606 | == NOTIFY_STOP) | 608 | == NOTIFY_STOP) |
607 | ia64_mca_spin(__FUNCTION__); | 609 | ia64_mca_spin(__FUNCTION__); |
608 | 610 | ||
@@ -961,7 +963,7 @@ no_mod: | |||
961 | */ | 963 | */ |
962 | 964 | ||
963 | static void | 965 | static void |
964 | ia64_wait_for_slaves(int monarch) | 966 | ia64_wait_for_slaves(int monarch, const char *type) |
965 | { | 967 | { |
966 | int c, wait = 0, missing = 0; | 968 | int c, wait = 0, missing = 0; |
967 | for_each_online_cpu(c) { | 969 | for_each_online_cpu(c) { |
@@ -987,7 +989,7 @@ ia64_wait_for_slaves(int monarch) | |||
987 | } | 989 | } |
988 | if (!missing) | 990 | if (!missing) |
989 | goto all_in; | 991 | goto all_in; |
990 | printk(KERN_INFO "OS MCA slave did not rendezvous on cpu"); | 992 | printk(KERN_INFO "OS %s slave did not rendezvous on cpu", type); |
991 | for_each_online_cpu(c) { | 993 | for_each_online_cpu(c) { |
992 | if (c == monarch) | 994 | if (c == monarch) |
993 | continue; | 995 | continue; |
@@ -998,7 +1000,7 @@ ia64_wait_for_slaves(int monarch) | |||
998 | return; | 1000 | return; |
999 | 1001 | ||
1000 | all_in: | 1002 | all_in: |
1001 | printk(KERN_INFO "All OS MCA slaves have reached rendezvous\n"); | 1003 | printk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type); |
1002 | return; | 1004 | return; |
1003 | } | 1005 | } |
1004 | 1006 | ||
@@ -1023,6 +1025,8 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1023 | &sos->proc_state_param; | 1025 | &sos->proc_state_param; |
1024 | int recover, cpu = smp_processor_id(); | 1026 | int recover, cpu = smp_processor_id(); |
1025 | task_t *previous_current; | 1027 | task_t *previous_current; |
1028 | struct ia64_mca_notify_die nd = | ||
1029 | { .sos = sos, .monarch_cpu = &monarch_cpu }; | ||
1026 | 1030 | ||
1027 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ | 1031 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ |
1028 | console_loglevel = 15; /* make sure printks make it to console */ | 1032 | console_loglevel = 15; /* make sure printks make it to console */ |
@@ -1031,10 +1035,10 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1031 | 1035 | ||
1032 | previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); | 1036 | previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); |
1033 | monarch_cpu = cpu; | 1037 | monarch_cpu = cpu; |
1034 | if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0) | 1038 | if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0) |
1035 | == NOTIFY_STOP) | 1039 | == NOTIFY_STOP) |
1036 | ia64_mca_spin(__FUNCTION__); | 1040 | ia64_mca_spin(__FUNCTION__); |
1037 | ia64_wait_for_slaves(cpu); | 1041 | ia64_wait_for_slaves(cpu, "MCA"); |
1038 | 1042 | ||
1039 | /* Wakeup all the processors which are spinning in the rendezvous loop. | 1043 | /* Wakeup all the processors which are spinning in the rendezvous loop. |
1040 | * They will leave SAL, then spin in the OS with interrupts disabled | 1044 | * They will leave SAL, then spin in the OS with interrupts disabled |
@@ -1043,7 +1047,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1043 | * spinning in SAL does not work. | 1047 | * spinning in SAL does not work. |
1044 | */ | 1048 | */ |
1045 | ia64_mca_wakeup_all(); | 1049 | ia64_mca_wakeup_all(); |
1046 | if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0) | 1050 | if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, (long)&nd, 0, 0) |
1047 | == NOTIFY_STOP) | 1051 | == NOTIFY_STOP) |
1048 | ia64_mca_spin(__FUNCTION__); | 1052 | ia64_mca_spin(__FUNCTION__); |
1049 | 1053 | ||
@@ -1064,7 +1068,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1064 | ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); | 1068 | ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); |
1065 | sos->os_status = IA64_MCA_CORRECTED; | 1069 | sos->os_status = IA64_MCA_CORRECTED; |
1066 | } | 1070 | } |
1067 | if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover) | 1071 | if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover) |
1068 | == NOTIFY_STOP) | 1072 | == NOTIFY_STOP) |
1069 | ia64_mca_spin(__FUNCTION__); | 1073 | ia64_mca_spin(__FUNCTION__); |
1070 | 1074 | ||
@@ -1351,10 +1355,14 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1351 | static atomic_t monarchs; | 1355 | static atomic_t monarchs; |
1352 | task_t *previous_current; | 1356 | task_t *previous_current; |
1353 | int cpu = smp_processor_id(); | 1357 | int cpu = smp_processor_id(); |
1358 | struct ia64_mca_notify_die nd = | ||
1359 | { .sos = sos, .monarch_cpu = &monarch_cpu }; | ||
1354 | 1360 | ||
1355 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ | 1361 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ |
1356 | console_loglevel = 15; /* make sure printks make it to console */ | 1362 | console_loglevel = 15; /* make sure printks make it to console */ |
1357 | 1363 | ||
1364 | (void) notify_die(DIE_INIT_ENTER, "INIT", regs, (long)&nd, 0, 0); | ||
1365 | |||
1358 | printk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n", | 1366 | printk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n", |
1359 | sos->proc_state_param, cpu, sos->monarch); | 1367 | sos->proc_state_param, cpu, sos->monarch); |
1360 | salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0); | 1368 | salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0); |
@@ -1390,15 +1398,15 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1390 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; | 1398 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; |
1391 | while (monarch_cpu == -1) | 1399 | while (monarch_cpu == -1) |
1392 | cpu_relax(); /* spin until monarch enters */ | 1400 | cpu_relax(); /* spin until monarch enters */ |
1393 | if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0) | 1401 | if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, (long)&nd, 0, 0) |
1394 | == NOTIFY_STOP) | 1402 | == NOTIFY_STOP) |
1395 | ia64_mca_spin(__FUNCTION__); | 1403 | ia64_mca_spin(__FUNCTION__); |
1396 | if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0) | 1404 | if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, (long)&nd, 0, 0) |
1397 | == NOTIFY_STOP) | 1405 | == NOTIFY_STOP) |
1398 | ia64_mca_spin(__FUNCTION__); | 1406 | ia64_mca_spin(__FUNCTION__); |
1399 | while (monarch_cpu != -1) | 1407 | while (monarch_cpu != -1) |
1400 | cpu_relax(); /* spin until monarch leaves */ | 1408 | cpu_relax(); /* spin until monarch leaves */ |
1401 | if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0) | 1409 | if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, (long)&nd, 0, 0) |
1402 | == NOTIFY_STOP) | 1410 | == NOTIFY_STOP) |
1403 | ia64_mca_spin(__FUNCTION__); | 1411 | ia64_mca_spin(__FUNCTION__); |
1404 | printk("Slave on cpu %d returning to normal service.\n", cpu); | 1412 | printk("Slave on cpu %d returning to normal service.\n", cpu); |
@@ -1409,7 +1417,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1409 | } | 1417 | } |
1410 | 1418 | ||
1411 | monarch_cpu = cpu; | 1419 | monarch_cpu = cpu; |
1412 | if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0) | 1420 | if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, (long)&nd, 0, 0) |
1413 | == NOTIFY_STOP) | 1421 | == NOTIFY_STOP) |
1414 | ia64_mca_spin(__FUNCTION__); | 1422 | ia64_mca_spin(__FUNCTION__); |
1415 | 1423 | ||
@@ -1421,15 +1429,15 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1421 | */ | 1429 | */ |
1422 | printk("Delaying for 5 seconds...\n"); | 1430 | printk("Delaying for 5 seconds...\n"); |
1423 | udelay(5*1000000); | 1431 | udelay(5*1000000); |
1424 | ia64_wait_for_slaves(cpu); | 1432 | ia64_wait_for_slaves(cpu, "INIT"); |
1425 | /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through | 1433 | /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through |
1426 | * to default_monarch_init_process() above and just print all the | 1434 | * to default_monarch_init_process() above and just print all the |
1427 | * tasks. | 1435 | * tasks. |
1428 | */ | 1436 | */ |
1429 | if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0) | 1437 | if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, (long)&nd, 0, 0) |
1430 | == NOTIFY_STOP) | 1438 | == NOTIFY_STOP) |
1431 | ia64_mca_spin(__FUNCTION__); | 1439 | ia64_mca_spin(__FUNCTION__); |
1432 | if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0) | 1440 | if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, (long)&nd, 0, 0) |
1433 | == NOTIFY_STOP) | 1441 | == NOTIFY_STOP) |
1434 | ia64_mca_spin(__FUNCTION__); | 1442 | ia64_mca_spin(__FUNCTION__); |
1435 | printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); | 1443 | printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); |
@@ -1631,6 +1639,7 @@ ia64_mca_init(void) | |||
1631 | printk(KERN_INFO "Increasing MCA rendezvous timeout from " | 1639 | printk(KERN_INFO "Increasing MCA rendezvous timeout from " |
1632 | "%ld to %ld milliseconds\n", timeout, isrv.v0); | 1640 | "%ld to %ld milliseconds\n", timeout, isrv.v0); |
1633 | timeout = isrv.v0; | 1641 | timeout = isrv.v0; |
1642 | (void) notify_die(DIE_MCA_NEW_TIMEOUT, "MCA", NULL, timeout, 0, 0); | ||
1634 | continue; | 1643 | continue; |
1635 | } | 1644 | } |
1636 | printk(KERN_ERR "Failed to register rendezvous interrupt " | 1645 | printk(KERN_ERR "Failed to register rendezvous interrupt " |
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index 60a464bfd9e2..6dff024cd62b 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S | |||
@@ -827,7 +827,7 @@ ia64_state_restore: | |||
827 | ld8 r9=[temp2],16 // sal_gp | 827 | ld8 r9=[temp2],16 // sal_gp |
828 | ;; | 828 | ;; |
829 | ld8 r22=[temp1],16 // pal_min_state, virtual | 829 | ld8 r22=[temp1],16 // pal_min_state, virtual |
830 | ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT | 830 | ld8 r13=[temp2],16 // prev_IA64_KR_CURRENT |
831 | ;; | 831 | ;; |
832 | ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK | 832 | ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK |
833 | ld8 r20=[temp2],16 // prev_task | 833 | ld8 r20=[temp2],16 // prev_task |
@@ -848,7 +848,7 @@ ia64_state_restore: | |||
848 | mov cr.iim=temp3 | 848 | mov cr.iim=temp3 |
849 | mov cr.iha=temp4 | 849 | mov cr.iha=temp4 |
850 | dep r22=0,r22,62,1 // pal_min_state, physical, uncached | 850 | dep r22=0,r22,62,1 // pal_min_state, physical, uncached |
851 | mov IA64_KR(CURRENT)=r21 | 851 | mov IA64_KR(CURRENT)=r13 |
852 | ld8 r8=[temp1] // os_status | 852 | ld8 r8=[temp1] // os_status |
853 | ld8 r10=[temp2] // context | 853 | ld8 r10=[temp2] // context |
854 | 854 | ||
@@ -856,7 +856,7 @@ ia64_state_restore: | |||
856 | * avoid any dependencies on the algorithm in ia64_switch_to(), just | 856 | * avoid any dependencies on the algorithm in ia64_switch_to(), just |
857 | * purge any existing CURRENT_STACK mapping and insert the new one. | 857 | * purge any existing CURRENT_STACK mapping and insert the new one. |
858 | * | 858 | * |
859 | * r16 contains prev_IA64_KR_CURRENT_STACK, r21 contains | 859 | * r16 contains prev_IA64_KR_CURRENT_STACK, r13 contains |
860 | * prev_IA64_KR_CURRENT, these values may have been changed by the C | 860 | * prev_IA64_KR_CURRENT, these values may have been changed by the C |
861 | * code. Do not use r8, r9, r10, r22, they contain values ready for | 861 | * code. Do not use r8, r9, r10, r22, they contain values ready for |
862 | * the return to SAL. | 862 | * the return to SAL. |
@@ -873,7 +873,7 @@ ia64_state_restore: | |||
873 | ;; | 873 | ;; |
874 | srlz.d | 874 | srlz.d |
875 | 875 | ||
876 | extr.u r19=r21,61,3 // r21 = prev_IA64_KR_CURRENT | 876 | extr.u r19=r13,61,3 // r13 = prev_IA64_KR_CURRENT |
877 | shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK | 877 | shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK |
878 | movl r21=PAGE_KERNEL // page properties | 878 | movl r21=PAGE_KERNEL // page properties |
879 | ;; | 879 | ;; |
@@ -883,7 +883,7 @@ ia64_state_restore: | |||
883 | (p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:( | 883 | (p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:( |
884 | ;; | 884 | ;; |
885 | mov cr.itir=r18 | 885 | mov cr.itir=r18 |
886 | mov cr.ifa=r21 | 886 | mov cr.ifa=r13 |
887 | mov r20=IA64_TR_CURRENT_STACK | 887 | mov r20=IA64_TR_CURRENT_STACK |
888 | ;; | 888 | ;; |
889 | itr.d dtr[r20]=r21 | 889 | itr.d dtr[r20]=r21 |
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index 7a2f0a798d12..3a30cfc9574f 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c | |||
@@ -947,7 +947,7 @@ void | |||
947 | percpu_modcopy (void *pcpudst, const void *src, unsigned long size) | 947 | percpu_modcopy (void *pcpudst, const void *src, unsigned long size) |
948 | { | 948 | { |
949 | unsigned int i; | 949 | unsigned int i; |
950 | for_each_cpu(i) { | 950 | for_each_possible_cpu(i) { |
951 | memcpy(pcpudst + __per_cpu_offset[i], src, size); | 951 | memcpy(pcpudst + __per_cpu_offset[i], src, size); |
952 | } | 952 | } |
953 | } | 953 | } |
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index ec9eeb89975d..b6bcc9fa3603 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c | |||
@@ -519,6 +519,68 @@ void __cpuinit *per_cpu_init(void) | |||
519 | } | 519 | } |
520 | #endif /* CONFIG_SMP */ | 520 | #endif /* CONFIG_SMP */ |
521 | 521 | ||
522 | #ifdef CONFIG_VIRTUAL_MEM_MAP | ||
523 | static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i) | ||
524 | { | ||
525 | unsigned long end_address, hole_next_pfn; | ||
526 | unsigned long stop_address; | ||
527 | |||
528 | end_address = (unsigned long) &vmem_map[pgdat->node_start_pfn + i]; | ||
529 | end_address = PAGE_ALIGN(end_address); | ||
530 | |||
531 | stop_address = (unsigned long) &vmem_map[ | ||
532 | pgdat->node_start_pfn + pgdat->node_spanned_pages]; | ||
533 | |||
534 | do { | ||
535 | pgd_t *pgd; | ||
536 | pud_t *pud; | ||
537 | pmd_t *pmd; | ||
538 | pte_t *pte; | ||
539 | |||
540 | pgd = pgd_offset_k(end_address); | ||
541 | if (pgd_none(*pgd)) { | ||
542 | end_address += PGDIR_SIZE; | ||
543 | continue; | ||
544 | } | ||
545 | |||
546 | pud = pud_offset(pgd, end_address); | ||
547 | if (pud_none(*pud)) { | ||
548 | end_address += PUD_SIZE; | ||
549 | continue; | ||
550 | } | ||
551 | |||
552 | pmd = pmd_offset(pud, end_address); | ||
553 | if (pmd_none(*pmd)) { | ||
554 | end_address += PMD_SIZE; | ||
555 | continue; | ||
556 | } | ||
557 | |||
558 | pte = pte_offset_kernel(pmd, end_address); | ||
559 | retry_pte: | ||
560 | if (pte_none(*pte)) { | ||
561 | end_address += PAGE_SIZE; | ||
562 | pte++; | ||
563 | if ((end_address < stop_address) && | ||
564 | (end_address != ALIGN(end_address, 1UL << PMD_SHIFT))) | ||
565 | goto retry_pte; | ||
566 | continue; | ||
567 | } | ||
568 | /* Found next valid vmem_map page */ | ||
569 | break; | ||
570 | } while (end_address < stop_address); | ||
571 | |||
572 | end_address = min(end_address, stop_address); | ||
573 | end_address = end_address - (unsigned long) vmem_map + sizeof(struct page) - 1; | ||
574 | hole_next_pfn = end_address / sizeof(struct page); | ||
575 | return hole_next_pfn - pgdat->node_start_pfn; | ||
576 | } | ||
577 | #else | ||
578 | static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i) | ||
579 | { | ||
580 | return i + 1; | ||
581 | } | ||
582 | #endif | ||
583 | |||
522 | /** | 584 | /** |
523 | * show_mem - give short summary of memory stats | 585 | * show_mem - give short summary of memory stats |
524 | * | 586 | * |
@@ -547,8 +609,10 @@ void show_mem(void) | |||
547 | struct page *page; | 609 | struct page *page; |
548 | if (pfn_valid(pgdat->node_start_pfn + i)) | 610 | if (pfn_valid(pgdat->node_start_pfn + i)) |
549 | page = pfn_to_page(pgdat->node_start_pfn + i); | 611 | page = pfn_to_page(pgdat->node_start_pfn + i); |
550 | else | 612 | else { |
613 | i = find_next_valid_pfn_for_pgdat(pgdat, i) - 1; | ||
551 | continue; | 614 | continue; |
615 | } | ||
552 | if (PageReserved(page)) | 616 | if (PageReserved(page)) |
553 | reserved++; | 617 | reserved++; |
554 | else if (PageSwapCache(page)) | 618 | else if (PageSwapCache(page)) |
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index af7eb087dca7..d98ec49570b8 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c | |||
@@ -60,6 +60,9 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re | |||
60 | struct siginfo si; | 60 | struct siginfo si; |
61 | unsigned long mask; | 61 | unsigned long mask; |
62 | 62 | ||
63 | /* mmap_sem is performance critical.... */ | ||
64 | prefetchw(&mm->mmap_sem); | ||
65 | |||
63 | /* | 66 | /* |
64 | * If we're in an interrupt or have no user context, we must not take the fault.. | 67 | * If we're in an interrupt or have no user context, we must not take the fault.. |
65 | */ | 68 | */ |
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index d0abddd9ffe6..8255a9be4632 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c | |||
@@ -1831,7 +1831,7 @@ xpc_initiate_allocate(partid_t partid, int ch_number, u32 flags, void **payload) | |||
1831 | { | 1831 | { |
1832 | struct xpc_partition *part = &xpc_partitions[partid]; | 1832 | struct xpc_partition *part = &xpc_partitions[partid]; |
1833 | enum xpc_retval ret = xpcUnknownReason; | 1833 | enum xpc_retval ret = xpcUnknownReason; |
1834 | struct xpc_msg *msg; | 1834 | struct xpc_msg *msg = NULL; |
1835 | 1835 | ||
1836 | 1836 | ||
1837 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | 1837 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); |
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 05c864c6c2d9..41fd490af3b4 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig | |||
@@ -285,6 +285,11 @@ config NUMA | |||
285 | depends on SMP && BROKEN | 285 | depends on SMP && BROKEN |
286 | default n | 286 | default n |
287 | 287 | ||
288 | config NODES_SHIFT | ||
289 | int | ||
290 | default "1" | ||
291 | depends on NEED_MULTIPLE_NODES | ||
292 | |||
288 | # turning this on wastes a bunch of space. | 293 | # turning this on wastes a bunch of space. |
289 | # Summit needs it only when NUMA is on | 294 | # Summit needs it only when NUMA is on |
290 | config BOOT_IOREMAP | 295 | config BOOT_IOREMAP |
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index 3871b65f0c82..920bb742b7a2 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S | |||
@@ -20,7 +20,7 @@ | |||
20 | * Stack layout in 'ret_from_system_call': | 20 | * Stack layout in 'ret_from_system_call': |
21 | * ptrace needs to have all regs on the stack. | 21 | * ptrace needs to have all regs on the stack. |
22 | * if the order here is changed, it needs to be | 22 | * if the order here is changed, it needs to be |
23 | * updated in fork.c:copy_process, signal.c:do_signal, | 23 | * updated in fork.c:copy_thread, signal.c:do_signal, |
24 | * ptrace.c and ptrace.h | 24 | * ptrace.c and ptrace.h |
25 | * | 25 | * |
26 | * M32Rx/M32R2 M32R | 26 | * M32Rx/M32R2 M32R |
@@ -41,18 +41,17 @@ | |||
41 | * @(0x38,sp) - syscall_nr ditto | 41 | * @(0x38,sp) - syscall_nr ditto |
42 | * @(0x3c,sp) - acc0h @(0x3c,sp) - acch | 42 | * @(0x3c,sp) - acc0h @(0x3c,sp) - acch |
43 | * @(0x40,sp) - acc0l @(0x40,sp) - accl | 43 | * @(0x40,sp) - acc0l @(0x40,sp) - accl |
44 | * @(0x44,sp) - acc1h @(0x44,sp) - psw | 44 | * @(0x44,sp) - acc1h @(0x44,sp) - dummy_acc1h |
45 | * @(0x48,sp) - acc1l @(0x48,sp) - bpc | 45 | * @(0x48,sp) - acc1l @(0x48,sp) - dummy_acc1l |
46 | * @(0x4c,sp) - psw @(0x4c,sp) - bbpsw | 46 | * @(0x4c,sp) - psw ditto |
47 | * @(0x50,sp) - bpc @(0x50,sp) - bbpc | 47 | * @(0x50,sp) - bpc ditto |
48 | * @(0x54,sp) - bbpsw @(0x54,sp) - spu (cr3) | 48 | * @(0x54,sp) - bbpsw ditto |
49 | * @(0x58,sp) - bbpc @(0x58,sp) - fp (r13) | 49 | * @(0x58,sp) - bbpc ditto |
50 | * @(0x5c,sp) - spu (cr3) @(0x5c,sp) - lr (r14) | 50 | * @(0x5c,sp) - spu (cr3) ditto |
51 | * @(0x60,sp) - fp (r13) @(0x60,sp) - spi (cr12) | 51 | * @(0x60,sp) - fp (r13) ditto |
52 | * @(0x64,sp) - lr (r14) @(0x64,sp) - orig_r0 | 52 | * @(0x64,sp) - lr (r14) ditto |
53 | * @(0x68,sp) - spi (cr2) | 53 | * @(0x68,sp) - spi (cr2) ditto |
54 | * @(0x6c,sp) - orig_r0 | 54 | * @(0x6c,sp) - orig_r0 ditto |
55 | * | ||
56 | */ | 55 | */ |
57 | 56 | ||
58 | #include <linux/config.h> | 57 | #include <linux/config.h> |
@@ -102,6 +101,12 @@ | |||
102 | #define ACC0L(reg) @(0x40,reg) | 101 | #define ACC0L(reg) @(0x40,reg) |
103 | #define ACC1H(reg) @(0x44,reg) | 102 | #define ACC1H(reg) @(0x44,reg) |
104 | #define ACC1L(reg) @(0x48,reg) | 103 | #define ACC1L(reg) @(0x48,reg) |
104 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | ||
105 | #define ACCH(reg) @(0x3C,reg) | ||
106 | #define ACCL(reg) @(0x40,reg) | ||
107 | #else | ||
108 | #error unknown isa configuration | ||
109 | #endif | ||
105 | #define PSW(reg) @(0x4C,reg) | 110 | #define PSW(reg) @(0x4C,reg) |
106 | #define BPC(reg) @(0x50,reg) | 111 | #define BPC(reg) @(0x50,reg) |
107 | #define BBPSW(reg) @(0x54,reg) | 112 | #define BBPSW(reg) @(0x54,reg) |
@@ -111,21 +116,6 @@ | |||
111 | #define LR(reg) @(0x64,reg) | 116 | #define LR(reg) @(0x64,reg) |
112 | #define SP(reg) @(0x68,reg) | 117 | #define SP(reg) @(0x68,reg) |
113 | #define ORIG_R0(reg) @(0x6C,reg) | 118 | #define ORIG_R0(reg) @(0x6C,reg) |
114 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | ||
115 | #define ACCH(reg) @(0x3C,reg) | ||
116 | #define ACCL(reg) @(0x40,reg) | ||
117 | #define PSW(reg) @(0x44,reg) | ||
118 | #define BPC(reg) @(0x48,reg) | ||
119 | #define BBPSW(reg) @(0x4C,reg) | ||
120 | #define BBPC(reg) @(0x50,reg) | ||
121 | #define SPU(reg) @(0x54,reg) | ||
122 | #define FP(reg) @(0x58,reg) /* FP = R13 */ | ||
123 | #define LR(reg) @(0x5C,reg) | ||
124 | #define SP(reg) @(0x60,reg) | ||
125 | #define ORIG_R0(reg) @(0x64,reg) | ||
126 | #else | ||
127 | #error unknown isa configuration | ||
128 | #endif | ||
129 | 119 | ||
130 | CF_MASK = 0x00000001 | 120 | CF_MASK = 0x00000001 |
131 | TF_MASK = 0x00000100 | 121 | TF_MASK = 0x00000100 |
@@ -142,7 +132,7 @@ VM_MASK = 0x00020000 | |||
142 | #endif | 132 | #endif |
143 | 133 | ||
144 | ENTRY(ret_from_fork) | 134 | ENTRY(ret_from_fork) |
145 | ld r0, @sp+ | 135 | pop r0 |
146 | bl schedule_tail | 136 | bl schedule_tail |
147 | GET_THREAD_INFO(r8) | 137 | GET_THREAD_INFO(r8) |
148 | bra syscall_exit | 138 | bra syscall_exit |
@@ -231,7 +221,7 @@ restore_all: | |||
231 | RESTORE_ALL | 221 | RESTORE_ALL |
232 | 222 | ||
233 | # perform work that needs to be done immediately before resumption | 223 | # perform work that needs to be done immediately before resumption |
234 | # r9 : frags | 224 | # r9 : flags |
235 | ALIGN | 225 | ALIGN |
236 | work_pending: | 226 | work_pending: |
237 | and3 r4, r9, #_TIF_NEED_RESCHED | 227 | and3 r4, r9, #_TIF_NEED_RESCHED |
@@ -320,7 +310,7 @@ ENTRY(ei_handler) | |||
320 | ; GET_ICU_STATUS; | 310 | ; GET_ICU_STATUS; |
321 | seth r0, #shigh(M32R_ICU_ISTS_ADDR) | 311 | seth r0, #shigh(M32R_ICU_ISTS_ADDR) |
322 | ld r0, @(low(M32R_ICU_ISTS_ADDR),r0) | 312 | ld r0, @(low(M32R_ICU_ISTS_ADDR),r0) |
323 | st r0, @-sp | 313 | push r0 |
324 | #if defined(CONFIG_SMP) | 314 | #if defined(CONFIG_SMP) |
325 | /* | 315 | /* |
326 | * If IRQ == 0 --> Nothing to do, Not write IMASK | 316 | * If IRQ == 0 --> Nothing to do, Not write IMASK |
@@ -557,7 +547,7 @@ check_end: | |||
557 | #endif /* CONFIG_PLAT_M32104UT */ | 547 | #endif /* CONFIG_PLAT_M32104UT */ |
558 | bl do_IRQ | 548 | bl do_IRQ |
559 | #endif /* CONFIG_SMP */ | 549 | #endif /* CONFIG_SMP */ |
560 | ld r14, @sp+ | 550 | pop r14 |
561 | seth r0, #shigh(M32R_ICU_IMASK_ADDR) | 551 | seth r0, #shigh(M32R_ICU_IMASK_ADDR) |
562 | st r14, @(low(M32R_ICU_IMASK_ADDR),r0) | 552 | st r14, @(low(M32R_ICU_IMASK_ADDR),r0) |
563 | #else | 553 | #else |
@@ -1015,4 +1005,3 @@ ENTRY(sys_call_table) | |||
1015 | .long sys_waitid | 1005 | .long sys_waitid |
1016 | 1006 | ||
1017 | syscall_table_size=(.-sys_call_table) | 1007 | syscall_table_size=(.-sys_call_table) |
1018 | |||
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c index be8b711367ec..c50330fa83b9 100644 --- a/arch/m32r/kernel/m32r_ksyms.c +++ b/arch/m32r/kernel/m32r_ksyms.c | |||
@@ -23,9 +23,6 @@ EXPORT_SYMBOL(boot_cpu_data); | |||
23 | EXPORT_SYMBOL(dump_fpu); | 23 | EXPORT_SYMBOL(dump_fpu); |
24 | EXPORT_SYMBOL(__ioremap); | 24 | EXPORT_SYMBOL(__ioremap); |
25 | EXPORT_SYMBOL(iounmap); | 25 | EXPORT_SYMBOL(iounmap); |
26 | EXPORT_SYMBOL(enable_irq); | ||
27 | EXPORT_SYMBOL(disable_irq); | ||
28 | EXPORT_SYMBOL(disable_irq_nosync); | ||
29 | EXPORT_SYMBOL(kernel_thread); | 26 | EXPORT_SYMBOL(kernel_thread); |
30 | EXPORT_SYMBOL(__down); | 27 | EXPORT_SYMBOL(__down); |
31 | EXPORT_SYMBOL(__down_interruptible); | 28 | EXPORT_SYMBOL(__down_interruptible); |
@@ -38,13 +35,6 @@ EXPORT_SYMBOL(__udelay); | |||
38 | EXPORT_SYMBOL(__delay); | 35 | EXPORT_SYMBOL(__delay); |
39 | EXPORT_SYMBOL(__const_udelay); | 36 | EXPORT_SYMBOL(__const_udelay); |
40 | 37 | ||
41 | EXPORT_SYMBOL(__get_user_1); | ||
42 | EXPORT_SYMBOL(__get_user_2); | ||
43 | EXPORT_SYMBOL(__get_user_4); | ||
44 | |||
45 | EXPORT_SYMBOL(strpbrk); | ||
46 | EXPORT_SYMBOL(strstr); | ||
47 | |||
48 | EXPORT_SYMBOL(strncpy_from_user); | 38 | EXPORT_SYMBOL(strncpy_from_user); |
49 | EXPORT_SYMBOL(__strncpy_from_user); | 39 | EXPORT_SYMBOL(__strncpy_from_user); |
50 | EXPORT_SYMBOL(clear_user); | 40 | EXPORT_SYMBOL(clear_user); |
@@ -59,11 +49,8 @@ extern void *dcache_dummy; | |||
59 | EXPORT_SYMBOL(dcache_dummy); | 49 | EXPORT_SYMBOL(dcache_dummy); |
60 | #endif | 50 | #endif |
61 | EXPORT_SYMBOL(cpu_data); | 51 | EXPORT_SYMBOL(cpu_data); |
62 | EXPORT_SYMBOL(cpu_online_map); | ||
63 | EXPORT_SYMBOL(cpu_callout_map); | ||
64 | 52 | ||
65 | /* Global SMP stuff */ | 53 | /* Global SMP stuff */ |
66 | EXPORT_SYMBOL(synchronize_irq); | ||
67 | EXPORT_SYMBOL(smp_call_function); | 54 | EXPORT_SYMBOL(smp_call_function); |
68 | 55 | ||
69 | /* TLB flushing */ | 56 | /* TLB flushing */ |
@@ -83,27 +70,11 @@ EXPORT_SYMBOL(__lshrdi3); | |||
83 | EXPORT_SYMBOL(__muldi3); | 70 | EXPORT_SYMBOL(__muldi3); |
84 | 71 | ||
85 | /* memory and string operations */ | 72 | /* memory and string operations */ |
86 | EXPORT_SYMBOL(memchr); | ||
87 | EXPORT_SYMBOL(memcpy); | 73 | EXPORT_SYMBOL(memcpy); |
88 | /* EXPORT_SYMBOL(memcpy_fromio); // not implement yet */ | ||
89 | /* EXPORT_SYMBOL(memcpy_toio); // not implement yet */ | ||
90 | EXPORT_SYMBOL(memset); | 74 | EXPORT_SYMBOL(memset); |
91 | /* EXPORT_SYMBOL(memset_io); // not implement yet */ | ||
92 | EXPORT_SYMBOL(memmove); | ||
93 | EXPORT_SYMBOL(memcmp); | ||
94 | EXPORT_SYMBOL(memscan); | ||
95 | EXPORT_SYMBOL(copy_page); | 75 | EXPORT_SYMBOL(copy_page); |
96 | EXPORT_SYMBOL(clear_page); | 76 | EXPORT_SYMBOL(clear_page); |
97 | |||
98 | EXPORT_SYMBOL(strcat); | ||
99 | EXPORT_SYMBOL(strchr); | ||
100 | EXPORT_SYMBOL(strcmp); | ||
101 | EXPORT_SYMBOL(strcpy); | ||
102 | EXPORT_SYMBOL(strlen); | 77 | EXPORT_SYMBOL(strlen); |
103 | EXPORT_SYMBOL(strncat); | ||
104 | EXPORT_SYMBOL(strncmp); | ||
105 | EXPORT_SYMBOL(strnlen); | ||
106 | EXPORT_SYMBOL(strncpy); | ||
107 | 78 | ||
108 | EXPORT_SYMBOL(_inb); | 79 | EXPORT_SYMBOL(_inb); |
109 | EXPORT_SYMBOL(_inw); | 80 | EXPORT_SYMBOL(_inw); |
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index 5dfc7ea45cf7..065f5e719058 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c | |||
@@ -116,6 +116,10 @@ void cpu_idle (void) | |||
116 | 116 | ||
117 | void machine_restart(char *__unused) | 117 | void machine_restart(char *__unused) |
118 | { | 118 | { |
119 | #if defined(CONFIG_PLAT_MAPPI3) | ||
120 | outw(1, (unsigned long)PLD_REBOOT); | ||
121 | #endif | ||
122 | |||
119 | printk("Please push reset button!\n"); | 123 | printk("Please push reset button!\n"); |
120 | while (1) | 124 | while (1) |
121 | cpu_relax(); | 125 | cpu_relax(); |
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index 0d78942b4c76..3cd3c2988a48 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/kernel.h> | ||
12 | #include <linux/stddef.h> | 13 | #include <linux/stddef.h> |
13 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
14 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
@@ -219,8 +220,6 @@ static unsigned long __init setup_memory(void) | |||
219 | extern unsigned long setup_memory(void); | 220 | extern unsigned long setup_memory(void); |
220 | #endif /* CONFIG_DISCONTIGMEM */ | 221 | #endif /* CONFIG_DISCONTIGMEM */ |
221 | 222 | ||
222 | #define M32R_PCC_PCATCR 0x00ef7014 /* will move to m32r.h */ | ||
223 | |||
224 | void __init setup_arch(char **cmdline_p) | 223 | void __init setup_arch(char **cmdline_p) |
225 | { | 224 | { |
226 | ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); | 225 | ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); |
@@ -269,15 +268,14 @@ void __init setup_arch(char **cmdline_p) | |||
269 | paging_init(); | 268 | paging_init(); |
270 | } | 269 | } |
271 | 270 | ||
272 | static struct cpu cpu[NR_CPUS]; | 271 | static struct cpu cpu_devices[NR_CPUS]; |
273 | 272 | ||
274 | static int __init topology_init(void) | 273 | static int __init topology_init(void) |
275 | { | 274 | { |
276 | int cpu_id; | 275 | int i; |
277 | 276 | ||
278 | for (cpu_id = 0; cpu_id < NR_CPUS; cpu_id++) | 277 | for_each_present_cpu(i) |
279 | if (cpu_possible(cpu_id)) | 278 | register_cpu(&cpu_devices[i], i, NULL); |
280 | register_cpu(&cpu[cpu_id], cpu_id, NULL); | ||
281 | 279 | ||
282 | return 0; | 280 | return 0; |
283 | } | 281 | } |
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index cb33097fefc4..6498ee70bb73 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
@@ -118,6 +118,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, | |||
118 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | 118 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) |
119 | COPY(acch); | 119 | COPY(acch); |
120 | COPY(accl); | 120 | COPY(accl); |
121 | COPY(dummy_acc1h); | ||
122 | COPY(dummy_acc1l); | ||
121 | #else | 123 | #else |
122 | #error unknown isa configuration | 124 | #error unknown isa configuration |
123 | #endif | 125 | #endif |
@@ -203,6 +205,8 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
203 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | 205 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) |
204 | COPY(acch); | 206 | COPY(acch); |
205 | COPY(accl); | 207 | COPY(accl); |
208 | COPY(dummy_acc1h); | ||
209 | COPY(dummy_acc1l); | ||
206 | #else | 210 | #else |
207 | #error unknown isa configuration | 211 | #error unknown isa configuration |
208 | #endif | 212 | #endif |
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c index d7ec16e7fb25..840b4348bf0c 100644 --- a/arch/m32r/kernel/smpboot.c +++ b/arch/m32r/kernel/smpboot.c | |||
@@ -39,8 +39,10 @@ | |||
39 | * Martin J. Bligh : Added support for multi-quad systems | 39 | * Martin J. Bligh : Added support for multi-quad systems |
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include <linux/module.h> | ||
42 | #include <linux/config.h> | 43 | #include <linux/config.h> |
43 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/kernel.h> | ||
44 | #include <linux/mm.h> | 46 | #include <linux/mm.h> |
45 | #include <linux/smp_lock.h> | 47 | #include <linux/smp_lock.h> |
46 | #include <linux/irq.h> | 48 | #include <linux/irq.h> |
@@ -72,11 +74,15 @@ physid_mask_t phys_cpu_present_map; | |||
72 | 74 | ||
73 | /* Bitmask of currently online CPUs */ | 75 | /* Bitmask of currently online CPUs */ |
74 | cpumask_t cpu_online_map; | 76 | cpumask_t cpu_online_map; |
77 | EXPORT_SYMBOL(cpu_online_map); | ||
75 | 78 | ||
76 | cpumask_t cpu_bootout_map; | 79 | cpumask_t cpu_bootout_map; |
77 | cpumask_t cpu_bootin_map; | 80 | cpumask_t cpu_bootin_map; |
78 | cpumask_t cpu_callout_map; | ||
79 | static cpumask_t cpu_callin_map; | 81 | static cpumask_t cpu_callin_map; |
82 | cpumask_t cpu_callout_map; | ||
83 | EXPORT_SYMBOL(cpu_callout_map); | ||
84 | cpumask_t cpu_possible_map = CPU_MASK_ALL; | ||
85 | EXPORT_SYMBOL(cpu_possible_map); | ||
80 | 86 | ||
81 | /* Per CPU bogomips and other parameters */ | 87 | /* Per CPU bogomips and other parameters */ |
82 | struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned; | 88 | struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned; |
@@ -110,7 +116,6 @@ static unsigned int calibration_result; | |||
110 | 116 | ||
111 | void smp_prepare_boot_cpu(void); | 117 | void smp_prepare_boot_cpu(void); |
112 | void smp_prepare_cpus(unsigned int); | 118 | void smp_prepare_cpus(unsigned int); |
113 | static void smp_tune_scheduling(void); | ||
114 | static void init_ipi_lock(void); | 119 | static void init_ipi_lock(void); |
115 | static void do_boot_cpu(int); | 120 | static void do_boot_cpu(int); |
116 | int __cpu_up(unsigned int); | 121 | int __cpu_up(unsigned int); |
@@ -177,6 +182,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
177 | } | 182 | } |
178 | for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++) | 183 | for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++) |
179 | physid_set(phys_id, phys_cpu_present_map); | 184 | physid_set(phys_id, phys_cpu_present_map); |
185 | #ifndef CONFIG_HOTPLUG_CPU | ||
186 | cpu_present_map = cpu_possible_map; | ||
187 | #endif | ||
180 | 188 | ||
181 | show_mp_info(nr_cpu); | 189 | show_mp_info(nr_cpu); |
182 | 190 | ||
@@ -186,7 +194,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
186 | * Setup boot CPU information | 194 | * Setup boot CPU information |
187 | */ | 195 | */ |
188 | smp_store_cpu_info(0); /* Final full version of the data */ | 196 | smp_store_cpu_info(0); /* Final full version of the data */ |
189 | smp_tune_scheduling(); | ||
190 | 197 | ||
191 | /* | 198 | /* |
192 | * If SMP should be disabled, then really disable it! | 199 | * If SMP should be disabled, then really disable it! |
@@ -230,11 +237,6 @@ smp_done: | |||
230 | Dprintk("Boot done.\n"); | 237 | Dprintk("Boot done.\n"); |
231 | } | 238 | } |
232 | 239 | ||
233 | static void __init smp_tune_scheduling(void) | ||
234 | { | ||
235 | /* Nothing to do. */ | ||
236 | } | ||
237 | |||
238 | /* | 240 | /* |
239 | * init_ipi_lock : Initialize IPI locks. | 241 | * init_ipi_lock : Initialize IPI locks. |
240 | */ | 242 | */ |
@@ -629,4 +631,3 @@ static void __init unmap_cpu_to_physid(int cpu_id, int phys_id) | |||
629 | physid_2_cpu[phys_id] = -1; | 631 | physid_2_cpu[phys_id] = -1; |
630 | cpu_2_physid[cpu_id] = -1; | 632 | cpu_2_physid[cpu_id] = -1; |
631 | } | 633 | } |
632 | |||
diff --git a/arch/m32r/lib/Makefile b/arch/m32r/lib/Makefile index e632d10c7d78..d16b4e40d1ae 100644 --- a/arch/m32r/lib/Makefile +++ b/arch/m32r/lib/Makefile | |||
@@ -2,6 +2,6 @@ | |||
2 | # Makefile for M32R-specific library files.. | 2 | # Makefile for M32R-specific library files.. |
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y := checksum.o ashxdi3.o memset.o memcpy.o getuser.o \ | 5 | lib-y := checksum.o ashxdi3.o memset.o memcpy.o \ |
6 | putuser.o delay.o strlen.o usercopy.o csum_partial_copy.o | 6 | delay.o strlen.o usercopy.o csum_partial_copy.o |
7 | 7 | ||
diff --git a/arch/m32r/lib/getuser.S b/arch/m32r/lib/getuser.S deleted file mode 100644 index 58a0db055c5c..000000000000 --- a/arch/m32r/lib/getuser.S +++ /dev/null | |||
@@ -1,88 +0,0 @@ | |||
1 | /* | ||
2 | * __get_user functions. | ||
3 | * | ||
4 | * (C) Copyright 2001 Hirokazu Takata | ||
5 | * | ||
6 | * These functions have a non-standard call interface | ||
7 | * to make them more efficient, especially as they | ||
8 | * return an error value in addition to the "real" | ||
9 | * return value. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | |||
14 | /* | ||
15 | * __get_user_X | ||
16 | * | ||
17 | * Inputs: r0 contains the address | ||
18 | * | ||
19 | * Outputs: r0 is error code (0 or -EFAULT) | ||
20 | * r1 contains zero-extended value | ||
21 | * | ||
22 | * These functions should not modify any other registers, | ||
23 | * as they get called from within inline assembly. | ||
24 | */ | ||
25 | |||
26 | #ifdef CONFIG_ISA_DUAL_ISSUE | ||
27 | |||
28 | .text | ||
29 | .balign 4 | ||
30 | .globl __get_user_1 | ||
31 | __get_user_1: | ||
32 | 1: ldub r1, @r0 || ldi r0, #0 | ||
33 | jmp r14 | ||
34 | |||
35 | .balign 4 | ||
36 | .globl __get_user_2 | ||
37 | __get_user_2: | ||
38 | 2: lduh r1, @r0 || ldi r0, #0 | ||
39 | jmp r14 | ||
40 | |||
41 | .balign 4 | ||
42 | .globl __get_user_4 | ||
43 | __get_user_4: | ||
44 | 3: ld r1, @r0 || ldi r0, #0 | ||
45 | jmp r14 | ||
46 | |||
47 | bad_get_user: | ||
48 | ldi r1, #0 || ldi r0, #-14 | ||
49 | jmp r14 | ||
50 | |||
51 | #else /* not CONFIG_ISA_DUAL_ISSUE */ | ||
52 | |||
53 | .text | ||
54 | .balign 4 | ||
55 | .globl __get_user_1 | ||
56 | __get_user_1: | ||
57 | 1: ldub r1, @r0 | ||
58 | ldi r0, #0 | ||
59 | jmp r14 | ||
60 | |||
61 | .balign 4 | ||
62 | .globl __get_user_2 | ||
63 | __get_user_2: | ||
64 | 2: lduh r1, @r0 | ||
65 | ldi r0, #0 | ||
66 | jmp r14 | ||
67 | |||
68 | .balign 4 | ||
69 | .globl __get_user_4 | ||
70 | __get_user_4: | ||
71 | 3: ld r1, @r0 | ||
72 | ldi r0, #0 | ||
73 | jmp r14 | ||
74 | |||
75 | bad_get_user: | ||
76 | ldi r1, #0 | ||
77 | ldi r0, #-14 | ||
78 | jmp r14 | ||
79 | |||
80 | #endif /* not CONFIG_ISA_DUAL_ISSUE */ | ||
81 | |||
82 | .section __ex_table,"a" | ||
83 | .long 1b,bad_get_user | ||
84 | .long 2b,bad_get_user | ||
85 | .long 3b,bad_get_user | ||
86 | .previous | ||
87 | |||
88 | .end | ||
diff --git a/arch/m32r/lib/putuser.S b/arch/m32r/lib/putuser.S deleted file mode 100644 index 218154cc3890..000000000000 --- a/arch/m32r/lib/putuser.S +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | /* | ||
2 | * __put_user functions. | ||
3 | * | ||
4 | * (C) Copyright 1998 Linus Torvalds | ||
5 | * (C) Copyright 2001 Hirokazu Takata | ||
6 | * | ||
7 | * These functions have a non-standard call interface | ||
8 | * to make them more efficient. | ||
9 | */ | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | |||
13 | /* | ||
14 | * __put_user_X | ||
15 | * | ||
16 | * Inputs: r0 contains the address | ||
17 | * r1 contains the value | ||
18 | * | ||
19 | * Outputs: r0 is error code (0 or -EFAULT) | ||
20 | * r1 is corrupted (will contain "current_task"). | ||
21 | * | ||
22 | * These functions should not modify any other registers, | ||
23 | * as they get called from within inline assembly. | ||
24 | */ | ||
25 | |||
26 | #ifdef CONFIG_ISA_DUAL_ISSUE | ||
27 | |||
28 | .text | ||
29 | .balign 4 | ||
30 | .globl __put_user_1 | ||
31 | __put_user_1: | ||
32 | 1: stb r1, @r0 || ldi r0, #0 | ||
33 | jmp r14 | ||
34 | |||
35 | .balign 4 | ||
36 | .globl __put_user_2 | ||
37 | __put_user_2: | ||
38 | 2: sth r1, @r0 || ldi r0, #0 | ||
39 | jmp r14 | ||
40 | |||
41 | .balign 4 | ||
42 | .globl __put_user_4 | ||
43 | __put_user_4: | ||
44 | 3: st r1, @r0 || ldi r0, #0 | ||
45 | jmp r14 | ||
46 | |||
47 | bad_put_user: | ||
48 | ldi r0, #-14 || jmp r14 | ||
49 | |||
50 | #else /* not CONFIG_ISA_DUAL_ISSUE */ | ||
51 | |||
52 | .text | ||
53 | .balign 4 | ||
54 | .globl __put_user_1 | ||
55 | __put_user_1: | ||
56 | 1: stb r1, @r0 | ||
57 | ldi r0, #0 | ||
58 | jmp r14 | ||
59 | |||
60 | .balign 4 | ||
61 | .globl __put_user_2 | ||
62 | __put_user_2: | ||
63 | 2: sth r1, @r0 | ||
64 | ldi r0, #0 | ||
65 | jmp r14 | ||
66 | |||
67 | .balign 4 | ||
68 | .globl __put_user_4 | ||
69 | __put_user_4: | ||
70 | 3: st r1, @r0 | ||
71 | ldi r0, #0 | ||
72 | jmp r14 | ||
73 | |||
74 | bad_put_user: | ||
75 | ldi r0, #-14 | ||
76 | jmp r14 | ||
77 | |||
78 | #endif /* not CONFIG_ISA_DUAL_ISSUE */ | ||
79 | |||
80 | .section __ex_table,"a" | ||
81 | .long 1b,bad_put_user | ||
82 | .long 2b,bad_put_user | ||
83 | .long 3b,bad_put_user | ||
84 | .previous | ||
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c index c3319514a85e..5b7952ea2bae 100644 --- a/arch/m68k/kernel/m68k_ksyms.c +++ b/arch/m68k/kernel/m68k_ksyms.c | |||
@@ -57,7 +57,6 @@ EXPORT_SYMBOL(dump_thread); | |||
57 | EXPORT_SYMBOL(strnlen); | 57 | EXPORT_SYMBOL(strnlen); |
58 | EXPORT_SYMBOL(strrchr); | 58 | EXPORT_SYMBOL(strrchr); |
59 | EXPORT_SYMBOL(strstr); | 59 | EXPORT_SYMBOL(strstr); |
60 | EXPORT_SYMBOL(strpbrk); | ||
61 | EXPORT_SYMBOL(enable_irq); | 60 | EXPORT_SYMBOL(enable_irq); |
62 | EXPORT_SYMBOL(disable_irq); | 61 | EXPORT_SYMBOL(disable_irq); |
63 | EXPORT_SYMBOL(kernel_thread); | 62 | EXPORT_SYMBOL(kernel_thread); |
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c index f9b4ea16c099..4320d5dcc9cb 100644 --- a/arch/m68knommu/kernel/m68k_ksyms.c +++ b/arch/m68knommu/kernel/m68k_ksyms.c | |||
@@ -26,7 +26,6 @@ EXPORT_SYMBOL(__ioremap); | |||
26 | EXPORT_SYMBOL(iounmap); | 26 | EXPORT_SYMBOL(iounmap); |
27 | EXPORT_SYMBOL(dump_fpu); | 27 | EXPORT_SYMBOL(dump_fpu); |
28 | EXPORT_SYMBOL(strnlen); | 28 | EXPORT_SYMBOL(strnlen); |
29 | EXPORT_SYMBOL(strpbrk); | ||
30 | EXPORT_SYMBOL(strrchr); | 29 | EXPORT_SYMBOL(strrchr); |
31 | EXPORT_SYMBOL(strstr); | 30 | EXPORT_SYMBOL(strstr); |
32 | EXPORT_SYMBOL(strchr); | 31 | EXPORT_SYMBOL(strchr); |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e15709ce8866..87f0b79c6b15 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -816,6 +816,10 @@ config GENERIC_CALIBRATE_DELAY | |||
816 | bool | 816 | bool |
817 | default y | 817 | default y |
818 | 818 | ||
819 | config SCHED_NO_NO_OMIT_FRAME_POINTER | ||
820 | bool | ||
821 | default y | ||
822 | |||
819 | # | 823 | # |
820 | # Select some configuration options automatically based on user selections. | 824 | # Select some configuration options automatically based on user selections. |
821 | # | 825 | # |
@@ -1443,6 +1447,10 @@ choice | |||
1443 | prompt "MIPS MT options" | 1447 | prompt "MIPS MT options" |
1444 | depends on MIPS_MT | 1448 | depends on MIPS_MT |
1445 | 1449 | ||
1450 | config MIPS_MT_SMTC | ||
1451 | bool "SMTC: Use all TCs on all VPEs for SMP" | ||
1452 | select SMP | ||
1453 | |||
1446 | config MIPS_MT_SMP | 1454 | config MIPS_MT_SMP |
1447 | bool "Use 1 TC on each available VPE for SMP" | 1455 | bool "Use 1 TC on each available VPE for SMP" |
1448 | select SMP | 1456 | select SMP |
@@ -1456,6 +1464,11 @@ config MIPS_VPE_LOADER | |||
1456 | 1464 | ||
1457 | endchoice | 1465 | endchoice |
1458 | 1466 | ||
1467 | config MIPS_MT_FPAFF | ||
1468 | bool "Dynamic FPU affinity for FP-intensive threads" | ||
1469 | depends on MIPS_MT | ||
1470 | default y | ||
1471 | |||
1459 | config MIPS_VPE_LOADER_TOM | 1472 | config MIPS_VPE_LOADER_TOM |
1460 | bool "Load VPE program into memory hidden from linux" | 1473 | bool "Load VPE program into memory hidden from linux" |
1461 | depends on MIPS_VPE_LOADER | 1474 | depends on MIPS_VPE_LOADER |
@@ -1472,6 +1485,16 @@ config MIPS_VPE_APSP_API | |||
1472 | depends on MIPS_VPE_LOADER | 1485 | depends on MIPS_VPE_LOADER |
1473 | help | 1486 | help |
1474 | 1487 | ||
1488 | config MIPS_APSP_KSPD | ||
1489 | bool "Enable KSPD" | ||
1490 | depends on MIPS_VPE_APSP_API | ||
1491 | default y | ||
1492 | help | ||
1493 | KSPD is a kernel daemon that accepts syscall requests from the SP | ||
1494 | side, actions them and returns the results. It also handles the | ||
1495 | "exit" syscall notifying other kernel modules the SP program is | ||
1496 | exiting. You probably want to say yes here. | ||
1497 | |||
1475 | config SB1_PASS_1_WORKAROUNDS | 1498 | config SB1_PASS_1_WORKAROUNDS |
1476 | bool | 1499 | bool |
1477 | depends on CPU_SB1_PASS_1 | 1500 | depends on CPU_SB1_PASS_1 |
@@ -1590,11 +1613,16 @@ config ARCH_FLATMEM_ENABLE | |||
1590 | def_bool y | 1613 | def_bool y |
1591 | depends on !NUMA | 1614 | depends on !NUMA |
1592 | 1615 | ||
1616 | config NODES_SHIFT | ||
1617 | int | ||
1618 | default "6" | ||
1619 | depends on NEED_MULTIPLE_NODES | ||
1620 | |||
1593 | source "mm/Kconfig" | 1621 | source "mm/Kconfig" |
1594 | 1622 | ||
1595 | config SMP | 1623 | config SMP |
1596 | bool "Multi-Processing support" | 1624 | bool "Multi-Processing support" |
1597 | depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250 || QEMU) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP | 1625 | depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250 || QEMU) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP || MIPS_MT_SMTC |
1598 | ---help--- | 1626 | ---help--- |
1599 | This enables support for systems with more than one CPU. If you have | 1627 | This enables support for systems with more than one CPU. If you have |
1600 | a system with only one CPU, like most personal computers, say N. If | 1628 | a system with only one CPU, like most personal computers, say N. If |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9a69e0f0ab76..69b9c1b8fafc 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -105,18 +105,18 @@ cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap | |||
105 | cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap | 105 | cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap |
106 | cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap | 106 | cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap |
107 | cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap | 107 | cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap |
108 | cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips2 -mtune=r4600) \ | 108 | cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ |
109 | -Wa,-mips32 -Wa,--trap | 109 | -Wa,-mips32 -Wa,--trap |
110 | cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips2 -mtune=r4600) \ | 110 | cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ |
111 | -Wa,-mips32r2 -Wa,--trap | 111 | -Wa,-mips32r2 -Wa,--trap |
112 | cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips2 -mtune=r4600) \ | 112 | cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips64 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \ |
113 | -Wa,-mips64 -Wa,--trap | 113 | -Wa,-mips64 -Wa,--trap |
114 | cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips2 -mtune=r4600 ) \ | 114 | cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \ |
115 | -Wa,-mips64r2 -Wa,--trap | 115 | -Wa,-mips64r2 -Wa,--trap |
116 | cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap | 116 | cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap |
117 | cflags-$(CONFIG_CPU_R5432) += $(call cc-options,-march=r5400,-march=r5000) \ | 117 | cflags-$(CONFIG_CPU_R5432) += $(call cc-option,-march=r5400,-march=r5000) \ |
118 | -Wa,--trap | 118 | -Wa,--trap |
119 | cflags-$(CONFIG_CPU_NEVADA) += $(call cc-options,-march=rm5200,-march=r5000) \ | 119 | cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \ |
120 | -Wa,--trap | 120 | -Wa,--trap |
121 | cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ | 121 | cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ |
122 | -Wa,--trap | 122 | -Wa,--trap |
diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile index a1edfd1f643c..bf682f50b859 100644 --- a/arch/mips/au1000/common/Makefile +++ b/arch/mips/au1000/common/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | # Makefile for the Alchemy Au1000 CPU, generic files. | 6 | # Makefile for the Alchemy Au1000 CPU, generic files. |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \ | 9 | obj-y += prom.o irq.o puts.o time.o reset.o \ |
10 | au1xxx_irqmap.o clocks.o platform.o power.o setup.o \ | 10 | au1xxx_irqmap.o clocks.o platform.o power.o setup.o \ |
11 | sleeper.o cputable.o dma.o dbdma.o gpio.o | 11 | sleeper.o cputable.o dma.o dbdma.o gpio.o |
12 | 12 | ||
diff --git a/arch/mips/au1000/common/int-handler.S b/arch/mips/au1000/common/int-handler.S deleted file mode 100644 index 1c4ca883321e..000000000000 --- a/arch/mips/au1000/common/int-handler.S +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: ppopov@mvista.com | ||
4 | * | ||
5 | * Interrupt dispatcher for Au1000 boards. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | |||
18 | .text | ||
19 | .set macro | ||
20 | .set noat | ||
21 | .align 5 | ||
22 | |||
23 | NESTED(au1000_IRQ, PT_SIZE, sp) | ||
24 | SAVE_ALL | ||
25 | CLI # Important: mark KERNEL mode ! | ||
26 | |||
27 | mfc0 t0,CP0_CAUSE # get pending interrupts | ||
28 | mfc0 t1,CP0_STATUS # get enabled interrupts | ||
29 | and t0,t1 # isolate allowed ones | ||
30 | |||
31 | andi t0,0xff00 # isolate pending bits | ||
32 | beqz t0, 3f # spurious interrupt | ||
33 | |||
34 | andi a0, t0, CAUSEF_IP7 | ||
35 | beq a0, zero, 1f | ||
36 | move a0, sp | ||
37 | jal mips_timer_interrupt | ||
38 | j ret_from_irq | ||
39 | |||
40 | 1: | ||
41 | andi a0, t0, CAUSEF_IP2 # Interrupt Controller 0, Request 0 | ||
42 | beq a0, zero, 2f | ||
43 | move a0,sp | ||
44 | jal intc0_req0_irqdispatch | ||
45 | j ret_from_irq | ||
46 | 2: | ||
47 | andi a0, t0, CAUSEF_IP3 # Interrupt Controller 0, Request 1 | ||
48 | beq a0, zero, 3f | ||
49 | move a0,sp | ||
50 | jal intc0_req1_irqdispatch | ||
51 | j ret_from_irq | ||
52 | 3: | ||
53 | andi a0, t0, CAUSEF_IP4 # Interrupt Controller 1, Request 0 | ||
54 | beq a0, zero, 4f | ||
55 | move a0,sp | ||
56 | jal intc1_req0_irqdispatch | ||
57 | j ret_from_irq | ||
58 | 4: | ||
59 | andi a0, t0, CAUSEF_IP5 # Interrupt Controller 1, Request 1 | ||
60 | beq a0, zero, 5f | ||
61 | move a0, sp | ||
62 | jal intc1_req1_irqdispatch | ||
63 | j ret_from_irq | ||
64 | |||
65 | 5: | ||
66 | move a0, sp | ||
67 | j spurious_interrupt | ||
68 | END(au1000_IRQ) | ||
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index 1339a0979f66..da61de776154 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #define EXT_INTC1_REQ1 5 /* IP 5 */ | 66 | #define EXT_INTC1_REQ1 5 /* IP 5 */ |
67 | #define MIPS_TIMER_IP 7 /* IP 7 */ | 67 | #define MIPS_TIMER_IP 7 /* IP 7 */ |
68 | 68 | ||
69 | extern asmlinkage void au1000_IRQ(void); | ||
70 | extern void set_debug_traps(void); | 69 | extern void set_debug_traps(void); |
71 | extern irq_cpustat_t irq_stat [NR_CPUS]; | 70 | extern irq_cpustat_t irq_stat [NR_CPUS]; |
72 | 71 | ||
@@ -446,7 +445,6 @@ void __init arch_init_irq(void) | |||
446 | extern int au1xxx_ic0_nr_irqs; | 445 | extern int au1xxx_ic0_nr_irqs; |
447 | 446 | ||
448 | cp0_status = read_c0_status(); | 447 | cp0_status = read_c0_status(); |
449 | set_except_vector(0, au1000_IRQ); | ||
450 | 448 | ||
451 | /* Initialize interrupt controllers to a safe state. | 449 | /* Initialize interrupt controllers to a safe state. |
452 | */ | 450 | */ |
@@ -661,3 +659,21 @@ restore_au1xxx_intctl(void) | |||
661 | au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); | 659 | au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); |
662 | } | 660 | } |
663 | #endif /* CONFIG_PM */ | 661 | #endif /* CONFIG_PM */ |
662 | |||
663 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
664 | { | ||
665 | unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; | ||
666 | |||
667 | if (pending & CAUSEF_IP7) | ||
668 | mips_timer_interrupt(regs); | ||
669 | else if (pending & CAUSEF_IP2) | ||
670 | intc0_req0_irqdispatch(regs); | ||
671 | else if (pending & CAUSEF_IP3) | ||
672 | intc0_req1_irqdispatch(regs); | ||
673 | else if (pending & CAUSEF_IP4) | ||
674 | intc1_req0_irqdispatch(regs); | ||
675 | else if (pending & CAUSEF_IP5) | ||
676 | intc1_req1_irqdispatch(regs); | ||
677 | else | ||
678 | spurious_interrupt(regs); | ||
679 | } | ||
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile index 720e757b2b64..225ac8f34ccd 100644 --- a/arch/mips/cobalt/Makefile +++ b/arch/mips/cobalt/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the Cobalt micro systems family specific parts of the kernel | 2 | # Makefile for the Cobalt micro systems family specific parts of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := irq.o int-handler.o reset.o setup.o | 5 | obj-y := irq.o reset.o setup.o |
6 | 6 | ||
7 | obj-$(CONFIG_EARLY_PRINTK) += console.o | 7 | obj-$(CONFIG_EARLY_PRINTK) += console.o |
8 | 8 | ||
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S deleted file mode 100644 index e75d5e3ca868..000000000000 --- a/arch/mips/cobalt/int-handler.S +++ /dev/null | |||
@@ -1,25 +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) 1995, 1996, 1997, 2003 by Ralf Baechle | ||
7 | * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) | ||
8 | */ | ||
9 | #include <asm/asm.h> | ||
10 | #include <asm/mipsregs.h> | ||
11 | #include <asm/mach-cobalt/cobalt.h> | ||
12 | #include <asm/regdef.h> | ||
13 | #include <asm/stackframe.h> | ||
14 | |||
15 | .text | ||
16 | .align 5 | ||
17 | NESTED(cobalt_handle_int, PT_SIZE, sp) | ||
18 | SAVE_ALL | ||
19 | CLI | ||
20 | |||
21 | PTR_LA ra, ret_from_irq | ||
22 | move a0, sp | ||
23 | j cobalt_irq | ||
24 | |||
25 | END(cobalt_handle_int) | ||
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c index f9a108820d6e..0b75f4fb7195 100644 --- a/arch/mips/cobalt/irq.c +++ b/arch/mips/cobalt/irq.c | |||
@@ -20,8 +20,6 @@ | |||
20 | 20 | ||
21 | #include <asm/mach-cobalt/cobalt.h> | 21 | #include <asm/mach-cobalt/cobalt.h> |
22 | 22 | ||
23 | extern void cobalt_handle_int(void); | ||
24 | |||
25 | /* | 23 | /* |
26 | * We have two types of interrupts that we handle, ones that come in through | 24 | * We have two types of interrupts that we handle, ones that come in through |
27 | * the CPU interrupt lines, and ones that come in on the via chip. The CPU | 25 | * the CPU interrupt lines, and ones that come in on the via chip. The CPU |
@@ -79,7 +77,7 @@ static inline void via_pic_irq(struct pt_regs *regs) | |||
79 | do_IRQ(irq, regs); | 77 | do_IRQ(irq, regs); |
80 | } | 78 | } |
81 | 79 | ||
82 | asmlinkage void cobalt_irq(struct pt_regs *regs) | 80 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
83 | { | 81 | { |
84 | unsigned pending; | 82 | unsigned pending; |
85 | 83 | ||
@@ -122,8 +120,6 @@ void __init arch_init_irq(void) | |||
122 | */ | 120 | */ |
123 | GALILEO_OUTL(0, GT_INTRMASK_OFS); | 121 | GALILEO_OUTL(0, GT_INTRMASK_OFS); |
124 | 122 | ||
125 | set_except_vector(0, cobalt_handle_int); | ||
126 | |||
127 | init_i8259_irqs(); /* 0 ... 15 */ | 123 | init_i8259_irqs(); /* 0 ... 15 */ |
128 | mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */ | 124 | mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */ |
129 | 125 | ||
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig new file mode 100644 index 000000000000..8a1e3ace0b2c --- /dev/null +++ b/arch/mips/configs/tb0287_defconfig | |||
@@ -0,0 +1,1096 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.16 | ||
4 | # Wed Mar 22 11:07:34 2006 | ||
5 | # | ||
6 | CONFIG_MIPS=y | ||
7 | |||
8 | # | ||
9 | # Machine selection | ||
10 | # | ||
11 | # CONFIG_MIPS_MTX1 is not set | ||
12 | # CONFIG_MIPS_BOSPORUS is not set | ||
13 | # CONFIG_MIPS_PB1000 is not set | ||
14 | # CONFIG_MIPS_PB1100 is not set | ||
15 | # CONFIG_MIPS_PB1500 is not set | ||
16 | # CONFIG_MIPS_PB1550 is not set | ||
17 | # CONFIG_MIPS_PB1200 is not set | ||
18 | # CONFIG_MIPS_DB1000 is not set | ||
19 | # CONFIG_MIPS_DB1100 is not set | ||
20 | # CONFIG_MIPS_DB1500 is not set | ||
21 | # CONFIG_MIPS_DB1550 is not set | ||
22 | # CONFIG_MIPS_DB1200 is not set | ||
23 | # CONFIG_MIPS_MIRAGE is not set | ||
24 | # CONFIG_MIPS_COBALT is not set | ||
25 | # CONFIG_MACH_DECSTATION is not set | ||
26 | # CONFIG_MIPS_EV64120 is not set | ||
27 | # CONFIG_MIPS_EV96100 is not set | ||
28 | # CONFIG_MIPS_IVR is not set | ||
29 | # CONFIG_MIPS_ITE8172 is not set | ||
30 | # CONFIG_MACH_JAZZ is not set | ||
31 | # CONFIG_LASAT is not set | ||
32 | # CONFIG_MIPS_ATLAS is not set | ||
33 | # CONFIG_MIPS_MALTA is not set | ||
34 | # CONFIG_MIPS_SEAD is not set | ||
35 | # CONFIG_MIPS_SIM is not set | ||
36 | # CONFIG_MOMENCO_JAGUAR_ATX is not set | ||
37 | # CONFIG_MOMENCO_OCELOT is not set | ||
38 | # CONFIG_MOMENCO_OCELOT_3 is not set | ||
39 | # CONFIG_MOMENCO_OCELOT_C is not set | ||
40 | # CONFIG_MOMENCO_OCELOT_G is not set | ||
41 | # CONFIG_MIPS_XXS1500 is not set | ||
42 | # CONFIG_PNX8550_V2PCI is not set | ||
43 | # CONFIG_PNX8550_JBS is not set | ||
44 | # CONFIG_DDB5074 is not set | ||
45 | # CONFIG_DDB5476 is not set | ||
46 | # CONFIG_DDB5477 is not set | ||
47 | CONFIG_MACH_VR41XX=y | ||
48 | # CONFIG_PMC_YOSEMITE is not set | ||
49 | # CONFIG_QEMU is not set | ||
50 | # CONFIG_SGI_IP22 is not set | ||
51 | # CONFIG_SGI_IP27 is not set | ||
52 | # CONFIG_SGI_IP32 is not set | ||
53 | # CONFIG_SIBYTE_BIGSUR is not set | ||
54 | # CONFIG_SIBYTE_SWARM is not set | ||
55 | # CONFIG_SIBYTE_SENTOSA is not set | ||
56 | # CONFIG_SIBYTE_RHONE is not set | ||
57 | # CONFIG_SIBYTE_CARMEL is not set | ||
58 | # CONFIG_SIBYTE_PTSWARM is not set | ||
59 | # CONFIG_SIBYTE_LITTLESUR is not set | ||
60 | # CONFIG_SIBYTE_CRHINE is not set | ||
61 | # CONFIG_SIBYTE_CRHONE is not set | ||
62 | # CONFIG_SNI_RM200_PCI is not set | ||
63 | # CONFIG_TOSHIBA_JMR3927 is not set | ||
64 | # CONFIG_TOSHIBA_RBTX4927 is not set | ||
65 | # CONFIG_TOSHIBA_RBTX4938 is not set | ||
66 | # CONFIG_CASIO_E55 is not set | ||
67 | # CONFIG_IBM_WORKPAD is not set | ||
68 | # CONFIG_NEC_CMBVR4133 is not set | ||
69 | CONFIG_TANBAC_TB022X=y | ||
70 | # CONFIG_TANBAC_TB0226 is not set | ||
71 | CONFIG_TANBAC_TB0287=y | ||
72 | # CONFIG_VICTOR_MPC30X is not set | ||
73 | # CONFIG_ZAO_CAPCELLA is not set | ||
74 | CONFIG_PCI_VR41XX=y | ||
75 | # CONFIG_VRC4173 is not set | ||
76 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
77 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
78 | CONFIG_DMA_NONCOHERENT=y | ||
79 | CONFIG_DMA_NEED_PCI_MAP_STATE=y | ||
80 | # CONFIG_CPU_BIG_ENDIAN is not set | ||
81 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
82 | CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y | ||
83 | CONFIG_IRQ_CPU=y | ||
84 | CONFIG_MIPS_L1_CACHE_SHIFT=5 | ||
85 | |||
86 | # | ||
87 | # CPU selection | ||
88 | # | ||
89 | # CONFIG_CPU_MIPS32_R1 is not set | ||
90 | # CONFIG_CPU_MIPS32_R2 is not set | ||
91 | # CONFIG_CPU_MIPS64_R1 is not set | ||
92 | # CONFIG_CPU_MIPS64_R2 is not set | ||
93 | # CONFIG_CPU_R3000 is not set | ||
94 | # CONFIG_CPU_TX39XX is not set | ||
95 | CONFIG_CPU_VR41XX=y | ||
96 | # CONFIG_CPU_R4300 is not set | ||
97 | # CONFIG_CPU_R4X00 is not set | ||
98 | # CONFIG_CPU_TX49XX is not set | ||
99 | # CONFIG_CPU_R5000 is not set | ||
100 | # CONFIG_CPU_R5432 is not set | ||
101 | # CONFIG_CPU_R6000 is not set | ||
102 | # CONFIG_CPU_NEVADA is not set | ||
103 | # CONFIG_CPU_R8000 is not set | ||
104 | # CONFIG_CPU_R10000 is not set | ||
105 | # CONFIG_CPU_RM7000 is not set | ||
106 | # CONFIG_CPU_RM9000 is not set | ||
107 | # CONFIG_CPU_SB1 is not set | ||
108 | CONFIG_SYS_HAS_CPU_VR41XX=y | ||
109 | CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y | ||
110 | CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y | ||
111 | CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y | ||
112 | CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y | ||
113 | |||
114 | # | ||
115 | # Kernel type | ||
116 | # | ||
117 | CONFIG_32BIT=y | ||
118 | # CONFIG_64BIT is not set | ||
119 | CONFIG_PAGE_SIZE_4KB=y | ||
120 | # CONFIG_PAGE_SIZE_8KB is not set | ||
121 | # CONFIG_PAGE_SIZE_16KB is not set | ||
122 | # CONFIG_PAGE_SIZE_64KB is not set | ||
123 | # CONFIG_MIPS_MT is not set | ||
124 | # CONFIG_CPU_ADVANCED is not set | ||
125 | CONFIG_CPU_HAS_SYNC=y | ||
126 | CONFIG_GENERIC_HARDIRQS=y | ||
127 | CONFIG_GENERIC_IRQ_PROBE=y | ||
128 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
129 | CONFIG_SELECT_MEMORY_MODEL=y | ||
130 | CONFIG_FLATMEM_MANUAL=y | ||
131 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
132 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
133 | CONFIG_FLATMEM=y | ||
134 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
135 | # CONFIG_SPARSEMEM_STATIC is not set | ||
136 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
137 | CONFIG_PREEMPT_NONE=y | ||
138 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
139 | # CONFIG_PREEMPT is not set | ||
140 | |||
141 | # | ||
142 | # Code maturity level options | ||
143 | # | ||
144 | CONFIG_EXPERIMENTAL=y | ||
145 | CONFIG_BROKEN_ON_SMP=y | ||
146 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
147 | |||
148 | # | ||
149 | # General setup | ||
150 | # | ||
151 | CONFIG_LOCALVERSION="" | ||
152 | CONFIG_LOCALVERSION_AUTO=y | ||
153 | CONFIG_SWAP=y | ||
154 | CONFIG_SYSVIPC=y | ||
155 | # CONFIG_POSIX_MQUEUE is not set | ||
156 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
157 | CONFIG_SYSCTL=y | ||
158 | # CONFIG_AUDIT is not set | ||
159 | # CONFIG_IKCONFIG is not set | ||
160 | CONFIG_INITRAMFS_SOURCE="" | ||
161 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
162 | CONFIG_EMBEDDED=y | ||
163 | CONFIG_KALLSYMS=y | ||
164 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
165 | # CONFIG_HOTPLUG is not set | ||
166 | CONFIG_PRINTK=y | ||
167 | CONFIG_BUG=y | ||
168 | CONFIG_ELF_CORE=y | ||
169 | CONFIG_BASE_FULL=y | ||
170 | CONFIG_FUTEX=y | ||
171 | CONFIG_EPOLL=y | ||
172 | CONFIG_SHMEM=y | ||
173 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
174 | CONFIG_CC_ALIGN_LABELS=0 | ||
175 | CONFIG_CC_ALIGN_LOOPS=0 | ||
176 | CONFIG_CC_ALIGN_JUMPS=0 | ||
177 | CONFIG_SLAB=y | ||
178 | # CONFIG_TINY_SHMEM is not set | ||
179 | CONFIG_BASE_SMALL=0 | ||
180 | # CONFIG_SLOB is not set | ||
181 | |||
182 | # | ||
183 | # Loadable module support | ||
184 | # | ||
185 | CONFIG_MODULES=y | ||
186 | CONFIG_MODULE_UNLOAD=y | ||
187 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
188 | CONFIG_OBSOLETE_MODPARM=y | ||
189 | CONFIG_MODVERSIONS=y | ||
190 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
191 | CONFIG_KMOD=y | ||
192 | |||
193 | # | ||
194 | # Block layer | ||
195 | # | ||
196 | # CONFIG_LBD is not set | ||
197 | |||
198 | # | ||
199 | # IO Schedulers | ||
200 | # | ||
201 | CONFIG_IOSCHED_NOOP=y | ||
202 | CONFIG_IOSCHED_AS=y | ||
203 | CONFIG_IOSCHED_DEADLINE=y | ||
204 | CONFIG_IOSCHED_CFQ=y | ||
205 | CONFIG_DEFAULT_AS=y | ||
206 | # CONFIG_DEFAULT_DEADLINE is not set | ||
207 | # CONFIG_DEFAULT_CFQ is not set | ||
208 | # CONFIG_DEFAULT_NOOP is not set | ||
209 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
210 | |||
211 | # | ||
212 | # Bus options (PCI, PCMCIA, EISA, ISA, TC) | ||
213 | # | ||
214 | CONFIG_HW_HAS_PCI=y | ||
215 | CONFIG_PCI=y | ||
216 | # CONFIG_PCI_LEGACY_PROC is not set | ||
217 | CONFIG_MMU=y | ||
218 | |||
219 | # | ||
220 | # PCCARD (PCMCIA/CardBus) support | ||
221 | # | ||
222 | # CONFIG_PCCARD is not set | ||
223 | |||
224 | # | ||
225 | # PCI Hotplug Support | ||
226 | # | ||
227 | # CONFIG_HOTPLUG_PCI is not set | ||
228 | |||
229 | # | ||
230 | # Executable file formats | ||
231 | # | ||
232 | CONFIG_BINFMT_ELF=y | ||
233 | # CONFIG_BINFMT_MISC is not set | ||
234 | CONFIG_TRAD_SIGNALS=y | ||
235 | |||
236 | # | ||
237 | # Networking | ||
238 | # | ||
239 | CONFIG_NET=y | ||
240 | |||
241 | # | ||
242 | # Networking options | ||
243 | # | ||
244 | # CONFIG_NETDEBUG is not set | ||
245 | CONFIG_PACKET=y | ||
246 | # CONFIG_PACKET_MMAP is not set | ||
247 | CONFIG_UNIX=y | ||
248 | CONFIG_XFRM=y | ||
249 | CONFIG_XFRM_USER=m | ||
250 | # CONFIG_NET_KEY is not set | ||
251 | CONFIG_INET=y | ||
252 | CONFIG_IP_MULTICAST=y | ||
253 | CONFIG_IP_ADVANCED_ROUTER=y | ||
254 | CONFIG_ASK_IP_FIB_HASH=y | ||
255 | # CONFIG_IP_FIB_TRIE is not set | ||
256 | CONFIG_IP_FIB_HASH=y | ||
257 | CONFIG_IP_MULTIPLE_TABLES=y | ||
258 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
259 | # CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set | ||
260 | CONFIG_IP_ROUTE_VERBOSE=y | ||
261 | CONFIG_IP_PNP=y | ||
262 | # CONFIG_IP_PNP_DHCP is not set | ||
263 | CONFIG_IP_PNP_BOOTP=y | ||
264 | # CONFIG_IP_PNP_RARP is not set | ||
265 | CONFIG_NET_IPIP=m | ||
266 | CONFIG_NET_IPGRE=m | ||
267 | # CONFIG_NET_IPGRE_BROADCAST is not set | ||
268 | # CONFIG_IP_MROUTE is not set | ||
269 | # CONFIG_ARPD is not set | ||
270 | CONFIG_SYN_COOKIES=y | ||
271 | # CONFIG_INET_AH is not set | ||
272 | # CONFIG_INET_ESP is not set | ||
273 | # CONFIG_INET_IPCOMP is not set | ||
274 | CONFIG_INET_TUNNEL=m | ||
275 | CONFIG_INET_DIAG=y | ||
276 | CONFIG_INET_TCP_DIAG=y | ||
277 | CONFIG_TCP_CONG_ADVANCED=y | ||
278 | |||
279 | # | ||
280 | # TCP congestion control | ||
281 | # | ||
282 | CONFIG_TCP_CONG_BIC=y | ||
283 | CONFIG_TCP_CONG_CUBIC=m | ||
284 | CONFIG_TCP_CONG_WESTWOOD=m | ||
285 | CONFIG_TCP_CONG_HTCP=m | ||
286 | # CONFIG_TCP_CONG_HSTCP is not set | ||
287 | # CONFIG_TCP_CONG_HYBLA is not set | ||
288 | # CONFIG_TCP_CONG_VEGAS is not set | ||
289 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
290 | # CONFIG_IPV6 is not set | ||
291 | # CONFIG_NETFILTER is not set | ||
292 | |||
293 | # | ||
294 | # DCCP Configuration (EXPERIMENTAL) | ||
295 | # | ||
296 | # CONFIG_IP_DCCP is not set | ||
297 | |||
298 | # | ||
299 | # SCTP Configuration (EXPERIMENTAL) | ||
300 | # | ||
301 | # CONFIG_IP_SCTP is not set | ||
302 | |||
303 | # | ||
304 | # TIPC Configuration (EXPERIMENTAL) | ||
305 | # | ||
306 | # CONFIG_TIPC is not set | ||
307 | # CONFIG_ATM is not set | ||
308 | # CONFIG_BRIDGE is not set | ||
309 | # CONFIG_VLAN_8021Q is not set | ||
310 | # CONFIG_DECNET is not set | ||
311 | # CONFIG_LLC2 is not set | ||
312 | # CONFIG_IPX is not set | ||
313 | # CONFIG_ATALK is not set | ||
314 | # CONFIG_X25 is not set | ||
315 | # CONFIG_LAPB is not set | ||
316 | # CONFIG_NET_DIVERT is not set | ||
317 | # CONFIG_ECONET is not set | ||
318 | # CONFIG_WAN_ROUTER is not set | ||
319 | |||
320 | # | ||
321 | # QoS and/or fair queueing | ||
322 | # | ||
323 | # CONFIG_NET_SCHED is not set | ||
324 | |||
325 | # | ||
326 | # Network testing | ||
327 | # | ||
328 | # CONFIG_NET_PKTGEN is not set | ||
329 | # CONFIG_HAMRADIO is not set | ||
330 | # CONFIG_IRDA is not set | ||
331 | # CONFIG_BT is not set | ||
332 | # CONFIG_IEEE80211 is not set | ||
333 | |||
334 | # | ||
335 | # Device Drivers | ||
336 | # | ||
337 | |||
338 | # | ||
339 | # Generic Driver Options | ||
340 | # | ||
341 | CONFIG_STANDALONE=y | ||
342 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
343 | # CONFIG_FW_LOADER is not set | ||
344 | |||
345 | # | ||
346 | # Connector - unified userspace <-> kernelspace linker | ||
347 | # | ||
348 | # CONFIG_CONNECTOR is not set | ||
349 | |||
350 | # | ||
351 | # Memory Technology Devices (MTD) | ||
352 | # | ||
353 | # CONFIG_MTD is not set | ||
354 | |||
355 | # | ||
356 | # Parallel port support | ||
357 | # | ||
358 | # CONFIG_PARPORT is not set | ||
359 | |||
360 | # | ||
361 | # Plug and Play support | ||
362 | # | ||
363 | |||
364 | # | ||
365 | # Block devices | ||
366 | # | ||
367 | # CONFIG_BLK_CPQ_DA is not set | ||
368 | # CONFIG_BLK_CPQ_CISS_DA is not set | ||
369 | # CONFIG_BLK_DEV_DAC960 is not set | ||
370 | # CONFIG_BLK_DEV_UMEM is not set | ||
371 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
372 | CONFIG_BLK_DEV_LOOP=m | ||
373 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
374 | CONFIG_BLK_DEV_NBD=m | ||
375 | # CONFIG_BLK_DEV_SX8 is not set | ||
376 | # CONFIG_BLK_DEV_UB is not set | ||
377 | CONFIG_BLK_DEV_RAM=y | ||
378 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
379 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
380 | # CONFIG_BLK_DEV_INITRD is not set | ||
381 | # CONFIG_CDROM_PKTCDVD is not set | ||
382 | # CONFIG_ATA_OVER_ETH is not set | ||
383 | |||
384 | # | ||
385 | # ATA/ATAPI/MFM/RLL support | ||
386 | # | ||
387 | CONFIG_IDE=y | ||
388 | CONFIG_BLK_DEV_IDE=y | ||
389 | |||
390 | # | ||
391 | # Please see Documentation/ide.txt for help/info on IDE drives | ||
392 | # | ||
393 | # CONFIG_BLK_DEV_IDE_SATA is not set | ||
394 | CONFIG_BLK_DEV_IDEDISK=y | ||
395 | # CONFIG_IDEDISK_MULTI_MODE is not set | ||
396 | # CONFIG_BLK_DEV_IDECD is not set | ||
397 | # CONFIG_BLK_DEV_IDETAPE is not set | ||
398 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | ||
399 | # CONFIG_BLK_DEV_IDESCSI is not set | ||
400 | # CONFIG_IDE_TASK_IOCTL is not set | ||
401 | |||
402 | # | ||
403 | # IDE chipset support/bugfixes | ||
404 | # | ||
405 | CONFIG_IDE_GENERIC=y | ||
406 | CONFIG_BLK_DEV_IDEPCI=y | ||
407 | # CONFIG_IDEPCI_SHARE_IRQ is not set | ||
408 | # CONFIG_BLK_DEV_OFFBOARD is not set | ||
409 | # CONFIG_BLK_DEV_GENERIC is not set | ||
410 | # CONFIG_BLK_DEV_OPTI621 is not set | ||
411 | CONFIG_BLK_DEV_IDEDMA_PCI=y | ||
412 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set | ||
413 | # CONFIG_IDEDMA_PCI_AUTO is not set | ||
414 | # CONFIG_BLK_DEV_AEC62XX is not set | ||
415 | # CONFIG_BLK_DEV_ALI15X3 is not set | ||
416 | # CONFIG_BLK_DEV_AMD74XX is not set | ||
417 | # CONFIG_BLK_DEV_CMD64X is not set | ||
418 | # CONFIG_BLK_DEV_TRIFLEX is not set | ||
419 | # CONFIG_BLK_DEV_CY82C693 is not set | ||
420 | # CONFIG_BLK_DEV_CS5520 is not set | ||
421 | # CONFIG_BLK_DEV_CS5530 is not set | ||
422 | # CONFIG_BLK_DEV_HPT34X is not set | ||
423 | # CONFIG_BLK_DEV_HPT366 is not set | ||
424 | # CONFIG_BLK_DEV_SC1200 is not set | ||
425 | # CONFIG_BLK_DEV_PIIX is not set | ||
426 | # CONFIG_BLK_DEV_IT821X is not set | ||
427 | # CONFIG_BLK_DEV_NS87415 is not set | ||
428 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | ||
429 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | ||
430 | # CONFIG_BLK_DEV_SVWKS is not set | ||
431 | CONFIG_BLK_DEV_SIIMAGE=y | ||
432 | # CONFIG_BLK_DEV_SLC90E66 is not set | ||
433 | # CONFIG_BLK_DEV_TRM290 is not set | ||
434 | # CONFIG_BLK_DEV_VIA82CXXX is not set | ||
435 | # CONFIG_IDE_ARM is not set | ||
436 | CONFIG_BLK_DEV_IDEDMA=y | ||
437 | # CONFIG_IDEDMA_IVB is not set | ||
438 | # CONFIG_IDEDMA_AUTO is not set | ||
439 | # CONFIG_BLK_DEV_HD is not set | ||
440 | |||
441 | # | ||
442 | # SCSI device support | ||
443 | # | ||
444 | # CONFIG_RAID_ATTRS is not set | ||
445 | CONFIG_SCSI=y | ||
446 | CONFIG_SCSI_PROC_FS=y | ||
447 | |||
448 | # | ||
449 | # SCSI support type (disk, tape, CD-ROM) | ||
450 | # | ||
451 | CONFIG_BLK_DEV_SD=y | ||
452 | # CONFIG_CHR_DEV_ST is not set | ||
453 | # CONFIG_CHR_DEV_OSST is not set | ||
454 | # CONFIG_BLK_DEV_SR is not set | ||
455 | # CONFIG_CHR_DEV_SG is not set | ||
456 | # CONFIG_CHR_DEV_SCH is not set | ||
457 | |||
458 | # | ||
459 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
460 | # | ||
461 | # CONFIG_SCSI_MULTI_LUN is not set | ||
462 | # CONFIG_SCSI_CONSTANTS is not set | ||
463 | # CONFIG_SCSI_LOGGING is not set | ||
464 | |||
465 | # | ||
466 | # SCSI Transport Attributes | ||
467 | # | ||
468 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
469 | # CONFIG_SCSI_FC_ATTRS is not set | ||
470 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
471 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
472 | |||
473 | # | ||
474 | # SCSI low-level drivers | ||
475 | # | ||
476 | # CONFIG_ISCSI_TCP is not set | ||
477 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | ||
478 | # CONFIG_SCSI_3W_9XXX is not set | ||
479 | # CONFIG_SCSI_ACARD is not set | ||
480 | # CONFIG_SCSI_AACRAID is not set | ||
481 | # CONFIG_SCSI_AIC7XXX is not set | ||
482 | # CONFIG_SCSI_AIC7XXX_OLD is not set | ||
483 | # CONFIG_SCSI_AIC79XX is not set | ||
484 | # CONFIG_SCSI_DPT_I2O is not set | ||
485 | # CONFIG_MEGARAID_NEWGEN is not set | ||
486 | # CONFIG_MEGARAID_LEGACY is not set | ||
487 | # CONFIG_MEGARAID_SAS is not set | ||
488 | # CONFIG_SCSI_SATA is not set | ||
489 | # CONFIG_SCSI_DMX3191D is not set | ||
490 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | ||
491 | # CONFIG_SCSI_IPS is not set | ||
492 | # CONFIG_SCSI_INITIO is not set | ||
493 | # CONFIG_SCSI_INIA100 is not set | ||
494 | # CONFIG_SCSI_SYM53C8XX_2 is not set | ||
495 | # CONFIG_SCSI_IPR is not set | ||
496 | # CONFIG_SCSI_QLOGIC_FC is not set | ||
497 | # CONFIG_SCSI_QLOGIC_1280 is not set | ||
498 | # CONFIG_SCSI_QLA_FC is not set | ||
499 | # CONFIG_SCSI_LPFC is not set | ||
500 | # CONFIG_SCSI_DC395x is not set | ||
501 | # CONFIG_SCSI_DC390T is not set | ||
502 | # CONFIG_SCSI_NSP32 is not set | ||
503 | # CONFIG_SCSI_DEBUG is not set | ||
504 | |||
505 | # | ||
506 | # Multi-device support (RAID and LVM) | ||
507 | # | ||
508 | # CONFIG_MD is not set | ||
509 | |||
510 | # | ||
511 | # Fusion MPT device support | ||
512 | # | ||
513 | # CONFIG_FUSION is not set | ||
514 | # CONFIG_FUSION_SPI is not set | ||
515 | # CONFIG_FUSION_FC is not set | ||
516 | # CONFIG_FUSION_SAS is not set | ||
517 | |||
518 | # | ||
519 | # IEEE 1394 (FireWire) support | ||
520 | # | ||
521 | CONFIG_IEEE1394=m | ||
522 | |||
523 | # | ||
524 | # Subsystem Options | ||
525 | # | ||
526 | # CONFIG_IEEE1394_VERBOSEDEBUG is not set | ||
527 | # CONFIG_IEEE1394_OUI_DB is not set | ||
528 | CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y | ||
529 | CONFIG_IEEE1394_CONFIG_ROM_IP1394=y | ||
530 | # CONFIG_IEEE1394_EXPORT_FULL_API is not set | ||
531 | |||
532 | # | ||
533 | # Device Drivers | ||
534 | # | ||
535 | |||
536 | # | ||
537 | # Texas Instruments PCILynx requires I2C | ||
538 | # | ||
539 | CONFIG_IEEE1394_OHCI1394=m | ||
540 | |||
541 | # | ||
542 | # Protocol Drivers | ||
543 | # | ||
544 | CONFIG_IEEE1394_VIDEO1394=m | ||
545 | CONFIG_IEEE1394_SBP2=m | ||
546 | # CONFIG_IEEE1394_SBP2_PHYS_DMA is not set | ||
547 | CONFIG_IEEE1394_ETH1394=m | ||
548 | CONFIG_IEEE1394_DV1394=m | ||
549 | CONFIG_IEEE1394_RAWIO=m | ||
550 | |||
551 | # | ||
552 | # I2O device support | ||
553 | # | ||
554 | # CONFIG_I2O is not set | ||
555 | |||
556 | # | ||
557 | # Network device support | ||
558 | # | ||
559 | CONFIG_NETDEVICES=y | ||
560 | CONFIG_DUMMY=m | ||
561 | # CONFIG_BONDING is not set | ||
562 | # CONFIG_EQUALIZER is not set | ||
563 | # CONFIG_TUN is not set | ||
564 | |||
565 | # | ||
566 | # ARCnet devices | ||
567 | # | ||
568 | # CONFIG_ARCNET is not set | ||
569 | |||
570 | # | ||
571 | # PHY device support | ||
572 | # | ||
573 | # CONFIG_PHYLIB is not set | ||
574 | |||
575 | # | ||
576 | # Ethernet (10 or 100Mbit) | ||
577 | # | ||
578 | CONFIG_NET_ETHERNET=y | ||
579 | CONFIG_MII=y | ||
580 | # CONFIG_HAPPYMEAL is not set | ||
581 | # CONFIG_SUNGEM is not set | ||
582 | # CONFIG_CASSINI is not set | ||
583 | # CONFIG_NET_VENDOR_3COM is not set | ||
584 | # CONFIG_DM9000 is not set | ||
585 | |||
586 | # | ||
587 | # Tulip family network device support | ||
588 | # | ||
589 | # CONFIG_NET_TULIP is not set | ||
590 | # CONFIG_HP100 is not set | ||
591 | # CONFIG_NET_PCI is not set | ||
592 | |||
593 | # | ||
594 | # Ethernet (1000 Mbit) | ||
595 | # | ||
596 | # CONFIG_ACENIC is not set | ||
597 | # CONFIG_DL2K is not set | ||
598 | # CONFIG_E1000 is not set | ||
599 | # CONFIG_NS83820 is not set | ||
600 | # CONFIG_HAMACHI is not set | ||
601 | # CONFIG_YELLOWFIN is not set | ||
602 | CONFIG_R8169=y | ||
603 | # CONFIG_R8169_NAPI is not set | ||
604 | # CONFIG_SIS190 is not set | ||
605 | # CONFIG_SKGE is not set | ||
606 | # CONFIG_SKY2 is not set | ||
607 | # CONFIG_SK98LIN is not set | ||
608 | # CONFIG_TIGON3 is not set | ||
609 | # CONFIG_BNX2 is not set | ||
610 | |||
611 | # | ||
612 | # Ethernet (10000 Mbit) | ||
613 | # | ||
614 | # CONFIG_CHELSIO_T1 is not set | ||
615 | # CONFIG_IXGB is not set | ||
616 | # CONFIG_S2IO is not set | ||
617 | |||
618 | # | ||
619 | # Token Ring devices | ||
620 | # | ||
621 | # CONFIG_TR is not set | ||
622 | |||
623 | # | ||
624 | # Wireless LAN (non-hamradio) | ||
625 | # | ||
626 | # CONFIG_NET_RADIO is not set | ||
627 | |||
628 | # | ||
629 | # Wan interfaces | ||
630 | # | ||
631 | # CONFIG_WAN is not set | ||
632 | # CONFIG_FDDI is not set | ||
633 | # CONFIG_HIPPI is not set | ||
634 | # CONFIG_PPP is not set | ||
635 | # CONFIG_SLIP is not set | ||
636 | # CONFIG_NET_FC is not set | ||
637 | # CONFIG_SHAPER is not set | ||
638 | # CONFIG_NETCONSOLE is not set | ||
639 | # CONFIG_NETPOLL is not set | ||
640 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
641 | |||
642 | # | ||
643 | # ISDN subsystem | ||
644 | # | ||
645 | # CONFIG_ISDN is not set | ||
646 | |||
647 | # | ||
648 | # Telephony Support | ||
649 | # | ||
650 | # CONFIG_PHONE is not set | ||
651 | |||
652 | # | ||
653 | # Input device support | ||
654 | # | ||
655 | CONFIG_INPUT=y | ||
656 | |||
657 | # | ||
658 | # Userland interfaces | ||
659 | # | ||
660 | # CONFIG_INPUT_MOUSEDEV is not set | ||
661 | # CONFIG_INPUT_JOYDEV is not set | ||
662 | # CONFIG_INPUT_TSDEV is not set | ||
663 | # CONFIG_INPUT_EVDEV is not set | ||
664 | # CONFIG_INPUT_EVBUG is not set | ||
665 | |||
666 | # | ||
667 | # Input Device Drivers | ||
668 | # | ||
669 | # CONFIG_INPUT_KEYBOARD is not set | ||
670 | # CONFIG_INPUT_MOUSE is not set | ||
671 | # CONFIG_INPUT_JOYSTICK is not set | ||
672 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
673 | # CONFIG_INPUT_MISC is not set | ||
674 | |||
675 | # | ||
676 | # Hardware I/O ports | ||
677 | # | ||
678 | # CONFIG_SERIO is not set | ||
679 | # CONFIG_GAMEPORT is not set | ||
680 | |||
681 | # | ||
682 | # Character devices | ||
683 | # | ||
684 | CONFIG_VT=y | ||
685 | CONFIG_VT_CONSOLE=y | ||
686 | CONFIG_HW_CONSOLE=y | ||
687 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
688 | |||
689 | # | ||
690 | # Serial drivers | ||
691 | # | ||
692 | # CONFIG_SERIAL_8250 is not set | ||
693 | |||
694 | # | ||
695 | # Non-8250 serial port support | ||
696 | # | ||
697 | CONFIG_SERIAL_CORE=y | ||
698 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
699 | CONFIG_SERIAL_VR41XX=y | ||
700 | CONFIG_SERIAL_VR41XX_CONSOLE=y | ||
701 | # CONFIG_SERIAL_JSM is not set | ||
702 | CONFIG_UNIX98_PTYS=y | ||
703 | CONFIG_LEGACY_PTYS=y | ||
704 | CONFIG_LEGACY_PTY_COUNT=256 | ||
705 | |||
706 | # | ||
707 | # IPMI | ||
708 | # | ||
709 | # CONFIG_IPMI_HANDLER is not set | ||
710 | |||
711 | # | ||
712 | # Watchdog Cards | ||
713 | # | ||
714 | # CONFIG_WATCHDOG is not set | ||
715 | # CONFIG_RTC is not set | ||
716 | # CONFIG_GEN_RTC is not set | ||
717 | # CONFIG_RTC_VR41XX is not set | ||
718 | # CONFIG_DTLK is not set | ||
719 | # CONFIG_R3964 is not set | ||
720 | # CONFIG_APPLICOM is not set | ||
721 | # CONFIG_TANBAC_TB0219 is not set | ||
722 | |||
723 | # | ||
724 | # Ftape, the floppy tape device driver | ||
725 | # | ||
726 | # CONFIG_DRM is not set | ||
727 | CONFIG_GPIO_VR41XX=y | ||
728 | # CONFIG_RAW_DRIVER is not set | ||
729 | |||
730 | # | ||
731 | # TPM devices | ||
732 | # | ||
733 | # CONFIG_TCG_TPM is not set | ||
734 | # CONFIG_TELCLOCK is not set | ||
735 | |||
736 | # | ||
737 | # I2C support | ||
738 | # | ||
739 | # CONFIG_I2C is not set | ||
740 | |||
741 | # | ||
742 | # SPI support | ||
743 | # | ||
744 | # CONFIG_SPI is not set | ||
745 | # CONFIG_SPI_MASTER is not set | ||
746 | |||
747 | # | ||
748 | # Dallas's 1-wire bus | ||
749 | # | ||
750 | # CONFIG_W1 is not set | ||
751 | |||
752 | # | ||
753 | # Hardware Monitoring support | ||
754 | # | ||
755 | # CONFIG_HWMON is not set | ||
756 | # CONFIG_HWMON_VID is not set | ||
757 | |||
758 | # | ||
759 | # Misc devices | ||
760 | # | ||
761 | |||
762 | # | ||
763 | # Multimedia Capabilities Port drivers | ||
764 | # | ||
765 | |||
766 | # | ||
767 | # Multimedia devices | ||
768 | # | ||
769 | # CONFIG_VIDEO_DEV is not set | ||
770 | |||
771 | # | ||
772 | # Digital Video Broadcasting Devices | ||
773 | # | ||
774 | # CONFIG_DVB is not set | ||
775 | |||
776 | # | ||
777 | # Graphics support | ||
778 | # | ||
779 | # CONFIG_FB is not set | ||
780 | |||
781 | # | ||
782 | # Console display driver support | ||
783 | # | ||
784 | # CONFIG_VGA_CONSOLE is not set | ||
785 | CONFIG_DUMMY_CONSOLE=y | ||
786 | |||
787 | # | ||
788 | # Sound | ||
789 | # | ||
790 | # CONFIG_SOUND is not set | ||
791 | |||
792 | # | ||
793 | # USB support | ||
794 | # | ||
795 | CONFIG_USB_ARCH_HAS_HCD=y | ||
796 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
797 | CONFIG_USB=m | ||
798 | # CONFIG_USB_DEBUG is not set | ||
799 | |||
800 | # | ||
801 | # Miscellaneous USB options | ||
802 | # | ||
803 | # CONFIG_USB_DEVICEFS is not set | ||
804 | # CONFIG_USB_BANDWIDTH is not set | ||
805 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
806 | # CONFIG_USB_OTG is not set | ||
807 | |||
808 | # | ||
809 | # USB Host Controller Drivers | ||
810 | # | ||
811 | CONFIG_USB_EHCI_HCD=m | ||
812 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | ||
813 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | ||
814 | # CONFIG_USB_ISP116X_HCD is not set | ||
815 | CONFIG_USB_OHCI_HCD=m | ||
816 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set | ||
817 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
818 | # CONFIG_USB_UHCI_HCD is not set | ||
819 | # CONFIG_USB_SL811_HCD is not set | ||
820 | |||
821 | # | ||
822 | # USB Device Class drivers | ||
823 | # | ||
824 | # CONFIG_USB_ACM is not set | ||
825 | # CONFIG_USB_PRINTER is not set | ||
826 | |||
827 | # | ||
828 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
829 | # | ||
830 | |||
831 | # | ||
832 | # may also be needed; see USB_STORAGE Help for more information | ||
833 | # | ||
834 | CONFIG_USB_STORAGE=m | ||
835 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
836 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
837 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
838 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
839 | # CONFIG_USB_STORAGE_DPCM is not set | ||
840 | # CONFIG_USB_STORAGE_USBAT is not set | ||
841 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
842 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
843 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
844 | # CONFIG_USB_STORAGE_ALAUDA is not set | ||
845 | # CONFIG_USB_LIBUSUAL is not set | ||
846 | |||
847 | # | ||
848 | # USB Input Devices | ||
849 | # | ||
850 | CONFIG_USB_HID=m | ||
851 | CONFIG_USB_HIDINPUT=y | ||
852 | # CONFIG_USB_HIDINPUT_POWERBOOK is not set | ||
853 | # CONFIG_HID_FF is not set | ||
854 | # CONFIG_USB_HIDDEV is not set | ||
855 | |||
856 | # | ||
857 | # USB HID Boot Protocol drivers | ||
858 | # | ||
859 | # CONFIG_USB_KBD is not set | ||
860 | # CONFIG_USB_MOUSE is not set | ||
861 | # CONFIG_USB_AIPTEK is not set | ||
862 | # CONFIG_USB_WACOM is not set | ||
863 | # CONFIG_USB_ACECAD is not set | ||
864 | # CONFIG_USB_KBTAB is not set | ||
865 | # CONFIG_USB_POWERMATE is not set | ||
866 | # CONFIG_USB_MTOUCH is not set | ||
867 | # CONFIG_USB_ITMTOUCH is not set | ||
868 | # CONFIG_USB_EGALAX is not set | ||
869 | # CONFIG_USB_YEALINK is not set | ||
870 | # CONFIG_USB_XPAD is not set | ||
871 | # CONFIG_USB_ATI_REMOTE is not set | ||
872 | # CONFIG_USB_ATI_REMOTE2 is not set | ||
873 | # CONFIG_USB_KEYSPAN_REMOTE is not set | ||
874 | # CONFIG_USB_APPLETOUCH is not set | ||
875 | |||
876 | # | ||
877 | # USB Imaging devices | ||
878 | # | ||
879 | # CONFIG_USB_MDC800 is not set | ||
880 | # CONFIG_USB_MICROTEK is not set | ||
881 | |||
882 | # | ||
883 | # USB Multimedia devices | ||
884 | # | ||
885 | # CONFIG_USB_DABUSB is not set | ||
886 | |||
887 | # | ||
888 | # Video4Linux support is needed for USB Multimedia device support | ||
889 | # | ||
890 | |||
891 | # | ||
892 | # USB Network Adapters | ||
893 | # | ||
894 | # CONFIG_USB_CATC is not set | ||
895 | # CONFIG_USB_KAWETH is not set | ||
896 | # CONFIG_USB_PEGASUS is not set | ||
897 | # CONFIG_USB_RTL8150 is not set | ||
898 | # CONFIG_USB_USBNET is not set | ||
899 | CONFIG_USB_MON=y | ||
900 | |||
901 | # | ||
902 | # USB port drivers | ||
903 | # | ||
904 | |||
905 | # | ||
906 | # USB Serial Converter support | ||
907 | # | ||
908 | # CONFIG_USB_SERIAL is not set | ||
909 | |||
910 | # | ||
911 | # USB Miscellaneous drivers | ||
912 | # | ||
913 | # CONFIG_USB_EMI62 is not set | ||
914 | # CONFIG_USB_EMI26 is not set | ||
915 | # CONFIG_USB_AUERSWALD is not set | ||
916 | # CONFIG_USB_RIO500 is not set | ||
917 | # CONFIG_USB_LEGOTOWER is not set | ||
918 | # CONFIG_USB_LCD is not set | ||
919 | # CONFIG_USB_LED is not set | ||
920 | # CONFIG_USB_CYTHERM is not set | ||
921 | # CONFIG_USB_PHIDGETKIT is not set | ||
922 | # CONFIG_USB_PHIDGETSERVO is not set | ||
923 | # CONFIG_USB_IDMOUSE is not set | ||
924 | # CONFIG_USB_SISUSBVGA is not set | ||
925 | # CONFIG_USB_LD is not set | ||
926 | |||
927 | # | ||
928 | # USB DSL modem support | ||
929 | # | ||
930 | |||
931 | # | ||
932 | # USB Gadget Support | ||
933 | # | ||
934 | # CONFIG_USB_GADGET is not set | ||
935 | |||
936 | # | ||
937 | # MMC/SD Card support | ||
938 | # | ||
939 | # CONFIG_MMC is not set | ||
940 | |||
941 | # | ||
942 | # InfiniBand support | ||
943 | # | ||
944 | # CONFIG_INFINIBAND is not set | ||
945 | |||
946 | # | ||
947 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) | ||
948 | # | ||
949 | |||
950 | # | ||
951 | # File systems | ||
952 | # | ||
953 | CONFIG_EXT2_FS=y | ||
954 | # CONFIG_EXT2_FS_XATTR is not set | ||
955 | # CONFIG_EXT2_FS_XIP is not set | ||
956 | CONFIG_EXT3_FS=y | ||
957 | CONFIG_EXT3_FS_XATTR=y | ||
958 | # CONFIG_EXT3_FS_POSIX_ACL is not set | ||
959 | # CONFIG_EXT3_FS_SECURITY is not set | ||
960 | CONFIG_JBD=y | ||
961 | # CONFIG_JBD_DEBUG is not set | ||
962 | CONFIG_FS_MBCACHE=y | ||
963 | # CONFIG_REISERFS_FS is not set | ||
964 | # CONFIG_JFS_FS is not set | ||
965 | # CONFIG_FS_POSIX_ACL is not set | ||
966 | CONFIG_XFS_FS=y | ||
967 | CONFIG_XFS_QUOTA=y | ||
968 | # CONFIG_XFS_SECURITY is not set | ||
969 | CONFIG_XFS_POSIX_ACL=y | ||
970 | # CONFIG_XFS_RT is not set | ||
971 | # CONFIG_OCFS2_FS is not set | ||
972 | # CONFIG_MINIX_FS is not set | ||
973 | CONFIG_ROMFS_FS=m | ||
974 | CONFIG_INOTIFY=y | ||
975 | # CONFIG_QUOTA is not set | ||
976 | CONFIG_QUOTACTL=y | ||
977 | # CONFIG_DNOTIFY is not set | ||
978 | # CONFIG_AUTOFS_FS is not set | ||
979 | CONFIG_AUTOFS4_FS=y | ||
980 | # CONFIG_FUSE_FS is not set | ||
981 | |||
982 | # | ||
983 | # CD-ROM/DVD Filesystems | ||
984 | # | ||
985 | # CONFIG_ISO9660_FS is not set | ||
986 | # CONFIG_UDF_FS is not set | ||
987 | |||
988 | # | ||
989 | # DOS/FAT/NT Filesystems | ||
990 | # | ||
991 | # CONFIG_MSDOS_FS is not set | ||
992 | # CONFIG_VFAT_FS is not set | ||
993 | # CONFIG_NTFS_FS is not set | ||
994 | |||
995 | # | ||
996 | # Pseudo filesystems | ||
997 | # | ||
998 | CONFIG_PROC_FS=y | ||
999 | CONFIG_PROC_KCORE=y | ||
1000 | CONFIG_SYSFS=y | ||
1001 | CONFIG_TMPFS=y | ||
1002 | # CONFIG_HUGETLB_PAGE is not set | ||
1003 | CONFIG_RAMFS=y | ||
1004 | # CONFIG_RELAYFS_FS is not set | ||
1005 | # CONFIG_CONFIGFS_FS is not set | ||
1006 | |||
1007 | # | ||
1008 | # Miscellaneous filesystems | ||
1009 | # | ||
1010 | # CONFIG_ADFS_FS is not set | ||
1011 | # CONFIG_AFFS_FS is not set | ||
1012 | # CONFIG_HFS_FS is not set | ||
1013 | # CONFIG_HFSPLUS_FS is not set | ||
1014 | # CONFIG_BEFS_FS is not set | ||
1015 | # CONFIG_BFS_FS is not set | ||
1016 | # CONFIG_EFS_FS is not set | ||
1017 | CONFIG_CRAMFS=m | ||
1018 | # CONFIG_VXFS_FS is not set | ||
1019 | # CONFIG_HPFS_FS is not set | ||
1020 | # CONFIG_QNX4FS_FS is not set | ||
1021 | # CONFIG_SYSV_FS is not set | ||
1022 | # CONFIG_UFS_FS is not set | ||
1023 | |||
1024 | # | ||
1025 | # Network File Systems | ||
1026 | # | ||
1027 | CONFIG_NFS_FS=y | ||
1028 | CONFIG_NFS_V3=y | ||
1029 | # CONFIG_NFS_V3_ACL is not set | ||
1030 | # CONFIG_NFS_V4 is not set | ||
1031 | # CONFIG_NFS_DIRECTIO is not set | ||
1032 | # CONFIG_NFSD is not set | ||
1033 | CONFIG_ROOT_NFS=y | ||
1034 | CONFIG_LOCKD=y | ||
1035 | CONFIG_LOCKD_V4=y | ||
1036 | CONFIG_NFS_COMMON=y | ||
1037 | CONFIG_SUNRPC=y | ||
1038 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
1039 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
1040 | # CONFIG_SMB_FS is not set | ||
1041 | # CONFIG_CIFS is not set | ||
1042 | # CONFIG_NCP_FS is not set | ||
1043 | # CONFIG_CODA_FS is not set | ||
1044 | # CONFIG_AFS_FS is not set | ||
1045 | # CONFIG_9P_FS is not set | ||
1046 | |||
1047 | # | ||
1048 | # Partition Types | ||
1049 | # | ||
1050 | # CONFIG_PARTITION_ADVANCED is not set | ||
1051 | CONFIG_MSDOS_PARTITION=y | ||
1052 | |||
1053 | # | ||
1054 | # Native Language Support | ||
1055 | # | ||
1056 | # CONFIG_NLS is not set | ||
1057 | |||
1058 | # | ||
1059 | # Profiling support | ||
1060 | # | ||
1061 | # CONFIG_PROFILING is not set | ||
1062 | |||
1063 | # | ||
1064 | # Kernel hacking | ||
1065 | # | ||
1066 | # CONFIG_PRINTK_TIME is not set | ||
1067 | # CONFIG_MAGIC_SYSRQ is not set | ||
1068 | # CONFIG_DEBUG_KERNEL is not set | ||
1069 | CONFIG_LOG_BUF_SHIFT=14 | ||
1070 | CONFIG_CROSSCOMPILE=y | ||
1071 | CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs" | ||
1072 | |||
1073 | # | ||
1074 | # Security options | ||
1075 | # | ||
1076 | CONFIG_KEYS=y | ||
1077 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
1078 | # CONFIG_SECURITY is not set | ||
1079 | |||
1080 | # | ||
1081 | # Cryptographic options | ||
1082 | # | ||
1083 | # CONFIG_CRYPTO is not set | ||
1084 | |||
1085 | # | ||
1086 | # Hardware crypto devices | ||
1087 | # | ||
1088 | |||
1089 | # | ||
1090 | # Library routines | ||
1091 | # | ||
1092 | # CONFIG_CRC_CCITT is not set | ||
1093 | # CONFIG_CRC16 is not set | ||
1094 | CONFIG_CRC32=y | ||
1095 | # CONFIG_LIBCRC32C is not set | ||
1096 | CONFIG_ZLIB_INFLATE=m | ||
diff --git a/arch/mips/ddb5xxx/ddb5074/Makefile b/arch/mips/ddb5xxx/ddb5074/Makefile index 488206b8d94e..304c02107b46 100644 --- a/arch/mips/ddb5xxx/ddb5074/Makefile +++ b/arch/mips/ddb5xxx/ddb5074/Makefile | |||
@@ -3,6 +3,6 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += setup.o irq.o int-handler.o nile4_pic.o | 6 | obj-y += setup.o irq.o nile4_pic.o |
7 | 7 | ||
8 | EXTRA_AFLAGS := $(CFLAGS) | 8 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/ddb5xxx/ddb5074/int-handler.S b/arch/mips/ddb5xxx/ddb5074/int-handler.S deleted file mode 100644 index a78644150b37..000000000000 --- a/arch/mips/ddb5xxx/ddb5074/int-handler.S +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | /* | ||
2 | * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler | ||
3 | * | ||
4 | * Based on arch/mips/sgi/kernel/indyIRQ.S | ||
5 | * | ||
6 | * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) | ||
7 | * | ||
8 | * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> | ||
9 | * Sony Software Development Center Europe (SDCE), Brussels | ||
10 | */ | ||
11 | #include <asm/asm.h> | ||
12 | #include <asm/mipsregs.h> | ||
13 | #include <asm/regdef.h> | ||
14 | #include <asm/stackframe.h> | ||
15 | |||
16 | /* A lot of complication here is taken away because: | ||
17 | * | ||
18 | * 1) We handle one interrupt and return, sitting in a loop and moving across | ||
19 | * all the pending IRQ bits in the cause register is _NOT_ the answer, the | ||
20 | * common case is one pending IRQ so optimize in that direction. | ||
21 | * | ||
22 | * 2) We need not check against bits in the status register IRQ mask, that | ||
23 | * would make this routine slow as hell. | ||
24 | * | ||
25 | * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in | ||
26 | * between like BSD spl() brain-damage. | ||
27 | * | ||
28 | * Furthermore, the IRQs on the INDY look basically (barring software IRQs | ||
29 | * which we don't use at all) like: | ||
30 | * | ||
31 | * MIPS IRQ Source | ||
32 | * -------- ------ | ||
33 | * 0 Software (ignored) | ||
34 | * 1 Software (ignored) | ||
35 | * 2 Local IRQ level zero | ||
36 | * 3 Local IRQ level one | ||
37 | * 4 8254 Timer zero | ||
38 | * 5 8254 Timer one | ||
39 | * 6 Bus Error | ||
40 | * 7 R4k timer (what we use) | ||
41 | * | ||
42 | * We handle the IRQ according to _our_ priority which is: | ||
43 | * | ||
44 | * Highest ---- R4k Timer | ||
45 | * Local IRQ zero | ||
46 | * Local IRQ one | ||
47 | * Bus Error | ||
48 | * 8254 Timer zero | ||
49 | * Lowest ---- 8254 Timer one | ||
50 | * | ||
51 | * then we just return, if multiple IRQs are pending then we will just take | ||
52 | * another exception, big deal. | ||
53 | */ | ||
54 | |||
55 | .text | ||
56 | .set noreorder | ||
57 | .set noat | ||
58 | .align 5 | ||
59 | NESTED(ddbIRQ, PT_SIZE, sp) | ||
60 | SAVE_ALL | ||
61 | CLI | ||
62 | .set at | ||
63 | mfc0 s0, CP0_CAUSE # get irq mask | ||
64 | |||
65 | #if 1 | ||
66 | mfc0 t2,CP0_STATUS # get enabled interrupts | ||
67 | and s0,t2 # isolate allowed ones | ||
68 | #endif | ||
69 | /* First we check for r4k counter/timer IRQ. */ | ||
70 | andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero | ||
71 | beq a0, zero, 1f | ||
72 | andi a0, s0, CAUSEF_IP3 # delay slot, check local level one | ||
73 | |||
74 | /* Wheee, local level zero interrupt. */ | ||
75 | jal ddb_local0_irqdispatch | ||
76 | move a0, sp # delay slot | ||
77 | |||
78 | j ret_from_irq | ||
79 | nop # delay slot | ||
80 | |||
81 | 1: | ||
82 | beq a0, zero, 1f | ||
83 | andi a0, s0, CAUSEF_IP6 # delay slot, check bus error | ||
84 | |||
85 | /* Wheee, local level one interrupt. */ | ||
86 | move a0, sp | ||
87 | jal ddb_local1_irqdispatch | ||
88 | nop | ||
89 | |||
90 | j ret_from_irq | ||
91 | nop | ||
92 | |||
93 | 1: | ||
94 | beq a0, zero, 1f | ||
95 | nop | ||
96 | |||
97 | /* Wheee, an asynchronous bus error... */ | ||
98 | move a0, sp | ||
99 | jal ddb_buserror_irq | ||
100 | nop | ||
101 | |||
102 | j ret_from_irq | ||
103 | nop | ||
104 | |||
105 | 1: | ||
106 | /* Here by mistake? This is possible, what can happen | ||
107 | * is that by the time we take the exception the IRQ | ||
108 | * pin goes low, so just leave if this is the case. | ||
109 | */ | ||
110 | andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) | ||
111 | beq a0, zero, 1f | ||
112 | |||
113 | /* Must be one of the 8254 timers... */ | ||
114 | move a0, sp | ||
115 | jal ddb_8254timer_irq | ||
116 | nop | ||
117 | 1: | ||
118 | j ret_from_irq | ||
119 | nop | ||
120 | END(ddbIRQ) | ||
diff --git a/arch/mips/ddb5xxx/ddb5074/irq.c b/arch/mips/ddb5xxx/ddb5074/irq.c index 45088a1be414..60c087b7738c 100644 --- a/arch/mips/ddb5xxx/ddb5074/irq.c +++ b/arch/mips/ddb5xxx/ddb5074/irq.c | |||
@@ -21,8 +21,6 @@ | |||
21 | #include <asm/ddb5xxx/ddb5074.h> | 21 | #include <asm/ddb5xxx/ddb5074.h> |
22 | 22 | ||
23 | 23 | ||
24 | extern asmlinkage void ddbIRQ(void); | ||
25 | |||
26 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; | 24 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; |
27 | 25 | ||
28 | #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ | 26 | #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ |
@@ -90,7 +88,7 @@ static void m1543_irq_setup(void) | |||
90 | 88 | ||
91 | } | 89 | } |
92 | 90 | ||
93 | void ddb_local0_irqdispatch(struct pt_regs *regs) | 91 | static void ddb_local0_irqdispatch(struct pt_regs *regs) |
94 | { | 92 | { |
95 | u32 mask; | 93 | u32 mask; |
96 | int nile4_irq; | 94 | int nile4_irq; |
@@ -118,29 +116,41 @@ void ddb_local0_irqdispatch(struct pt_regs *regs) | |||
118 | } | 116 | } |
119 | } | 117 | } |
120 | 118 | ||
121 | void ddb_local1_irqdispatch(void) | 119 | static void ddb_local1_irqdispatch(void) |
122 | { | 120 | { |
123 | printk("ddb_local1_irqdispatch called\n"); | 121 | printk("ddb_local1_irqdispatch called\n"); |
124 | } | 122 | } |
125 | 123 | ||
126 | void ddb_buserror_irq(void) | 124 | static void ddb_buserror_irq(void) |
127 | { | 125 | { |
128 | printk("ddb_buserror_irq called\n"); | 126 | printk("ddb_buserror_irq called\n"); |
129 | } | 127 | } |
130 | 128 | ||
131 | void ddb_8254timer_irq(void) | 129 | static void ddb_8254timer_irq(void) |
132 | { | 130 | { |
133 | printk("ddb_8254timer_irq called\n"); | 131 | printk("ddb_8254timer_irq called\n"); |
134 | } | 132 | } |
135 | 133 | ||
134 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
135 | { | ||
136 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
137 | |||
138 | if (pending & CAUSEF_IP2) | ||
139 | ddb_local0_irqdispatch(regs); | ||
140 | else if (pending & CAUSEF_IP3) | ||
141 | ddb_local1_irqdispatch(); | ||
142 | else if (pending & CAUSEF_IP6) | ||
143 | ddb_buserror_irq(); | ||
144 | else if (pending & (CAUSEF_IP4 | CAUSEF_IP5)) | ||
145 | ddb_8254timer_irq(); | ||
146 | } | ||
147 | |||
136 | void __init arch_init_irq(void) | 148 | void __init arch_init_irq(void) |
137 | { | 149 | { |
138 | /* setup cascade interrupts */ | 150 | /* setup cascade interrupts */ |
139 | setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade); | 151 | setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade); |
140 | setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade); | 152 | setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade); |
141 | 153 | ||
142 | set_except_vector(0, ddbIRQ); | ||
143 | |||
144 | nile4_irq_setup(NILE4_IRQ_BASE); | 154 | nile4_irq_setup(NILE4_IRQ_BASE); |
145 | m1543_irq_setup(); | 155 | m1543_irq_setup(); |
146 | init_i8259_irqs(); | 156 | init_i8259_irqs(); |
diff --git a/arch/mips/ddb5xxx/ddb5476/Makefile b/arch/mips/ddb5xxx/ddb5476/Makefile index 61eec363cb02..ab0312cb47b4 100644 --- a/arch/mips/ddb5xxx/ddb5476/Makefile +++ b/arch/mips/ddb5xxx/ddb5476/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += setup.o irq.o int-handler.o nile4_pic.o vrc5476_irq.o | 6 | obj-y += setup.o irq.o nile4_pic.o vrc5476_irq.o |
7 | obj-$(CONFIG_KGDB) += dbg_io.o | 7 | obj-$(CONFIG_KGDB) += dbg_io.o |
8 | 8 | ||
9 | EXTRA_AFLAGS := $(CFLAGS) | 9 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/ddb5xxx/ddb5476/int-handler.S b/arch/mips/ddb5xxx/ddb5476/int-handler.S deleted file mode 100644 index 12c292e189ba..000000000000 --- a/arch/mips/ddb5xxx/ddb5476/int-handler.S +++ /dev/null | |||
@@ -1,112 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: jsun@mvista.com or jsun@junsun.net | ||
4 | * | ||
5 | * First-level interrupt dispatcher for ddb5476 | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | |||
18 | #include <asm/ddb5xxx/ddb5476.h> | ||
19 | |||
20 | /* | ||
21 | * first level interrupt dispatcher for ocelot board - | ||
22 | * We check for the timer first, then check PCI ints A and D. | ||
23 | * Then check for serial IRQ and fall through. | ||
24 | */ | ||
25 | .align 5 | ||
26 | NESTED(ddb5476_handle_int, PT_SIZE, sp) | ||
27 | SAVE_ALL | ||
28 | CLI | ||
29 | .set at | ||
30 | .set noreorder | ||
31 | mfc0 t0, CP0_CAUSE | ||
32 | mfc0 t2, CP0_STATUS | ||
33 | |||
34 | and t0, t2 | ||
35 | |||
36 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
37 | bnez t1, ll_cpu_ip7 | ||
38 | andi t1, t0, STATUSF_IP2 /* vrc5476 & i8259 */ | ||
39 | bnez t1, ll_cpu_ip2 | ||
40 | andi t1, t0, STATUSF_IP3 | ||
41 | bnez t1, ll_cpu_ip3 | ||
42 | andi t1, t0, STATUSF_IP4 | ||
43 | bnez t1, ll_cpu_ip4 | ||
44 | andi t1, t0, STATUSF_IP5 | ||
45 | bnez t1, ll_cpu_ip5 | ||
46 | andi t1, t0, STATUSF_IP6 | ||
47 | bnez t1, ll_cpu_ip6 | ||
48 | andi t1, t0, STATUSF_IP0 /* software int 0 */ | ||
49 | bnez t1, ll_cpu_ip0 | ||
50 | andi t1, t0, STATUSF_IP1 /* software int 1 */ | ||
51 | bnez t1, ll_cpu_ip1 | ||
52 | nop | ||
53 | |||
54 | .set reorder | ||
55 | |||
56 | /* wrong alarm or masked ... */ | ||
57 | // j spurious_interrupt | ||
58 | move a0, sp | ||
59 | jal vrc5476_irq_dispatch | ||
60 | j ret_from_irq | ||
61 | nop | ||
62 | |||
63 | .align 5 | ||
64 | |||
65 | ll_cpu_ip0: | ||
66 | li a0, CPU_IRQ_BASE + 0 | ||
67 | move a1, sp | ||
68 | jal do_IRQ | ||
69 | j ret_from_irq | ||
70 | |||
71 | ll_cpu_ip1: | ||
72 | li a0, CPU_IRQ_BASE + 1 | ||
73 | move a1, sp | ||
74 | jal do_IRQ | ||
75 | j ret_from_irq | ||
76 | |||
77 | ll_cpu_ip2: /* jump to second-level dispatching */ | ||
78 | move a0, sp | ||
79 | jal vrc5476_irq_dispatch | ||
80 | j ret_from_irq | ||
81 | |||
82 | ll_cpu_ip3: | ||
83 | li a0, CPU_IRQ_BASE + 3 | ||
84 | move a1, sp | ||
85 | jal do_IRQ | ||
86 | j ret_from_irq | ||
87 | |||
88 | ll_cpu_ip4: | ||
89 | li a0, CPU_IRQ_BASE + 4 | ||
90 | move a1, sp | ||
91 | jal do_IRQ | ||
92 | j ret_from_irq | ||
93 | |||
94 | ll_cpu_ip5: | ||
95 | li a0, CPU_IRQ_BASE + 5 | ||
96 | move a1, sp | ||
97 | jal do_IRQ | ||
98 | j ret_from_irq | ||
99 | |||
100 | ll_cpu_ip6: | ||
101 | li a0, CPU_IRQ_BASE + 6 | ||
102 | move a1, sp | ||
103 | jal do_IRQ | ||
104 | j ret_from_irq | ||
105 | |||
106 | ll_cpu_ip7: | ||
107 | li a0, CPU_IRQ_BASE + 7 | ||
108 | move a1, sp | ||
109 | jal do_IRQ | ||
110 | j ret_from_irq | ||
111 | |||
112 | END(ddb5476_handle_int) | ||
diff --git a/arch/mips/ddb5xxx/ddb5476/irq.c b/arch/mips/ddb5xxx/ddb5476/irq.c index 5388b5868c4a..7583a1f30711 100644 --- a/arch/mips/ddb5xxx/ddb5476/irq.c +++ b/arch/mips/ddb5xxx/ddb5476/irq.c | |||
@@ -110,11 +110,36 @@ static void nile4_irq_setup(void) | |||
110 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; | 110 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; |
111 | static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; | 111 | static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; |
112 | 112 | ||
113 | extern asmlinkage void ddb5476_handle_int(void); | ||
114 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); | 113 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); |
115 | extern void mips_cpu_irq_init(u32 irq_base); | 114 | extern void mips_cpu_irq_init(u32 irq_base); |
116 | extern void vrc5476_irq_init(u32 irq_base); | 115 | extern void vrc5476_irq_init(u32 irq_base); |
117 | 116 | ||
117 | extern void vrc5476_irq_dispatch(struct pt_regs *regs); | ||
118 | |||
119 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
120 | { | ||
121 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
122 | |||
123 | if (pending & STATUSF_IP7) | ||
124 | do_IRQ(CPU_IRQ_BASE + 7, regs); | ||
125 | else if (pending & STATUSF_IP2) | ||
126 | vrc5476_irq_dispatch(regs); | ||
127 | else if (pending & STATUSF_IP3) | ||
128 | do_IRQ(CPU_IRQ_BASE + 3, regs); | ||
129 | else if (pending & STATUSF_IP4) | ||
130 | do_IRQ(CPU_IRQ_BASE + 4, regs); | ||
131 | else if (pending & STATUSF_IP5) | ||
132 | do_IRQ(CPU_IRQ_BASE + 5, regs); | ||
133 | else if (pending & STATUSF_IP6) | ||
134 | do_IRQ(CPU_IRQ_BASE + 6, regs); | ||
135 | else if (pending & STATUSF_IP0) | ||
136 | do_IRQ(CPU_IRQ_BASE, regs); | ||
137 | else if (pending & STATUSF_IP1) | ||
138 | do_IRQ(CPU_IRQ_BASE + 1, regs); | ||
139 | |||
140 | vrc5476_irq_dispatch(regs); | ||
141 | } | ||
142 | |||
118 | void __init arch_init_irq(void) | 143 | void __init arch_init_irq(void) |
119 | { | 144 | { |
120 | /* hardware initialization */ | 145 | /* hardware initialization */ |
@@ -137,7 +162,4 @@ void __init arch_init_irq(void) | |||
137 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error); | 162 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error); |
138 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error); | 163 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error); |
139 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error); | 164 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error); |
140 | |||
141 | /* setup the grandpa intr vector */ | ||
142 | set_except_vector(0, ddb5476_handle_int); | ||
143 | } | 165 | } |
diff --git a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c index f66fe5b58636..a3c5e7b18018 100644 --- a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c +++ b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c | |||
@@ -77,11 +77,9 @@ vrc5476_irq_init(u32 base) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | 79 | ||
80 | asmlinkage void | 80 | void |
81 | vrc5476_irq_dispatch(struct pt_regs *regs) | 81 | vrc5476_irq_dispatch(struct pt_regs *regs) |
82 | { | 82 | { |
83 | extern void spurious_interrupt(void); | ||
84 | |||
85 | u32 mask; | 83 | u32 mask; |
86 | int nile4_irq; | 84 | int nile4_irq; |
87 | 85 | ||
@@ -107,5 +105,5 @@ vrc5476_irq_dispatch(struct pt_regs *regs) | |||
107 | return; | 105 | return; |
108 | } | 106 | } |
109 | } | 107 | } |
110 | spurious_interrupt(); | 108 | spurious_interrupt(regs); |
111 | } | 109 | } |
diff --git a/arch/mips/ddb5xxx/ddb5477/Makefile b/arch/mips/ddb5xxx/ddb5477/Makefile index b79b43c9f93b..ea68815ad17a 100644 --- a/arch/mips/ddb5xxx/ddb5477/Makefile +++ b/arch/mips/ddb5xxx/ddb5477/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for NEC DDB-Vrc5477 board | 2 | # Makefile for NEC DDB-Vrc5477 board |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += int-handler.o irq.o irq_5477.o setup.o lcd44780.o | 5 | obj-y += irq.o irq_5477.o setup.o lcd44780.o |
6 | 6 | ||
7 | obj-$(CONFIG_RUNTIME_DEBUG) += debug.o | 7 | obj-$(CONFIG_RUNTIME_DEBUG) += debug.o |
8 | obj-$(CONFIG_KGDB) += kgdb_io.o | 8 | obj-$(CONFIG_KGDB) += kgdb_io.o |
diff --git a/arch/mips/ddb5xxx/ddb5477/int-handler.S b/arch/mips/ddb5xxx/ddb5477/int-handler.S deleted file mode 100644 index a2502a14400e..000000000000 --- a/arch/mips/ddb5xxx/ddb5477/int-handler.S +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: jsun@mvista.com or jsun@junsun.net | ||
4 | * | ||
5 | * First-level interrupt dispatcher for ddb5477 | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | #include <asm/ddb5xxx/ddb5477.h> | ||
18 | |||
19 | /* | ||
20 | * first level interrupt dispatcher for ocelot board - | ||
21 | * We check for the timer first, then check PCI ints A and D. | ||
22 | * Then check for serial IRQ and fall through. | ||
23 | */ | ||
24 | .align 5 | ||
25 | NESTED(ddb5477_handle_int, PT_SIZE, sp) | ||
26 | SAVE_ALL | ||
27 | CLI | ||
28 | .set at | ||
29 | .set noreorder | ||
30 | mfc0 t0, CP0_CAUSE | ||
31 | mfc0 t2, CP0_STATUS | ||
32 | |||
33 | and t0, t2 | ||
34 | |||
35 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
36 | bnez t1, ll_cputimer_irq | ||
37 | andi t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 ) | ||
38 | bnez t1, ll_vrc5477_irq | ||
39 | andi t1, t0, STATUSF_IP0 /* software int 0 */ | ||
40 | bnez t1, ll_cpu_ip0 | ||
41 | andi t1, t0, STATUSF_IP1 /* software int 1 */ | ||
42 | bnez t1, ll_cpu_ip1 | ||
43 | nop | ||
44 | .set reorder | ||
45 | |||
46 | /* wrong alarm or masked ... */ | ||
47 | j spurious_interrupt | ||
48 | nop | ||
49 | END(ddb5477_handle_int) | ||
50 | |||
51 | .align 5 | ||
52 | |||
53 | ll_vrc5477_irq: | ||
54 | move a0, sp | ||
55 | jal vrc5477_irq_dispatch | ||
56 | j ret_from_irq | ||
57 | |||
58 | ll_cputimer_irq: | ||
59 | li a0, CPU_IRQ_BASE + 7 | ||
60 | move a1, sp | ||
61 | jal do_IRQ | ||
62 | j ret_from_irq | ||
63 | |||
64 | |||
65 | ll_cpu_ip0: | ||
66 | li a0, CPU_IRQ_BASE + 0 | ||
67 | move a1, sp | ||
68 | jal do_IRQ | ||
69 | j ret_from_irq | ||
70 | |||
71 | ll_cpu_ip1: | ||
72 | li a0, CPU_IRQ_BASE + 1 | ||
73 | move a1, sp | ||
74 | jal do_IRQ | ||
75 | j ret_from_irq | ||
diff --git a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c index 9ffe1a9142ca..de433cf9fb50 100644 --- a/arch/mips/ddb5xxx/ddb5477/irq.c +++ b/arch/mips/ddb5xxx/ddb5477/irq.c | |||
@@ -75,7 +75,6 @@ set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger) | |||
75 | 75 | ||
76 | extern void vrc5477_irq_init(u32 base); | 76 | extern void vrc5477_irq_init(u32 base); |
77 | extern void mips_cpu_irq_init(u32 base); | 77 | extern void mips_cpu_irq_init(u32 base); |
78 | extern asmlinkage void ddb5477_handle_int(void); | ||
79 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); | 78 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); |
80 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; | 79 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; |
81 | 80 | ||
@@ -135,9 +134,6 @@ void __init arch_init_irq(void) | |||
135 | /* setup cascade interrupts */ | 134 | /* setup cascade interrupts */ |
136 | setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); | 135 | setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); |
137 | setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); | 136 | setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); |
138 | |||
139 | /* hook up the first-level interrupt handler */ | ||
140 | set_except_vector(0, ddb5477_handle_int); | ||
141 | } | 137 | } |
142 | 138 | ||
143 | u8 i8259_interrupt_ack(void) | 139 | u8 i8259_interrupt_ack(void) |
@@ -159,7 +155,7 @@ u8 i8259_interrupt_ack(void) | |||
159 | * the first level int-handler will jump here if it is a vrc5477 irq | 155 | * the first level int-handler will jump here if it is a vrc5477 irq |
160 | */ | 156 | */ |
161 | #define NUM_5477_IRQS 32 | 157 | #define NUM_5477_IRQS 32 |
162 | asmlinkage void | 158 | static void |
163 | vrc5477_irq_dispatch(struct pt_regs *regs) | 159 | vrc5477_irq_dispatch(struct pt_regs *regs) |
164 | { | 160 | { |
165 | u32 intStatus; | 161 | u32 intStatus; |
@@ -197,3 +193,21 @@ vrc5477_irq_dispatch(struct pt_regs *regs) | |||
197 | } | 193 | } |
198 | } | 194 | } |
199 | } | 195 | } |
196 | |||
197 | #define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6) | ||
198 | |||
199 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
200 | { | ||
201 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
202 | |||
203 | if (pending & STATUSF_IP7) | ||
204 | do_IRQ(CPU_IRQ_BASE + 7, regs); | ||
205 | else if (pending & VR5477INTS) | ||
206 | vrc5477_irq_dispatch(regs); | ||
207 | else if (pending & STATUSF_IP0) | ||
208 | do_IRQ(CPU_IRQ_BASE, regs); | ||
209 | else if (pending & STATUSF_IP1) | ||
210 | do_IRQ(CPU_IRQ_BASE + 1, regs); | ||
211 | else | ||
212 | spurious_interrupt(regs); | ||
213 | } | ||
diff --git a/arch/mips/dec/boot/decstation.c b/arch/mips/dec/boot/decstation.c index 56fd4277555e..4db8bacaf22d 100644 --- a/arch/mips/dec/boot/decstation.c +++ b/arch/mips/dec/boot/decstation.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/mips/dec/decstation.c | 2 | * arch/mips/dec/decstation.c |
3 | */ | 3 | */ |
4 | #include <asm/sections.h> | ||
4 | 5 | ||
5 | #define RELOC | 6 | #define RELOC |
6 | #define INITRD | 7 | #define INITRD |
@@ -24,7 +25,7 @@ | |||
24 | #define INITRD_START (*(unsigned long *) (PARAM+0x218)) | 25 | #define INITRD_START (*(unsigned long *) (PARAM+0x218)) |
25 | #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) | 26 | #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) |
26 | 27 | ||
27 | extern int _ftext, _end; /* begin and end of kernel image */ | 28 | extern int _ftext; /* begin and end of kernel image */ |
28 | extern void kernel_entry(int, char **, unsigned long, int *); | 29 | extern void kernel_entry(int, char **, unsigned long, int *); |
29 | 30 | ||
30 | void * memcpy(void * dest, const void *src, unsigned int count) | 31 | void * memcpy(void * dest, const void *src, unsigned int count) |
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S index 41fa372007bf..e8ec93e33fe6 100644 --- a/arch/mips/dec/int-handler.S +++ b/arch/mips/dec/int-handler.S | |||
@@ -36,7 +36,7 @@ | |||
36 | .text | 36 | .text |
37 | .set noreorder | 37 | .set noreorder |
38 | /* | 38 | /* |
39 | * decstation_handle_int: Interrupt handler for DECstations | 39 | * plat_irq_dispatch: Interrupt handler for DECstations |
40 | * | 40 | * |
41 | * We follow the model in the Indy interrupt code by David Miller, where he | 41 | * We follow the model in the Indy interrupt code by David Miller, where he |
42 | * says: a lot of complication here is taken away because: | 42 | * says: a lot of complication here is taken away because: |
@@ -125,11 +125,7 @@ | |||
125 | * just take another exception, big deal. | 125 | * just take another exception, big deal. |
126 | */ | 126 | */ |
127 | .align 5 | 127 | .align 5 |
128 | NESTED(decstation_handle_int, PT_SIZE, ra) | 128 | NESTED(plat_irq_dispatch, PT_SIZE, ra) |
129 | .set noat | ||
130 | SAVE_ALL | ||
131 | CLI # TEST: interrupts should be off | ||
132 | .set at | ||
133 | .set noreorder | 129 | .set noreorder |
134 | 130 | ||
135 | /* | 131 | /* |
@@ -282,9 +278,11 @@ fpu: | |||
282 | #endif | 278 | #endif |
283 | 279 | ||
284 | spurious: | 280 | spurious: |
285 | j spurious_interrupt | 281 | jal spurious_interrupt |
286 | nop | 282 | nop |
287 | END(decstation_handle_int) | 283 | j ret_from_irq |
284 | nop | ||
285 | END(plat_irq_dispatch) | ||
288 | 286 | ||
289 | /* | 287 | /* |
290 | * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl | 288 | * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl |
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c index 7c1ca8f6330e..ad5d436d80c1 100644 --- a/arch/mips/dec/setup.c +++ b/arch/mips/dec/setup.c | |||
@@ -48,8 +48,6 @@ extern void dec_machine_halt(void); | |||
48 | extern void dec_machine_power_off(void); | 48 | extern void dec_machine_power_off(void); |
49 | extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs); | 49 | extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs); |
50 | 50 | ||
51 | extern asmlinkage void decstation_handle_int(void); | ||
52 | |||
53 | unsigned long dec_kn_slot_base, dec_kn_slot_size; | 51 | unsigned long dec_kn_slot_base, dec_kn_slot_size; |
54 | 52 | ||
55 | EXPORT_SYMBOL(dec_kn_slot_base); | 53 | EXPORT_SYMBOL(dec_kn_slot_base); |
@@ -744,7 +742,6 @@ void __init arch_init_irq(void) | |||
744 | panic("Don't know how to set this up!"); | 742 | panic("Don't know how to set this up!"); |
745 | break; | 743 | break; |
746 | } | 744 | } |
747 | set_except_vector(0, decstation_handle_int); | ||
748 | 745 | ||
749 | /* Free the FPU interrupt if the exception is present. */ | 746 | /* Free the FPU interrupt if the exception is present. */ |
750 | if (!cpu_has_nofpuex) { | 747 | if (!cpu_has_nofpuex) { |
diff --git a/arch/mips/galileo-boards/ev96100/Makefile b/arch/mips/galileo-boards/ev96100/Makefile index 58c02f9db69d..cd868ec78cbc 100644 --- a/arch/mips/galileo-boards/ev96100/Makefile +++ b/arch/mips/galileo-boards/ev96100/Makefile | |||
@@ -6,4 +6,4 @@ | |||
6 | # Makefile for the Galileo EV96100 board. | 6 | # Makefile for the Galileo EV96100 board. |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += init.o irq.o puts.o reset.o time.o int-handler.o setup.o | 9 | obj-y += init.o irq.o puts.o reset.o time.o setup.o |
diff --git a/arch/mips/galileo-boards/ev96100/int-handler.S b/arch/mips/galileo-boards/ev96100/int-handler.S deleted file mode 100644 index ff4d10a38859..000000000000 --- a/arch/mips/galileo-boards/ev96100/int-handler.S +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | #include <asm/asm.h> | ||
2 | #include <asm/mipsregs.h> | ||
3 | #include <asm/regdef.h> | ||
4 | #include <asm/stackframe.h> | ||
5 | |||
6 | .set noat | ||
7 | .align 5 | ||
8 | |||
9 | NESTED(ev96100IRQ, PT_SIZE, sp) | ||
10 | SAVE_ALL | ||
11 | CLI # Important: mark KERNEL mode ! | ||
12 | |||
13 | mfc0 t0, CP0_CAUSE # get pending interrupts | ||
14 | mfc0 t1, CP0_STATUS # get enabled interrupts | ||
15 | and t0, t1 # isolate allowed ones | ||
16 | |||
17 | # FIX ME add R7000 extensions | ||
18 | andi t0,0xff00 # isolate pending bits | ||
19 | andi a0, t0, CAUSEF_IP7 | ||
20 | beq a0, zero, 1f | ||
21 | move a0, sp | ||
22 | jal mips_timer_interrupt | ||
23 | j ret_from_irq | ||
24 | |||
25 | 1: beqz t0, 3f # spurious interrupt | ||
26 | |||
27 | move a0, t0 | ||
28 | move a1, sp | ||
29 | jal ev96100_cpu_irq | ||
30 | j ret_from_irq | ||
31 | |||
32 | 3: j spurious_interrupt | ||
33 | END(ev96100IRQ) | ||
diff --git a/arch/mips/galileo-boards/ev96100/irq.c b/arch/mips/galileo-boards/ev96100/irq.c index 97bf094da4fe..ee5d6720f23b 100644 --- a/arch/mips/galileo-boards/ev96100/irq.c +++ b/arch/mips/galileo-boards/ev96100/irq.c | |||
@@ -40,8 +40,6 @@ | |||
40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
41 | #include <asm/irq_cpu.h> | 41 | #include <asm/irq_cpu.h> |
42 | 42 | ||
43 | extern asmlinkage void ev96100IRQ(void); | ||
44 | |||
45 | static inline unsigned int ffz8(unsigned int word) | 43 | static inline unsigned int ffz8(unsigned int word) |
46 | { | 44 | { |
47 | unsigned long k; | 45 | unsigned long k; |
@@ -54,13 +52,26 @@ static inline unsigned int ffz8(unsigned int word) | |||
54 | return k; | 52 | return k; |
55 | } | 53 | } |
56 | 54 | ||
57 | asmlinkage void ev96100_cpu_irq(unsigned int pendin) | 55 | extern void mips_timer_interrupt(struct pt_regs *regs); |
56 | |||
57 | asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs) | ||
58 | { | 58 | { |
59 | do_IRQ(ffz8(pending >> 8), regs); | 59 | do_IRQ(ffz8(pending >> 8), regs); |
60 | } | 60 | } |
61 | 61 | ||
62 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
63 | { | ||
64 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
65 | |||
66 | if (pending & CAUSEF_IP7) | ||
67 | mips_timer_interrupt(regs); | ||
68 | else if (pending) | ||
69 | ev96100_cpu_irq(pending, regs); | ||
70 | else | ||
71 | spurious_interrupt(regs); | ||
72 | } | ||
73 | |||
62 | void __init arch_init_irq(void) | 74 | void __init arch_init_irq(void) |
63 | { | 75 | { |
64 | set_except_vector(0, ev96100IRQ); | ||
65 | mips_cpu_irq_init(0); | 76 | mips_cpu_irq_init(0); |
66 | } | 77 | } |
diff --git a/arch/mips/gt64120/ev64120/Makefile b/arch/mips/gt64120/ev64120/Makefile index ebe91c57e173..b2c53a8f8718 100644 --- a/arch/mips/gt64120/ev64120/Makefile +++ b/arch/mips/gt64120/ev64120/Makefile | |||
@@ -6,6 +6,6 @@ | |||
6 | # Makefile for the Galileo EV64120 board. | 6 | # Makefile for the Galileo EV64120 board. |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += int-handler.o irq.o promcon.o reset.o serialGT.o setup.o | 9 | obj-y += irq.o promcon.o reset.o serialGT.o setup.o |
10 | 10 | ||
11 | EXTRA_AFLAGS := $(CFLAGS) | 11 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/gt64120/ev64120/int-handler.S b/arch/mips/gt64120/ev64120/int-handler.S deleted file mode 100644 index 752435faf2de..000000000000 --- a/arch/mips/gt64120/ev64120/int-handler.S +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | /* | ||
2 | * int-handler.S | ||
3 | * | ||
4 | * Based on the cobalt handler. | ||
5 | */ | ||
6 | #include <asm/asm.h> | ||
7 | #include <asm/mipsregs.h> | ||
8 | #include <asm/addrspace.h> | ||
9 | #include <asm/regdef.h> | ||
10 | #include <asm/stackframe.h> | ||
11 | |||
12 | /* | ||
13 | * galileo_handle_int - | ||
14 | * We check for the timer first, then check PCI ints A and D. | ||
15 | * Then check for serial IRQ and fall through. | ||
16 | */ | ||
17 | .align 5 | ||
18 | .set reorder | ||
19 | .set noat | ||
20 | NESTED(galileo_handle_int, PT_SIZE, sp) | ||
21 | SAVE_ALL | ||
22 | CLI | ||
23 | .set at | ||
24 | mfc0 t0,CP0_CAUSE | ||
25 | mfc0 t2,CP0_STATUS | ||
26 | |||
27 | and t0,t2 | ||
28 | |||
29 | andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */ | ||
30 | bnez t1,ll_gt64120_irq | ||
31 | andi t1,t0,STATUSF_IP2 /* int0 hardware line */ | ||
32 | bnez t1,ll_pci_intA | ||
33 | andi t1,t0,STATUSF_IP5 /* int3 hardware line */ | ||
34 | bnez t1,ll_pci_intD | ||
35 | andi t1,t0,STATUSF_IP6 /* int4 hardware line */ | ||
36 | bnez t1,ll_serial_irq | ||
37 | andi t1,t0,STATUSF_IP7 /* compare int */ | ||
38 | bnez t1,ll_compare_irq | ||
39 | nop | ||
40 | |||
41 | /* wrong alarm or masked ... */ | ||
42 | j spurious_interrupt | ||
43 | nop | ||
44 | END(galileo_handle_int) | ||
45 | |||
46 | |||
47 | .align 5 | ||
48 | .set reorder | ||
49 | ll_gt64120_irq: | ||
50 | li a0,4 | ||
51 | move a1,sp | ||
52 | jal do_IRQ | ||
53 | nop | ||
54 | j ret_from_irq | ||
55 | nop | ||
56 | |||
57 | .align 5 | ||
58 | .set reorder | ||
59 | ll_compare_irq: | ||
60 | li a0,7 | ||
61 | move a1,sp | ||
62 | jal do_IRQ | ||
63 | nop | ||
64 | j ret_from_irq | ||
65 | nop | ||
66 | |||
67 | .align 5 | ||
68 | .set reorder | ||
69 | ll_pci_intA: | ||
70 | move a0,sp | ||
71 | jal pci_intA | ||
72 | nop | ||
73 | j ret_from_irq | ||
74 | nop | ||
75 | |||
76 | #if 0 | ||
77 | .align 5 | ||
78 | .set reorder | ||
79 | ll_pci_intB: | ||
80 | move a0,sp | ||
81 | jal pci_intB | ||
82 | nop | ||
83 | j ret_from_irq | ||
84 | nop | ||
85 | |||
86 | .align 5 | ||
87 | .set reorder | ||
88 | ll_pci_intC: | ||
89 | move a0,sp | ||
90 | jal pci_intC | ||
91 | nop | ||
92 | j ret_from_irq | ||
93 | nop | ||
94 | #endif | ||
95 | |||
96 | .align 5 | ||
97 | .set reorder | ||
98 | ll_pci_intD: | ||
99 | move a0,sp | ||
100 | jal pci_intD | ||
101 | nop | ||
102 | j ret_from_irq | ||
103 | nop | ||
104 | |||
105 | .align 5 | ||
106 | .set reorder | ||
107 | ll_serial_irq: | ||
108 | li a0,6 | ||
109 | move a1,sp | ||
110 | jal do_IRQ | ||
111 | nop | ||
112 | j ret_from_irq | ||
113 | nop | ||
diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c index 3b186159b21a..46c468b26b30 100644 --- a/arch/mips/gt64120/ev64120/irq.c +++ b/arch/mips/gt64120/ev64120/irq.c | |||
@@ -46,14 +46,22 @@ | |||
46 | #include <asm/system.h> | 46 | #include <asm/system.h> |
47 | #include <asm/gt64120.h> | 47 | #include <asm/gt64120.h> |
48 | 48 | ||
49 | asmlinkage inline void pci_intA(struct pt_regs *regs) | 49 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
50 | { | 50 | { |
51 | do_IRQ(GT_INTA, regs); | 51 | unsigned int pending = read_c0_status() & read_c0_cause(); |
52 | } | 52 | |
53 | 53 | if (pending & STATUSF_IP4) /* int2 hardware line (timer) */ | |
54 | asmlinkage inline void pci_intD(struct pt_regs *regs) | 54 | do_IRQ(4, regs); |
55 | { | 55 | else if (pending & STATUSF_IP2) /* int0 hardware line */ |
56 | do_IRQ(GT_INTD, regs); | 56 | do_IRQ(GT_INTA, regs); |
57 | else if (pending & STATUSF_IP5) /* int3 hardware line */ | ||
58 | do_IRQ(GT_INTD, regs); | ||
59 | else if (pending & STATUSF_IP6) /* int4 hardware line */ | ||
60 | do_IRQ(6, regs); | ||
61 | else if (pending & STATUSF_IP7) /* compare int */ | ||
62 | do_IRQ(7, regs); | ||
63 | else | ||
64 | spurious_interrupt(regs); | ||
57 | } | 65 | } |
58 | 66 | ||
59 | static void disable_ev64120_irq(unsigned int irq_nr) | 67 | static void disable_ev64120_irq(unsigned int irq_nr) |
@@ -109,16 +117,11 @@ static struct hw_interrupt_type ev64120_irq_type = { | |||
109 | 117 | ||
110 | void gt64120_irq_setup(void) | 118 | void gt64120_irq_setup(void) |
111 | { | 119 | { |
112 | extern asmlinkage void galileo_handle_int(void); | ||
113 | |||
114 | /* | 120 | /* |
115 | * Clear all of the interrupts while we change the able around a bit. | 121 | * Clear all of the interrupts while we change the able around a bit. |
116 | */ | 122 | */ |
117 | clear_c0_status(ST0_IM); | 123 | clear_c0_status(ST0_IM); |
118 | 124 | ||
119 | /* Sets the exception_handler array. */ | ||
120 | set_except_vector(0, galileo_handle_int); | ||
121 | |||
122 | local_irq_disable(); | 125 | local_irq_disable(); |
123 | 126 | ||
124 | /* | 127 | /* |
diff --git a/arch/mips/gt64120/momenco_ocelot/Makefile b/arch/mips/gt64120/momenco_ocelot/Makefile index 7b59c6567c79..6f708df8373b 100644 --- a/arch/mips/gt64120/momenco_ocelot/Makefile +++ b/arch/mips/gt64120/momenco_ocelot/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for Momentum's Ocelot board. | 2 | # Makefile for Momentum's Ocelot board. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += int-handler.o irq.o prom.o reset.o setup.o | 5 | obj-y += irq.o prom.o reset.o setup.o |
6 | 6 | ||
7 | obj-$(CONFIG_KGDB) += dbg_io.o | 7 | obj-$(CONFIG_KGDB) += dbg_io.o |
8 | 8 | ||
diff --git a/arch/mips/gt64120/momenco_ocelot/int-handler.S b/arch/mips/gt64120/momenco_ocelot/int-handler.S deleted file mode 100644 index 808acef248cc..000000000000 --- a/arch/mips/gt64120/momenco_ocelot/int-handler.S +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: jsun@mvista.com or jsun@junsun.net | ||
4 | * | ||
5 | * First-level interrupt dispatcher for ocelot board. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | |||
18 | /* | ||
19 | * first level interrupt dispatcher for ocelot board - | ||
20 | * We check for the timer first, then check PCI ints A and D. | ||
21 | * Then check for serial IRQ and fall through. | ||
22 | */ | ||
23 | .align 5 | ||
24 | NESTED(ocelot_handle_int, PT_SIZE, sp) | ||
25 | SAVE_ALL | ||
26 | CLI | ||
27 | .set at | ||
28 | mfc0 t0, CP0_CAUSE | ||
29 | mfc0 t2, CP0_STATUS | ||
30 | |||
31 | and t0, t2 | ||
32 | |||
33 | andi t1, t0, STATUSF_IP2 /* int0 hardware line */ | ||
34 | bnez t1, ll_pri_enet_irq | ||
35 | andi t1, t0, STATUSF_IP3 /* int1 hardware line */ | ||
36 | bnez t1, ll_sec_enet_irq | ||
37 | andi t1, t0, STATUSF_IP4 /* int2 hardware line */ | ||
38 | bnez t1, ll_uart1_irq | ||
39 | andi t1, t0, STATUSF_IP5 /* int3 hardware line */ | ||
40 | bnez t1, ll_cpci_irq | ||
41 | andi t1, t0, STATUSF_IP6 /* int4 hardware line */ | ||
42 | bnez t1, ll_galileo_irq | ||
43 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
44 | bnez t1, ll_cputimer_irq | ||
45 | |||
46 | /* now look at the extended interrupts */ | ||
47 | mfc0 t0, CP0_CAUSE | ||
48 | cfc0 t1, CP0_S1_INTCONTROL | ||
49 | |||
50 | /* shift the mask 8 bits left to line up the bits */ | ||
51 | sll t2, t1, 8 | ||
52 | |||
53 | and t0, t2 | ||
54 | srl t0, t0, 16 | ||
55 | |||
56 | andi t1, t0, STATUSF_IP8 /* int6 hardware line */ | ||
57 | bnez t1, ll_pmc1_irq | ||
58 | andi t1, t0, STATUSF_IP9 /* int7 hardware line */ | ||
59 | bnez t1, ll_pmc2_irq | ||
60 | andi t1, t0, STATUSF_IP10 /* int8 hardware line */ | ||
61 | bnez t1, ll_cpci_abcd_irq | ||
62 | andi t1, t0, STATUSF_IP11 /* int9 hardware line */ | ||
63 | bnez t1, ll_uart2_irq | ||
64 | |||
65 | .set reorder | ||
66 | |||
67 | /* wrong alarm or masked ... */ | ||
68 | j spurious_interrupt | ||
69 | nop | ||
70 | END(ocelot_handle_int) | ||
71 | |||
72 | .align 5 | ||
73 | ll_pri_enet_irq: | ||
74 | li a0, 2 | ||
75 | move a1, sp | ||
76 | jal do_IRQ | ||
77 | j ret_from_irq | ||
78 | |||
79 | ll_sec_enet_irq: | ||
80 | li a0, 3 | ||
81 | move a1, sp | ||
82 | jal do_IRQ | ||
83 | j ret_from_irq | ||
84 | |||
85 | ll_uart1_irq: | ||
86 | li a0, 4 | ||
87 | move a1, sp | ||
88 | jal do_IRQ | ||
89 | j ret_from_irq | ||
90 | |||
91 | ll_cpci_irq: | ||
92 | li a0, 5 | ||
93 | move a1, sp | ||
94 | jal do_IRQ | ||
95 | j ret_from_irq | ||
96 | |||
97 | ll_galileo_irq: | ||
98 | li a0, 6 | ||
99 | move a1, sp | ||
100 | jal do_IRQ | ||
101 | j ret_from_irq | ||
102 | |||
103 | ll_cputimer_irq: | ||
104 | li a0, 7 | ||
105 | move a1, sp | ||
106 | jal do_IRQ | ||
107 | j ret_from_irq | ||
108 | |||
109 | ll_pmc1_irq: | ||
110 | li a0, 8 | ||
111 | move a1, sp | ||
112 | jal do_IRQ | ||
113 | j ret_from_irq | ||
114 | |||
115 | ll_pmc2_irq: | ||
116 | li a0, 9 | ||
117 | move a1, sp | ||
118 | jal do_IRQ | ||
119 | j ret_from_irq | ||
120 | |||
121 | ll_cpci_abcd_irq: | ||
122 | li a0, 10 | ||
123 | move a1, sp | ||
124 | jal do_IRQ | ||
125 | j ret_from_irq | ||
126 | |||
127 | ll_uart2_irq: | ||
128 | li a0, 11 | ||
129 | move a1, sp | ||
130 | jal do_IRQ | ||
131 | j ret_from_irq | ||
diff --git a/arch/mips/gt64120/momenco_ocelot/irq.c b/arch/mips/gt64120/momenco_ocelot/irq.c index 4f108da71b23..885f67f32ea3 100644 --- a/arch/mips/gt64120/momenco_ocelot/irq.c +++ b/arch/mips/gt64120/momenco_ocelot/irq.c | |||
@@ -48,7 +48,38 @@ | |||
48 | #include <asm/mipsregs.h> | 48 | #include <asm/mipsregs.h> |
49 | #include <asm/system.h> | 49 | #include <asm/system.h> |
50 | 50 | ||
51 | extern asmlinkage void ocelot_handle_int(void); | 51 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
52 | { | ||
53 | unsigned int pending = read_c0_status() & read_c0_cause(); | ||
54 | |||
55 | if (pending & STATUSF_IP2) /* int0 hardware line */ | ||
56 | do_IRQ(2, regs); | ||
57 | else if (pending & STATUSF_IP3) /* int1 hardware line */ | ||
58 | do_IRQ(3, regs); | ||
59 | else if (pending & STATUSF_IP4) /* int2 hardware line */ | ||
60 | do_IRQ(4, regs); | ||
61 | else if (pending & STATUSF_IP5) /* int3 hardware line */ | ||
62 | do_IRQ(5, regs); | ||
63 | else if (pending & STATUSF_IP6) /* int4 hardware line */ | ||
64 | do_IRQ(6, regs); | ||
65 | else if (pending & STATUSF_IP7) /* cpu timer */ | ||
66 | do_IRQ(7, regs); | ||
67 | else { | ||
68 | /* | ||
69 | * Now look at the extended interrupts | ||
70 | */ | ||
71 | pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; | ||
72 | |||
73 | if (pending & STATUSF_IP8) /* int6 hardware line */ | ||
74 | do_IRQ(8, regs); | ||
75 | else if (pending & STATUSF_IP9) /* int7 hardware line */ | ||
76 | do_IRQ(9, regs); | ||
77 | else if (pending & STATUSF_IP10) /* int8 hardware line */ | ||
78 | do_IRQ(10, regs); | ||
79 | else if (pending & STATUSF_IP11) /* int9 hardware line */ | ||
80 | do_IRQ(11, regs); | ||
81 | } | ||
82 | } | ||
52 | 83 | ||
53 | void __init arch_init_irq(void) | 84 | void __init arch_init_irq(void) |
54 | { | 85 | { |
@@ -59,9 +90,6 @@ void __init arch_init_irq(void) | |||
59 | clear_c0_status(ST0_IM); | 90 | clear_c0_status(ST0_IM); |
60 | local_irq_disable(); | 91 | local_irq_disable(); |
61 | 92 | ||
62 | /* Sets the first-level interrupt dispatcher. */ | ||
63 | set_except_vector(0, ocelot_handle_int); | ||
64 | |||
65 | mips_cpu_irq_init(0); | 93 | mips_cpu_irq_init(0); |
66 | rm7k_cpu_irq_init(8); | 94 | rm7k_cpu_irq_init(8); |
67 | } | 95 | } |
diff --git a/arch/mips/ite-boards/generic/Makefile b/arch/mips/ite-boards/generic/Makefile index 0e7853f43983..63431538d0ec 100644 --- a/arch/mips/ite-boards/generic/Makefile +++ b/arch/mips/ite-boards/generic/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | # Makefile for the ITE 8172 (qed-4n-s01b) board, generic files. | 6 | # Makefile for the ITE 8172 (qed-4n-s01b) board, generic files. |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += it8172_setup.o irq.o int-handler.o pmon_prom.o \ | 9 | obj-y += it8172_setup.o irq.o pmon_prom.o \ |
10 | time.o lpc.o puts.o reset.o | 10 | time.o lpc.o puts.o reset.o |
11 | 11 | ||
12 | obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o | 12 | obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o |
diff --git a/arch/mips/ite-boards/generic/int-handler.S b/arch/mips/ite-boards/generic/int-handler.S deleted file mode 100644 index d190d8add9cb..000000000000 --- a/arch/mips/ite-boards/generic/int-handler.S +++ /dev/null | |||
@@ -1,63 +0,0 @@ | |||
1 | #include <asm/asm.h> | ||
2 | #include <asm/mipsregs.h> | ||
3 | #include <asm/regdef.h> | ||
4 | #include <asm/stackframe.h> | ||
5 | |||
6 | .text | ||
7 | .set macro | ||
8 | .set noat | ||
9 | .align 5 | ||
10 | |||
11 | NESTED(it8172_IRQ, PT_SIZE, sp) | ||
12 | SAVE_ALL | ||
13 | CLI # Important: mark KERNEL mode ! | ||
14 | |||
15 | /* We're working with 'reorder' set at this point. */ | ||
16 | /* | ||
17 | * Get pending interrupts | ||
18 | */ | ||
19 | |||
20 | mfc0 t0,CP0_CAUSE # get pending interrupts | ||
21 | mfc0 t1,CP0_STATUS # get enabled interrupts | ||
22 | and t0,t1 # isolate allowed ones | ||
23 | |||
24 | andi t0,0xff00 # isolate pending bits | ||
25 | beqz t0, 3f # spurious interrupt | ||
26 | |||
27 | andi a0, t0, CAUSEF_IP7 | ||
28 | beq a0, zero, 1f | ||
29 | |||
30 | li a0, 127 # MIPS_CPU_TIMER_IRQ = (NR_IRQS-1) | ||
31 | move a1, sp | ||
32 | jal ll_timer_interrupt | ||
33 | j ret_from_irq | ||
34 | nop | ||
35 | |||
36 | 1: | ||
37 | andi a0, t0, CAUSEF_IP2 # the only int we expect at this time | ||
38 | beq a0, zero, 3f | ||
39 | move a0,sp | ||
40 | jal it8172_hw0_irqdispatch | ||
41 | |||
42 | mfc0 t0,CP0_STATUS # disable interrupts | ||
43 | ori t0,1 | ||
44 | xori t0,1 | ||
45 | mtc0 t0,CP0_STATUS | ||
46 | nop | ||
47 | nop | ||
48 | nop | ||
49 | |||
50 | la a1, ret_from_irq | ||
51 | jr a1 | ||
52 | nop | ||
53 | |||
54 | 3: | ||
55 | move a0, sp | ||
56 | jal mips_spurious_interrupt | ||
57 | nop | ||
58 | la a1, ret_from_irq | ||
59 | jr a1 | ||
60 | nop | ||
61 | |||
62 | END(it8172_IRQ) | ||
63 | |||
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c index e67f96129491..77be7216bdd0 100644 --- a/arch/mips/ite-boards/generic/irq.c +++ b/arch/mips/ite-boards/generic/irq.c | |||
@@ -62,12 +62,8 @@ | |||
62 | 62 | ||
63 | #define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) | 63 | #define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) |
64 | 64 | ||
65 | void disable_it8172_irq(unsigned int irq_nr); | ||
66 | void enable_it8172_irq(unsigned int irq_nr); | ||
67 | |||
68 | extern void set_debug_traps(void); | 65 | extern void set_debug_traps(void); |
69 | extern void mips_timer_interrupt(int irq, struct pt_regs *regs); | 66 | extern void mips_timer_interrupt(int irq, struct pt_regs *regs); |
70 | extern asmlinkage void it8172_IRQ(void); | ||
71 | 67 | ||
72 | struct it8172_intc_regs volatile *it8172_hw0_icregs = | 68 | struct it8172_intc_regs volatile *it8172_hw0_icregs = |
73 | (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE)); | 69 | (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE)); |
@@ -181,8 +177,6 @@ void __init arch_init_irq(void) | |||
181 | int i; | 177 | int i; |
182 | unsigned long flags; | 178 | unsigned long flags; |
183 | 179 | ||
184 | set_except_vector(0, it8172_IRQ); | ||
185 | |||
186 | /* mask all interrupts */ | 180 | /* mask all interrupts */ |
187 | it8172_hw0_icregs->lb_mask = 0xffff; | 181 | it8172_hw0_icregs->lb_mask = 0xffff; |
188 | it8172_hw0_icregs->lpc_mask = 0xffff; | 182 | it8172_hw0_icregs->lpc_mask = 0xffff; |
@@ -282,6 +276,18 @@ void it8172_hw0_irqdispatch(struct pt_regs *regs) | |||
282 | do_IRQ(irq, regs); | 276 | do_IRQ(irq, regs); |
283 | } | 277 | } |
284 | 278 | ||
279 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
280 | { | ||
281 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
282 | |||
283 | if (!pending) | ||
284 | mips_spurious_interrupt(regs); | ||
285 | else if (pending & CAUSEF_IP7) | ||
286 | ll_timer_interrupt(127, regs); | ||
287 | else if (pending & CAUSEF_IP2) | ||
288 | it8172_hw0_irqdispatch(regs); | ||
289 | } | ||
290 | |||
285 | void show_pending_irqs(void) | 291 | void show_pending_irqs(void) |
286 | { | 292 | { |
287 | fputs("intstatus: "); | 293 | fputs("intstatus: "); |
diff --git a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c index b79817bb6cce..dee497a91807 100644 --- a/arch/mips/ite-boards/generic/time.c +++ b/arch/mips/ite-boards/generic/time.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/time.h> | 30 | #include <linux/time.h> |
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | #include <linux/mc146818rtc.h> | ||
32 | 33 | ||
33 | #include <asm/time.h> | 34 | #include <asm/time.h> |
34 | #include <asm/mipsregs.h> | 35 | #include <asm/mipsregs.h> |
diff --git a/arch/mips/ite-boards/ivr/init.c b/arch/mips/ite-boards/ivr/init.c index b774db035b31..05cf9218c432 100644 --- a/arch/mips/ite-boards/ivr/init.c +++ b/arch/mips/ite-boards/ivr/init.c | |||
@@ -34,13 +34,13 @@ | |||
34 | #include <asm/bootinfo.h> | 34 | #include <asm/bootinfo.h> |
35 | #include <linux/string.h> | 35 | #include <linux/string.h> |
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <asm/sections.h> | ||
37 | #include <asm/it8172/it8172.h> | 38 | #include <asm/it8172/it8172.h> |
38 | #include <asm/it8172/it8172_dbg.h> | 39 | #include <asm/it8172/it8172_dbg.h> |
39 | 40 | ||
40 | int prom_argc; | 41 | int prom_argc; |
41 | char **prom_argv, **prom_envp; | 42 | char **prom_argv, **prom_envp; |
42 | 43 | ||
43 | extern char _end; | ||
44 | extern void __init prom_init_cmdline(void); | 44 | extern void __init prom_init_cmdline(void); |
45 | extern unsigned long __init prom_get_memsize(void); | 45 | extern unsigned long __init prom_get_memsize(void); |
46 | extern void __init it8172_init_ram_resource(unsigned long memsize); | 46 | extern void __init it8172_init_ram_resource(unsigned long memsize); |
diff --git a/arch/mips/ite-boards/qed-4n-s01b/init.c b/arch/mips/ite-boards/qed-4n-s01b/init.c index e8ec8be66a80..ea2a754cafe5 100644 --- a/arch/mips/ite-boards/qed-4n-s01b/init.c +++ b/arch/mips/ite-boards/qed-4n-s01b/init.c | |||
@@ -34,13 +34,13 @@ | |||
34 | #include <asm/bootinfo.h> | 34 | #include <asm/bootinfo.h> |
35 | #include <linux/string.h> | 35 | #include <linux/string.h> |
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <asm/sections.h> | ||
37 | #include <asm/it8172/it8172.h> | 38 | #include <asm/it8172/it8172.h> |
38 | #include <asm/it8172/it8172_dbg.h> | 39 | #include <asm/it8172/it8172_dbg.h> |
39 | 40 | ||
40 | int prom_argc; | 41 | int prom_argc; |
41 | char **prom_argv, **prom_envp; | 42 | char **prom_argv, **prom_envp; |
42 | 43 | ||
43 | extern char _end; | ||
44 | extern void __init prom_init_cmdline(void); | 44 | extern void __init prom_init_cmdline(void); |
45 | extern unsigned long __init prom_get_memsize(void); | 45 | extern unsigned long __init prom_get_memsize(void); |
46 | extern void __init it8172_init_ram_resource(unsigned long memsize); | 46 | extern void __init it8172_init_ram_resource(unsigned long memsize); |
diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile index 85749246a671..02bd39add891 100644 --- a/arch/mips/jazz/Makefile +++ b/arch/mips/jazz/Makefile | |||
@@ -2,6 +2,6 @@ | |||
2 | # Makefile for the Jazz family specific parts of the kernel | 2 | # Makefile for the Jazz family specific parts of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := int-handler.o irq.o jazzdma.o reset.o setup.o | 5 | obj-y := irq.o jazzdma.o reset.o setup.o |
6 | 6 | ||
7 | EXTRA_AFLAGS := $(CFLAGS) | 7 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/jazz/int-handler.S b/arch/mips/jazz/int-handler.S deleted file mode 100644 index dc752c67b528..000000000000 --- a/arch/mips/jazz/int-handler.S +++ /dev/null | |||
@@ -1,282 +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) 1995, 1996, 1997, 1998 by Ralf Baechle and Andreas Busse | ||
7 | * | ||
8 | * Jazz family specific interrupt stuff | ||
9 | * | ||
10 | * To do: On Jazz machines we remap some non-ISA interrupts to ISA | ||
11 | * interrupts. These interrupts should use their own vectors. | ||
12 | * Squeeze the last cycles out of the handlers. Only a dead | ||
13 | * cycle is a good cycle. | ||
14 | */ | ||
15 | #include <asm/asm.h> | ||
16 | #include <asm/mipsregs.h> | ||
17 | #include <asm/jazz.h> | ||
18 | #include <asm/regdef.h> | ||
19 | #include <asm/stackframe.h> | ||
20 | |||
21 | /* | ||
22 | * jazz_handle_int: Interrupt handler for the ACER Pica-61 boards | ||
23 | */ | ||
24 | .set noreorder | ||
25 | |||
26 | NESTED(jazz_handle_int, PT_SIZE, ra) | ||
27 | .set noat | ||
28 | SAVE_ALL | ||
29 | CLI | ||
30 | .set at | ||
31 | |||
32 | /* | ||
33 | * Get pending interrupts | ||
34 | */ | ||
35 | mfc0 t0,CP0_CAUSE # get pending interrupts | ||
36 | mfc0 t1,CP0_STATUS # get enabled interrupts | ||
37 | and t0,t1 # isolate allowed ones | ||
38 | andi t0,0xff00 # isolate pending bits | ||
39 | beqz t0,3f | ||
40 | sll t0,16 # delay slot | ||
41 | |||
42 | /* | ||
43 | * Find irq with highest priority | ||
44 | * FIXME: This is slow - use binary search | ||
45 | */ | ||
46 | la t1,ll_vectors | ||
47 | 1: bltz t0,2f # found pending irq | ||
48 | sll t0,1 | ||
49 | b 1b | ||
50 | subu t1,PTRSIZE # delay slot | ||
51 | |||
52 | /* | ||
53 | * Do the low-level stuff | ||
54 | */ | ||
55 | 2: lw t0,(t1) | ||
56 | jr t0 | ||
57 | nop # delay slot | ||
58 | END(jazz_handle_int) | ||
59 | |||
60 | ll_sw0: li s1,~IE_SW0 | ||
61 | mfc0 t0,CP0_CAUSE | ||
62 | and t0,s1 | ||
63 | mtc0 t0,CP0_CAUSE | ||
64 | PANIC("Unimplemented sw0 handler") | ||
65 | |||
66 | ll_sw1: li s1,~IE_SW1 | ||
67 | mfc0 t0,CP0_CAUSE | ||
68 | and t0,s1 | ||
69 | mtc0 t0,CP0_CAUSE | ||
70 | PANIC("Unimplemented sw1 handler") | ||
71 | |||
72 | ll_local_dma: li s1,~IE_IRQ0 | ||
73 | PANIC("Unimplemented local_dma handler") | ||
74 | |||
75 | ll_local_dev: lbu t0,JAZZ_IO_IRQ_SOURCE | ||
76 | #if PTRSIZE == 8 /* True 64 bit kernel */ | ||
77 | dsll t0,1 | ||
78 | #endif | ||
79 | .set reorder | ||
80 | LONG_L t0,local_vector(t0) | ||
81 | jr t0 | ||
82 | .set noreorder | ||
83 | |||
84 | /* | ||
85 | * The braindead PICA hardware gives us no way to distinguish if we really | ||
86 | * received interrupt 7 from the (E)ISA bus or if we just received an | ||
87 | * interrupt with no findable cause. This sometimes happens with braindead | ||
88 | * cards. Oh well - for all the Jazz boxes slots are more or less just | ||
89 | * whistles and bells and we're aware of the problem. | ||
90 | */ | ||
91 | ll_isa_irq: lw a0, JAZZ_EISA_IRQ_ACK | ||
92 | |||
93 | jal do_IRQ | ||
94 | move a1,sp | ||
95 | |||
96 | j ret_from_irq | ||
97 | nop | ||
98 | |||
99 | /* | ||
100 | * Hmm... This is not just a plain PC clone so the question is | ||
101 | * which devices on Jazz machines can generate an (E)ISA NMI? | ||
102 | * (Writing to nonexistent memory?) | ||
103 | */ | ||
104 | ll_isa_nmi: li s1,~IE_IRQ3 | ||
105 | PANIC("Unimplemented isa_nmi handler") | ||
106 | |||
107 | /* | ||
108 | * Timer IRQ - remapped to be more similar to an IBM compatible. | ||
109 | * | ||
110 | * The timer interrupt is handled specially to ensure that the jiffies | ||
111 | * variable is updated at all times. Specifically, the timer interrupt is | ||
112 | * just like the complete handlers except that it is invoked with interrupts | ||
113 | * disabled and should never re-enable them. If other interrupts were | ||
114 | * allowed to be processed while the timer interrupt is active, then the | ||
115 | * other interrupts would have to avoid using the jiffies variable for delay | ||
116 | * and interval timing operations to avoid hanging the system. | ||
117 | */ | ||
118 | ll_timer: lw zero,JAZZ_TIMER_REGISTER # timer irq cleared on read | ||
119 | li s1,~IE_IRQ4 | ||
120 | |||
121 | li a0, JAZZ_TIMER_IRQ | ||
122 | jal do_IRQ | ||
123 | move a1,sp | ||
124 | |||
125 | mfc0 t0,CP0_STATUS # disable interrupts again | ||
126 | ori t0,1 | ||
127 | xori t0,1 | ||
128 | mtc0 t0,CP0_STATUS | ||
129 | |||
130 | j ret_from_irq | ||
131 | nop | ||
132 | |||
133 | /* | ||
134 | * CPU count/compare IRQ (unused) | ||
135 | */ | ||
136 | ll_count: j ret_from_irq | ||
137 | mtc0 zero,CP0_COMPARE | ||
138 | |||
139 | #if 0 | ||
140 | /* | ||
141 | * Call the handler for the interrupt | ||
142 | * (Currently unused) | ||
143 | */ | ||
144 | call_real: /* | ||
145 | * temporarily disable interrupt | ||
146 | */ | ||
147 | mfc0 t2,CP0_STATUS | ||
148 | and t2,s1 | ||
149 | mtc0 t2,CP0_STATUS | ||
150 | nor s1,zero,s1 | ||
151 | jal do_IRQ | ||
152 | |||
153 | /* | ||
154 | * reenable interrupt | ||
155 | */ | ||
156 | mfc0 t2,CP0_STATUS | ||
157 | or t2,s1 | ||
158 | mtc0 t2,CP0_STATUS | ||
159 | j ret_from_irq | ||
160 | #endif | ||
161 | |||
162 | .data | ||
163 | PTR ll_sw0 # SW0 | ||
164 | PTR ll_sw1 # SW1 | ||
165 | PTR ll_local_dma # Local DMA | ||
166 | PTR ll_local_dev # Local devices | ||
167 | PTR ll_isa_irq # ISA IRQ | ||
168 | PTR ll_isa_nmi # ISA NMI | ||
169 | PTR ll_timer # Timer | ||
170 | ll_vectors: PTR ll_count # Count/Compare IRQ | ||
171 | |||
172 | /* | ||
173 | * Interrupt handlers for local devices. | ||
174 | */ | ||
175 | .text | ||
176 | .set reorder | ||
177 | loc_no_irq: PANIC("Unimplemented loc_no_irq handler") | ||
178 | /* | ||
179 | * Parallel port IRQ | ||
180 | */ | ||
181 | loc_parallel: li s1,~JAZZ_IE_PARALLEL | ||
182 | li a0,JAZZ_PARALLEL_IRQ | ||
183 | b loc_call | ||
184 | |||
185 | /* | ||
186 | * Floppy IRQ | ||
187 | */ | ||
188 | loc_floppy: li s1,~JAZZ_IE_FLOPPY | ||
189 | li a0,JAZZ_FLOPPY_IRQ | ||
190 | b loc_call | ||
191 | |||
192 | /* | ||
193 | * Sound IRQ | ||
194 | */ | ||
195 | loc_sound: PANIC("Unimplemented loc_sound handler") | ||
196 | loc_video: PANIC("Unimplemented loc_video handler") | ||
197 | |||
198 | /* | ||
199 | * Ethernet interrupt handler | ||
200 | */ | ||
201 | loc_ethernet: li s1,~JAZZ_IE_ETHERNET | ||
202 | li a0,JAZZ_ETHERNET_IRQ | ||
203 | b loc_call | ||
204 | |||
205 | /* | ||
206 | * SCSI interrupt handler | ||
207 | */ | ||
208 | loc_scsi: li s1,~JAZZ_IE_SCSI | ||
209 | li a0,JAZZ_SCSI_IRQ | ||
210 | b loc_call | ||
211 | |||
212 | /* | ||
213 | * Keyboard interrupt handler | ||
214 | */ | ||
215 | loc_keyboard: li s1,~JAZZ_IE_KEYBOARD | ||
216 | li a0,JAZZ_KEYBOARD_IRQ | ||
217 | b loc_call | ||
218 | |||
219 | /* | ||
220 | * Mouse interrupt handler | ||
221 | */ | ||
222 | loc_mouse: li s1,~JAZZ_IE_MOUSE | ||
223 | li a0,JAZZ_MOUSE_IRQ | ||
224 | b loc_call | ||
225 | |||
226 | /* | ||
227 | * Serial port 1 IRQ | ||
228 | */ | ||
229 | loc_serial1: li s1,~JAZZ_IE_SERIAL1 | ||
230 | li a0,JAZZ_SERIAL1_IRQ | ||
231 | b loc_call | ||
232 | |||
233 | /* | ||
234 | * Serial port 2 IRQ | ||
235 | */ | ||
236 | loc_serial2: li s1,~JAZZ_IE_SERIAL2 | ||
237 | li a0,JAZZ_SERIAL2_IRQ | ||
238 | b loc_call | ||
239 | |||
240 | /* | ||
241 | * Call the interrupt handler for an interrupt generated by a | ||
242 | * local device. | ||
243 | */ | ||
244 | loc_call: /* | ||
245 | * Temporarily disable interrupt source | ||
246 | */ | ||
247 | lhu t2,JAZZ_IO_IRQ_ENABLE | ||
248 | and t2,s1 | ||
249 | sh t2,JAZZ_IO_IRQ_ENABLE | ||
250 | |||
251 | nor s1,zero,s1 | ||
252 | jal do_IRQ | ||
253 | |||
254 | /* | ||
255 | * Reenable interrupt | ||
256 | */ | ||
257 | lhu t2,JAZZ_IO_IRQ_ENABLE | ||
258 | or t2,s1 | ||
259 | sh t2,JAZZ_IO_IRQ_ENABLE | ||
260 | |||
261 | j ret_from_irq | ||
262 | |||
263 | /* | ||
264 | * "Jump extender" to reach spurious_interrupt | ||
265 | */ | ||
266 | 3: j spurious_interrupt | ||
267 | |||
268 | /* | ||
269 | * Vectors for interrupts generated by local devices | ||
270 | */ | ||
271 | .data | ||
272 | local_vector: PTR loc_no_irq | ||
273 | PTR loc_parallel | ||
274 | PTR loc_floppy | ||
275 | PTR loc_sound | ||
276 | PTR loc_video | ||
277 | PTR loc_ethernet | ||
278 | PTR loc_scsi | ||
279 | PTR loc_keyboard | ||
280 | PTR loc_mouse | ||
281 | PTR loc_serial1 | ||
282 | PTR loc_serial2 | ||
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index b309b1bcf2e8..becc9accd495 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c | |||
@@ -15,8 +15,6 @@ | |||
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <asm/jazz.h> | 16 | #include <asm/jazz.h> |
17 | 17 | ||
18 | extern asmlinkage void jazz_handle_int(void); | ||
19 | |||
20 | static DEFINE_SPINLOCK(r4030_lock); | 18 | static DEFINE_SPINLOCK(r4030_lock); |
21 | 19 | ||
22 | static void enable_r4030_irq(unsigned int irq) | 20 | static void enable_r4030_irq(unsigned int irq) |
@@ -90,10 +88,82 @@ void __init init_r4030_ints(void) | |||
90 | */ | 88 | */ |
91 | void __init arch_init_irq(void) | 89 | void __init arch_init_irq(void) |
92 | { | 90 | { |
93 | set_except_vector(0, jazz_handle_int); | ||
94 | |||
95 | init_i8259_irqs(); /* Integrated i8259 */ | 91 | init_i8259_irqs(); /* Integrated i8259 */ |
96 | init_r4030_ints(); | 92 | init_r4030_ints(); |
97 | 93 | ||
98 | change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); | 94 | change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); |
99 | } | 95 | } |
96 | |||
97 | static void loc_call(unsigned int irq, struct pt_regs *regs, unsigned int mask) | ||
98 | { | ||
99 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, | ||
100 | r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask); | ||
101 | do_IRQ(irq, regs); | ||
102 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, | ||
103 | r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask); | ||
104 | } | ||
105 | |||
106 | static void ll_local_dev(struct pt_regs *regs) | ||
107 | { | ||
108 | switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) { | ||
109 | case 0: | ||
110 | panic("Unimplemented loc_no_irq handler"); | ||
111 | break; | ||
112 | case 4: | ||
113 | loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_PARALLEL); | ||
114 | break; | ||
115 | case 8: | ||
116 | loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_FLOPPY); | ||
117 | break; | ||
118 | case 12: | ||
119 | panic("Unimplemented loc_sound handler"); | ||
120 | break; | ||
121 | case 16: | ||
122 | panic("Unimplemented loc_video handler"); | ||
123 | break; | ||
124 | case 20: | ||
125 | loc_call(JAZZ_ETHERNET_IRQ, regs, JAZZ_IE_ETHERNET); | ||
126 | break; | ||
127 | case 24: | ||
128 | loc_call(JAZZ_SCSI_IRQ, regs, JAZZ_IE_SCSI); | ||
129 | break; | ||
130 | case 28: | ||
131 | loc_call(JAZZ_KEYBOARD_IRQ, regs, JAZZ_IE_KEYBOARD); | ||
132 | break; | ||
133 | case 32: | ||
134 | loc_call(JAZZ_MOUSE_IRQ, regs, JAZZ_IE_MOUSE); | ||
135 | break; | ||
136 | case 36: | ||
137 | loc_call(JAZZ_SERIAL1_IRQ, regs, JAZZ_IE_SERIAL1); | ||
138 | break; | ||
139 | case 40: | ||
140 | loc_call(JAZZ_SERIAL2_IRQ, regs, JAZZ_IE_SERIAL2); | ||
141 | break; | ||
142 | } | ||
143 | } | ||
144 | |||
145 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
146 | { | ||
147 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
148 | |||
149 | if (pending & IE_IRQ5) | ||
150 | write_c0_compare(0); | ||
151 | else if (pending & IE_IRQ4) { | ||
152 | r4030_read_reg32(JAZZ_TIMER_REGISTER); | ||
153 | do_IRQ(JAZZ_TIMER_IRQ, regs); | ||
154 | } else if (pending & IE_IRQ3) | ||
155 | panic("Unimplemented ISA NMI handler"); | ||
156 | else if (pending & IE_IRQ2) | ||
157 | do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK), regs); | ||
158 | else if (pending & IE_IRQ1) { | ||
159 | ll_local_dev(regs); | ||
160 | } else if (unlikely(pending & IE_IRQ0)) | ||
161 | panic("Unimplemented local_dma handler"); | ||
162 | else if (pending & IE_SW1) { | ||
163 | clear_c0_cause(IE_SW1); | ||
164 | panic("Unimplemented sw1 handler"); | ||
165 | } else if (pending & IE_SW0) { | ||
166 | clear_c0_cause(IE_SW0); | ||
167 | panic("Unimplemented sw0 handler"); | ||
168 | } | ||
169 | } | ||
diff --git a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c index a6bd3f4d3049..e6561345d12a 100644 --- a/arch/mips/jmr3927/common/rtc_ds1742.c +++ b/arch/mips/jmr3927/common/rtc_ds1742.c | |||
@@ -60,15 +60,15 @@ rtc_ds1742_get_time(void) | |||
60 | unsigned long flags; | 60 | unsigned long flags; |
61 | 61 | ||
62 | spin_lock_irqsave(&rtc_lock, flags); | 62 | spin_lock_irqsave(&rtc_lock, flags); |
63 | CMOS_WRITE(RTC_READ, RTC_CONTROL); | 63 | rtc_write(RTC_READ, RTC_CONTROL); |
64 | second = BCD2BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); | 64 | second = BCD2BIN(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK); |
65 | minute = BCD2BIN(CMOS_READ(RTC_MINUTES)); | 65 | minute = BCD2BIN(rtc_read(RTC_MINUTES)); |
66 | hour = BCD2BIN(CMOS_READ(RTC_HOURS)); | 66 | hour = BCD2BIN(rtc_read(RTC_HOURS)); |
67 | day = BCD2BIN(CMOS_READ(RTC_DATE)); | 67 | day = BCD2BIN(rtc_read(RTC_DATE)); |
68 | month = BCD2BIN(CMOS_READ(RTC_MONTH)); | 68 | month = BCD2BIN(rtc_read(RTC_MONTH)); |
69 | year = BCD2BIN(CMOS_READ(RTC_YEAR)); | 69 | year = BCD2BIN(rtc_read(RTC_YEAR)); |
70 | century = BCD2BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK); | 70 | century = BCD2BIN(rtc_read(RTC_CENTURY) & RTC_CENTURY_MASK); |
71 | CMOS_WRITE(0, RTC_CONTROL); | 71 | rtc_write(0, RTC_CONTROL); |
72 | spin_unlock_irqrestore(&rtc_lock, flags); | 72 | spin_unlock_irqrestore(&rtc_lock, flags); |
73 | 73 | ||
74 | year += century * 100; | 74 | year += century * 100; |
@@ -87,16 +87,16 @@ rtc_ds1742_set_time(unsigned long t) | |||
87 | unsigned long flags; | 87 | unsigned long flags; |
88 | 88 | ||
89 | spin_lock_irqsave(&rtc_lock, flags); | 89 | spin_lock_irqsave(&rtc_lock, flags); |
90 | CMOS_WRITE(RTC_READ, RTC_CONTROL); | 90 | rtc_write(RTC_READ, RTC_CONTROL); |
91 | cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); | 91 | cmos_second = (u8)(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK); |
92 | cmos_minute = (u8)CMOS_READ(RTC_MINUTES); | 92 | cmos_minute = (u8)rtc_read(RTC_MINUTES); |
93 | cmos_hour = (u8)CMOS_READ(RTC_HOURS); | 93 | cmos_hour = (u8)rtc_read(RTC_HOURS); |
94 | cmos_day = (u8)CMOS_READ(RTC_DATE); | 94 | cmos_day = (u8)rtc_read(RTC_DATE); |
95 | cmos_month = (u8)CMOS_READ(RTC_MONTH); | 95 | cmos_month = (u8)rtc_read(RTC_MONTH); |
96 | cmos_year = (u8)CMOS_READ(RTC_YEAR); | 96 | cmos_year = (u8)rtc_read(RTC_YEAR); |
97 | cmos_century = CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK; | 97 | cmos_century = rtc_read(RTC_CENTURY) & RTC_CENTURY_MASK; |
98 | 98 | ||
99 | CMOS_WRITE(RTC_WRITE, RTC_CONTROL); | 99 | rtc_write(RTC_WRITE, RTC_CONTROL); |
100 | 100 | ||
101 | /* convert */ | 101 | /* convert */ |
102 | to_tm(t, &tm); | 102 | to_tm(t, &tm); |
@@ -104,18 +104,18 @@ rtc_ds1742_set_time(unsigned long t) | |||
104 | /* check each field one by one */ | 104 | /* check each field one by one */ |
105 | year = BIN2BCD(tm.tm_year - EPOCH); | 105 | year = BIN2BCD(tm.tm_year - EPOCH); |
106 | if (year != cmos_year) { | 106 | if (year != cmos_year) { |
107 | CMOS_WRITE(year,RTC_YEAR); | 107 | rtc_write(year,RTC_YEAR); |
108 | } | 108 | } |
109 | 109 | ||
110 | month = BIN2BCD(tm.tm_mon); | 110 | month = BIN2BCD(tm.tm_mon); |
111 | if (month != (cmos_month & 0x1f)) { | 111 | if (month != (cmos_month & 0x1f)) { |
112 | CMOS_WRITE((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH); | 112 | rtc_write((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH); |
113 | } | 113 | } |
114 | 114 | ||
115 | day = BIN2BCD(tm.tm_mday); | 115 | day = BIN2BCD(tm.tm_mday); |
116 | if (day != cmos_day) { | 116 | if (day != cmos_day) { |
117 | 117 | ||
118 | CMOS_WRITE(day, RTC_DATE); | 118 | rtc_write(day, RTC_DATE); |
119 | } | 119 | } |
120 | 120 | ||
121 | if (cmos_hour & 0x40) { | 121 | if (cmos_hour & 0x40) { |
@@ -130,20 +130,20 @@ rtc_ds1742_set_time(unsigned long t) | |||
130 | /* 24 hour format */ | 130 | /* 24 hour format */ |
131 | hour = BIN2BCD(tm.tm_hour) & 0x3f; | 131 | hour = BIN2BCD(tm.tm_hour) & 0x3f; |
132 | } | 132 | } |
133 | if (hour != cmos_hour) CMOS_WRITE(hour, RTC_HOURS); | 133 | if (hour != cmos_hour) rtc_write(hour, RTC_HOURS); |
134 | 134 | ||
135 | minute = BIN2BCD(tm.tm_min); | 135 | minute = BIN2BCD(tm.tm_min); |
136 | if (minute != cmos_minute) { | 136 | if (minute != cmos_minute) { |
137 | CMOS_WRITE(minute, RTC_MINUTES); | 137 | rtc_write(minute, RTC_MINUTES); |
138 | } | 138 | } |
139 | 139 | ||
140 | second = BIN2BCD(tm.tm_sec); | 140 | second = BIN2BCD(tm.tm_sec); |
141 | if (second != cmos_second) { | 141 | if (second != cmos_second) { |
142 | CMOS_WRITE(second & RTC_SECONDS_MASK,RTC_SECONDS); | 142 | rtc_write(second & RTC_SECONDS_MASK,RTC_SECONDS); |
143 | } | 143 | } |
144 | 144 | ||
145 | /* RTC_CENTURY and RTC_CONTROL share same address... */ | 145 | /* RTC_CENTURY and RTC_CONTROL share same address... */ |
146 | CMOS_WRITE(cmos_century, RTC_CONTROL); | 146 | rtc_write(cmos_century, RTC_CONTROL); |
147 | spin_unlock_irqrestore(&rtc_lock, flags); | 147 | spin_unlock_irqrestore(&rtc_lock, flags); |
148 | 148 | ||
149 | return 0; | 149 | return 0; |
@@ -163,9 +163,9 @@ rtc_ds1742_init(unsigned long base) | |||
163 | rtc_mips_set_time = rtc_ds1742_set_time; | 163 | rtc_mips_set_time = rtc_ds1742_set_time; |
164 | 164 | ||
165 | /* clear oscillator stop bit */ | 165 | /* clear oscillator stop bit */ |
166 | CMOS_WRITE(RTC_READ, RTC_CONTROL); | 166 | rtc_write(RTC_READ, RTC_CONTROL); |
167 | cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); | 167 | cmos_second = (u8)(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK); |
168 | CMOS_WRITE(RTC_WRITE, RTC_CONTROL); | 168 | rtc_write(RTC_WRITE, RTC_CONTROL); |
169 | CMOS_WRITE(cmos_second, RTC_SECONDS); /* clear msb */ | 169 | rtc_write(cmos_second, RTC_SECONDS); /* clear msb */ |
170 | CMOS_WRITE(0, RTC_CONTROL); | 170 | rtc_write(0, RTC_CONTROL); |
171 | } | 171 | } |
diff --git a/arch/mips/jmr3927/rbhma3100/Makefile b/arch/mips/jmr3927/rbhma3100/Makefile index 75bf418b94c0..baf5077813c1 100644 --- a/arch/mips/jmr3927/rbhma3100/Makefile +++ b/arch/mips/jmr3927/rbhma3100/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for TOSHIBA JMR-TX3927 board | 2 | # Makefile for TOSHIBA JMR-TX3927 board |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += init.o int-handler.o irq.o setup.o | 5 | obj-y += init.o irq.o setup.o |
6 | obj-$(CONFIG_RUNTIME_DEBUG) += debug.o | 6 | obj-$(CONFIG_RUNTIME_DEBUG) += debug.o |
7 | obj-$(CONFIG_KGDB) += kgdb_io.o | 7 | obj-$(CONFIG_KGDB) += kgdb_io.o |
8 | 8 | ||
diff --git a/arch/mips/jmr3927/rbhma3100/int-handler.S b/arch/mips/jmr3927/rbhma3100/int-handler.S deleted file mode 100644 index f85bbf407542..000000000000 --- a/arch/mips/jmr3927/rbhma3100/int-handler.S +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: MontaVista Software, Inc. | ||
4 | * ahennessy@mvista.com | ||
5 | * | ||
6 | * Based on arch/mips/tsdb/kernel/int-handler.S | ||
7 | * | ||
8 | * Copyright (C) 2000-2001 Toshiba Corporation | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
16 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
17 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
18 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
21 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License along | ||
27 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
28 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
29 | */ | ||
30 | |||
31 | #include <asm/asm.h> | ||
32 | #include <asm/mipsregs.h> | ||
33 | #include <asm/regdef.h> | ||
34 | #include <asm/stackframe.h> | ||
35 | #include <asm/jmr3927/jmr3927.h> | ||
36 | |||
37 | /* A lot of complication here is taken away because: | ||
38 | * | ||
39 | * 1) We handle one interrupt and return, sitting in a loop | ||
40 | * and moving across all the pending IRQ bits in the cause | ||
41 | * register is _NOT_ the answer, the common case is one | ||
42 | * pending IRQ so optimize in that direction. | ||
43 | * | ||
44 | * 2) We need not check against bits in the status register | ||
45 | * IRQ mask, that would make this routine slow as hell. | ||
46 | * | ||
47 | * 3) Linux only thinks in terms of all IRQs on or all IRQs | ||
48 | * off, nothing in between like BSD spl() brain-damage. | ||
49 | * | ||
50 | */ | ||
51 | |||
52 | /* Flush write buffer (needed?) | ||
53 | * NOTE: TX39xx performs "non-blocking load", so explicitly use the target | ||
54 | * register of LBU to flush immediately. | ||
55 | */ | ||
56 | #define FLUSH_WB(tmp) \ | ||
57 | la tmp, JMR3927_IOC_REV_ADDR; \ | ||
58 | lbu tmp, (tmp); \ | ||
59 | move tmp, zero; | ||
60 | |||
61 | .text | ||
62 | .set noreorder | ||
63 | .set noat | ||
64 | .align 5 | ||
65 | NESTED(jmr3927_IRQ, PT_SIZE, sp) | ||
66 | SAVE_ALL | ||
67 | CLI | ||
68 | .set at | ||
69 | jal jmr3927_irc_irqdispatch | ||
70 | move a0, sp | ||
71 | FLUSH_WB(t0) | ||
72 | j ret_from_irq | ||
73 | nop | ||
74 | END(jmr3927_IRQ) | ||
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index 2810727f1d4e..11304d1354f4 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c | |||
@@ -77,8 +77,6 @@ static int jmr3927_gen_iack(void) | |||
77 | } | 77 | } |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | extern asmlinkage void jmr3927_IRQ(void); | ||
81 | |||
82 | #define irc_dlevel 0 | 80 | #define irc_dlevel 0 |
83 | #define irc_elevel 1 | 81 | #define irc_elevel 1 |
84 | 82 | ||
@@ -262,7 +260,7 @@ void jmr3927_spurious(struct pt_regs *regs) | |||
262 | regs->cp0_cause, regs->cp0_epc, regs->regs[31]); | 260 | regs->cp0_cause, regs->cp0_epc, regs->regs[31]); |
263 | } | 261 | } |
264 | 262 | ||
265 | void jmr3927_irc_irqdispatch(struct pt_regs *regs) | 263 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
266 | { | 264 | { |
267 | int irq; | 265 | int irq; |
268 | 266 | ||
@@ -398,8 +396,6 @@ void __init arch_init_irq(void) | |||
398 | 396 | ||
399 | jmr3927_irq_init(NR_ISA_IRQS); | 397 | jmr3927_irq_init(NR_ISA_IRQS); |
400 | 398 | ||
401 | set_except_vector(0, jmr3927_IRQ); | ||
402 | |||
403 | /* setup irq space */ | 399 | /* setup irq space */ |
404 | add_tb_irq_space(&jmr3927_isac_irqspace); | 400 | add_tb_irq_space(&jmr3927_isac_irqspace); |
405 | add_tb_irq_space(&jmr3927_ioc_irqspace); | 401 | add_tb_irq_space(&jmr3927_ioc_irqspace); |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 309d54cceda3..34e8a256765c 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -34,8 +34,11 @@ obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o | |||
34 | 34 | ||
35 | obj-$(CONFIG_SMP) += smp.o | 35 | obj-$(CONFIG_SMP) += smp.o |
36 | 36 | ||
37 | obj-$(CONFIG_MIPS_MT_SMP) += smp_mt.o | 37 | obj-$(CONFIG_MIPS_MT) += mips-mt.o |
38 | obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o | ||
39 | obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o | ||
38 | 40 | ||
41 | obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o | ||
39 | obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o | 42 | obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o |
40 | obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o | 43 | obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o |
41 | 44 | ||
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index ca6b03c773be..92b28b674d6f 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -69,6 +69,9 @@ void output_ptreg_defines(void) | |||
69 | offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr); | 69 | offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr); |
70 | offset("#define PT_STATUS ", struct pt_regs, cp0_status); | 70 | offset("#define PT_STATUS ", struct pt_regs, cp0_status); |
71 | offset("#define PT_CAUSE ", struct pt_regs, cp0_cause); | 71 | offset("#define PT_CAUSE ", struct pt_regs, cp0_cause); |
72 | #ifdef CONFIG_MIPS_MT_SMTC | ||
73 | offset("#define PT_TCSTATUS ", struct pt_regs, cp0_tcstatus); | ||
74 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
72 | size("#define PT_SIZE ", struct pt_regs); | 75 | size("#define PT_SIZE ", struct pt_regs); |
73 | linefeed; | 76 | linefeed; |
74 | } | 77 | } |
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index 83c87fe4ee4f..d101d2fb24ca 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S | |||
@@ -17,6 +17,9 @@ | |||
17 | #include <asm/isadep.h> | 17 | #include <asm/isadep.h> |
18 | #include <asm/thread_info.h> | 18 | #include <asm/thread_info.h> |
19 | #include <asm/war.h> | 19 | #include <asm/war.h> |
20 | #ifdef CONFIG_MIPS_MT_SMTC | ||
21 | #include <asm/mipsmtregs.h> | ||
22 | #endif | ||
20 | 23 | ||
21 | #ifdef CONFIG_PREEMPT | 24 | #ifdef CONFIG_PREEMPT |
22 | .macro preempt_stop | 25 | .macro preempt_stop |
@@ -75,6 +78,37 @@ FEXPORT(syscall_exit) | |||
75 | bnez t0, syscall_exit_work | 78 | bnez t0, syscall_exit_work |
76 | 79 | ||
77 | FEXPORT(restore_all) # restore full frame | 80 | FEXPORT(restore_all) # restore full frame |
81 | #ifdef CONFIG_MIPS_MT_SMTC | ||
82 | /* Detect and execute deferred IPI "interrupts" */ | ||
83 | move a0,sp | ||
84 | jal deferred_smtc_ipi | ||
85 | /* Re-arm any temporarily masked interrupts not explicitly "acked" */ | ||
86 | mfc0 v0, CP0_TCSTATUS | ||
87 | ori v1, v0, TCSTATUS_IXMT | ||
88 | mtc0 v1, CP0_TCSTATUS | ||
89 | andi v0, TCSTATUS_IXMT | ||
90 | ehb | ||
91 | mfc0 t0, CP0_TCCONTEXT | ||
92 | DMT 9 # dmt t1 | ||
93 | jal mips_ihb | ||
94 | mfc0 t2, CP0_STATUS | ||
95 | andi t3, t0, 0xff00 | ||
96 | or t2, t2, t3 | ||
97 | mtc0 t2, CP0_STATUS | ||
98 | ehb | ||
99 | andi t1, t1, VPECONTROL_TE | ||
100 | beqz t1, 1f | ||
101 | EMT | ||
102 | 1: | ||
103 | mfc0 v1, CP0_TCSTATUS | ||
104 | /* We set IXMT above, XOR should cler it here */ | ||
105 | xori v1, v1, TCSTATUS_IXMT | ||
106 | or v1, v0, v1 | ||
107 | mtc0 v1, CP0_TCSTATUS | ||
108 | ehb | ||
109 | xor t0, t0, t3 | ||
110 | mtc0 t0, CP0_TCCONTEXT | ||
111 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
78 | .set noat | 112 | .set noat |
79 | RESTORE_TEMP | 113 | RESTORE_TEMP |
80 | RESTORE_AT | 114 | RESTORE_AT |
@@ -120,28 +154,17 @@ syscall_exit_work: | |||
120 | jal do_syscall_trace | 154 | jal do_syscall_trace |
121 | b resume_userspace | 155 | b resume_userspace |
122 | 156 | ||
157 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT) | ||
158 | |||
123 | /* | 159 | /* |
124 | * Common spurious interrupt handler. | 160 | * MIPS32R2 Instruction Hazard Barrier - must be called |
161 | * | ||
162 | * For C code use the inline version named instruction_hazard(). | ||
125 | */ | 163 | */ |
126 | LEAF(spurious_interrupt) | 164 | LEAF(mips_ihb) |
127 | /* | 165 | .set mips32r2 |
128 | * Someone tried to fool us by sending an interrupt but we | 166 | jr.hb ra |
129 | * couldn't find a cause for it. | 167 | nop |
130 | */ | 168 | END(mips_ihb) |
131 | PTR_LA t1, irq_err_count | 169 | |
132 | #ifdef CONFIG_SMP | 170 | #endif /* CONFIG_CPU_MIPSR2 or CONFIG_MIPS_MT */ |
133 | 1: ll t0, (t1) | ||
134 | addiu t0, 1 | ||
135 | sc t0, (t1) | ||
136 | #if R10000_LLSC_WAR | ||
137 | beqzl t0, 1b | ||
138 | #else | ||
139 | beqz t0, 1b | ||
140 | #endif | ||
141 | #else | ||
142 | lw t0, (t1) | ||
143 | addiu t0, 1 | ||
144 | sw t0, (t1) | ||
145 | #endif | ||
146 | j ret_from_irq | ||
147 | END(spurious_interrupt) | ||
diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S index 235ad9f6bd35..10f28fb9f008 100644 --- a/arch/mips/kernel/gdb-low.S +++ b/arch/mips/kernel/gdb-low.S | |||
@@ -283,11 +283,33 @@ | |||
283 | */ | 283 | */ |
284 | 284 | ||
285 | 3: | 285 | 3: |
286 | #ifdef CONFIG_MIPS_MT_SMTC | ||
287 | /* Read-modify write of Status must be atomic */ | ||
288 | mfc0 t2, CP0_TCSTATUS | ||
289 | ori t1, t2, TCSTATUS_IXMT | ||
290 | mtc0 t1, CP0_TCSTATUS | ||
291 | andi t2, t2, TCSTATUS_IXMT | ||
292 | ehb | ||
293 | DMT 9 # dmt t1 | ||
294 | jal mips_ihb | ||
295 | nop | ||
296 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
286 | mfc0 t0, CP0_STATUS | 297 | mfc0 t0, CP0_STATUS |
287 | ori t0, 0x1f | 298 | ori t0, 0x1f |
288 | xori t0, 0x1f | 299 | xori t0, 0x1f |
289 | mtc0 t0, CP0_STATUS | 300 | mtc0 t0, CP0_STATUS |
290 | 301 | #ifdef CONFIG_MIPS_MT_SMTC | |
302 | andi t1, t1, VPECONTROL_TE | ||
303 | beqz t1, 9f | ||
304 | nop | ||
305 | EMT # emt | ||
306 | 9: | ||
307 | mfc0 t1, CP0_TCSTATUS | ||
308 | xori t1, t1, TCSTATUS_IXMT | ||
309 | or t1, t1, t2 | ||
310 | mtc0 t1, CP0_TCSTATUS | ||
311 | ehb | ||
312 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
291 | LONG_L v0, GDB_FR_STATUS(sp) | 313 | LONG_L v0, GDB_FR_STATUS(sp) |
292 | LONG_L v1, GDB_FR_EPC(sp) | 314 | LONG_L v1, GDB_FR_EPC(sp) |
293 | mtc0 v0, CP0_STATUS | 315 | mtc0 v0, CP0_STATUS |
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c index d4f88e0af24c..6ecbdc1fefd1 100644 --- a/arch/mips/kernel/gdb-stub.c +++ b/arch/mips/kernel/gdb-stub.c | |||
@@ -140,6 +140,7 @@ | |||
140 | #include <asm/system.h> | 140 | #include <asm/system.h> |
141 | #include <asm/gdb-stub.h> | 141 | #include <asm/gdb-stub.h> |
142 | #include <asm/inst.h> | 142 | #include <asm/inst.h> |
143 | #include <asm/smp.h> | ||
143 | 144 | ||
144 | /* | 145 | /* |
145 | * external low-level support routines | 146 | * external low-level support routines |
@@ -669,6 +670,64 @@ static void kgdb_wait(void *arg) | |||
669 | local_irq_restore(flags); | 670 | local_irq_restore(flags); |
670 | } | 671 | } |
671 | 672 | ||
673 | /* | ||
674 | * GDB stub needs to call kgdb_wait on all processor with interrupts | ||
675 | * disabled, so it uses it's own special variant. | ||
676 | */ | ||
677 | static int kgdb_smp_call_kgdb_wait(void) | ||
678 | { | ||
679 | #ifdef CONFIG_SMP | ||
680 | struct call_data_struct data; | ||
681 | int i, cpus = num_online_cpus() - 1; | ||
682 | int cpu = smp_processor_id(); | ||
683 | |||
684 | /* | ||
685 | * Can die spectacularly if this CPU isn't yet marked online | ||
686 | */ | ||
687 | BUG_ON(!cpu_online(cpu)); | ||
688 | |||
689 | if (!cpus) | ||
690 | return 0; | ||
691 | |||
692 | if (spin_is_locked(&smp_call_lock)) { | ||
693 | /* | ||
694 | * Some other processor is trying to make us do something | ||
695 | * but we're not going to respond... give up | ||
696 | */ | ||
697 | return -1; | ||
698 | } | ||
699 | |||
700 | /* | ||
701 | * We will continue here, accepting the fact that | ||
702 | * the kernel may deadlock if another CPU attempts | ||
703 | * to call smp_call_function now... | ||
704 | */ | ||
705 | |||
706 | data.func = kgdb_wait; | ||
707 | data.info = NULL; | ||
708 | atomic_set(&data.started, 0); | ||
709 | data.wait = 0; | ||
710 | |||
711 | spin_lock(&smp_call_lock); | ||
712 | call_data = &data; | ||
713 | mb(); | ||
714 | |||
715 | /* Send a message to all other CPUs and wait for them to respond */ | ||
716 | for (i = 0; i < NR_CPUS; i++) | ||
717 | if (cpu_online(i) && i != cpu) | ||
718 | core_send_ipi(i, SMP_CALL_FUNCTION); | ||
719 | |||
720 | /* Wait for response */ | ||
721 | /* FIXME: lock-up detection, backtrace on lock-up */ | ||
722 | while (atomic_read(&data.started) != cpus) | ||
723 | barrier(); | ||
724 | |||
725 | call_data = NULL; | ||
726 | spin_unlock(&smp_call_lock); | ||
727 | #endif | ||
728 | |||
729 | return 0; | ||
730 | } | ||
672 | 731 | ||
673 | /* | 732 | /* |
674 | * This function does all command processing for interfacing to gdb. It | 733 | * This function does all command processing for interfacing to gdb. It |
@@ -718,7 +777,7 @@ void handle_exception (struct gdb_regs *regs) | |||
718 | /* | 777 | /* |
719 | * force other cpus to enter kgdb | 778 | * force other cpus to enter kgdb |
720 | */ | 779 | */ |
721 | smp_call_function(kgdb_wait, NULL, 0, 0); | 780 | kgdb_smp_call_kgdb_wait(); |
722 | 781 | ||
723 | /* | 782 | /* |
724 | * If we're in breakpoint() increment the PC | 783 | * If we're in breakpoint() increment the PC |
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 13f22d1d0e8b..ff7af369f286 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | 13 | ||
14 | #include <asm/asm.h> | 14 | #include <asm/asm.h> |
15 | #include <asm/asmmacro.h> | ||
15 | #include <asm/cacheops.h> | 16 | #include <asm/cacheops.h> |
16 | #include <asm/regdef.h> | 17 | #include <asm/regdef.h> |
17 | #include <asm/fpregdef.h> | 18 | #include <asm/fpregdef.h> |
@@ -122,6 +123,20 @@ handle_vcei: | |||
122 | .set pop | 123 | .set pop |
123 | END(except_vec3_r4000) | 124 | END(except_vec3_r4000) |
124 | 125 | ||
126 | __FINIT | ||
127 | |||
128 | .align 5 | ||
129 | NESTED(handle_int, PT_SIZE, sp) | ||
130 | SAVE_ALL | ||
131 | CLI | ||
132 | |||
133 | PTR_LA ra, ret_from_irq | ||
134 | move a0, sp | ||
135 | j plat_irq_dispatch | ||
136 | END(handle_int) | ||
137 | |||
138 | __INIT | ||
139 | |||
125 | /* | 140 | /* |
126 | * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. | 141 | * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. |
127 | * This is a dedicated interrupt exception vector which reduces the | 142 | * This is a dedicated interrupt exception vector which reduces the |
@@ -157,6 +172,15 @@ NESTED(except_vec_vi, 0, sp) | |||
157 | SAVE_AT | 172 | SAVE_AT |
158 | .set push | 173 | .set push |
159 | .set noreorder | 174 | .set noreorder |
175 | #ifdef CONFIG_MIPS_MT_SMTC | ||
176 | /* | ||
177 | * To keep from blindly blocking *all* interrupts | ||
178 | * during service by SMTC kernel, we also want to | ||
179 | * pass the IM value to be cleared. | ||
180 | */ | ||
181 | EXPORT(except_vec_vi_mori) | ||
182 | ori a0, $0, 0 | ||
183 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
160 | EXPORT(except_vec_vi_lui) | 184 | EXPORT(except_vec_vi_lui) |
161 | lui v0, 0 /* Patched */ | 185 | lui v0, 0 /* Patched */ |
162 | j except_vec_vi_handler | 186 | j except_vec_vi_handler |
@@ -173,6 +197,25 @@ EXPORT(except_vec_vi_end) | |||
173 | NESTED(except_vec_vi_handler, 0, sp) | 197 | NESTED(except_vec_vi_handler, 0, sp) |
174 | SAVE_TEMP | 198 | SAVE_TEMP |
175 | SAVE_STATIC | 199 | SAVE_STATIC |
200 | #ifdef CONFIG_MIPS_MT_SMTC | ||
201 | /* | ||
202 | * SMTC has an interesting problem that interrupts are level-triggered, | ||
203 | * and the CLI macro will clear EXL, potentially causing a duplicate | ||
204 | * interrupt service invocation. So we need to clear the associated | ||
205 | * IM bit of Status prior to doing CLI, and restore it after the | ||
206 | * service routine has been invoked - we must assume that the | ||
207 | * service routine will have cleared the state, and any active | ||
208 | * level represents a new or otherwised unserviced event... | ||
209 | */ | ||
210 | mfc0 t1, CP0_STATUS | ||
211 | and t0, a0, t1 | ||
212 | mfc0 t2, CP0_TCCONTEXT | ||
213 | or t0, t0, t2 | ||
214 | mtc0 t0, CP0_TCCONTEXT | ||
215 | xor t1, t1, t0 | ||
216 | mtc0 t1, CP0_STATUS | ||
217 | ehb | ||
218 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
176 | CLI | 219 | CLI |
177 | move a0, sp | 220 | move a0, sp |
178 | jalr v0 | 221 | jalr v0 |
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 2e9122a4213a..bdf6f6eff721 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/threads.h> | 18 | #include <linux/threads.h> |
19 | 19 | ||
20 | #include <asm/asm.h> | 20 | #include <asm/asm.h> |
21 | #include <asm/asmmacro.h> | ||
21 | #include <asm/regdef.h> | 22 | #include <asm/regdef.h> |
22 | #include <asm/page.h> | 23 | #include <asm/page.h> |
23 | #include <asm/mipsregs.h> | 24 | #include <asm/mipsregs.h> |
@@ -82,12 +83,33 @@ | |||
82 | */ | 83 | */ |
83 | .macro setup_c0_status set clr | 84 | .macro setup_c0_status set clr |
84 | .set push | 85 | .set push |
86 | #ifdef CONFIG_MIPS_MT_SMTC | ||
87 | /* | ||
88 | * For SMTC, we need to set privilege and disable interrupts only for | ||
89 | * the current TC, using the TCStatus register. | ||
90 | */ | ||
91 | mfc0 t0, CP0_TCSTATUS | ||
92 | /* Fortunately CU 0 is in the same place in both registers */ | ||
93 | /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */ | ||
94 | li t1, ST0_CU0 | 0x08001c00 | ||
95 | or t0, t1 | ||
96 | /* Clear TKSU, leave IXMT */ | ||
97 | xori t0, 0x00001800 | ||
98 | mtc0 t0, CP0_TCSTATUS | ||
99 | ehb | ||
100 | /* We need to leave the global IE bit set, but clear EXL...*/ | ||
101 | mfc0 t0, CP0_STATUS | ||
102 | or t0, ST0_CU0 | ST0_EXL | ST0_ERL | \set | \clr | ||
103 | xor t0, ST0_EXL | ST0_ERL | \clr | ||
104 | mtc0 t0, CP0_STATUS | ||
105 | #else | ||
85 | mfc0 t0, CP0_STATUS | 106 | mfc0 t0, CP0_STATUS |
86 | or t0, ST0_CU0|\set|0x1f|\clr | 107 | or t0, ST0_CU0|\set|0x1f|\clr |
87 | xor t0, 0x1f|\clr | 108 | xor t0, 0x1f|\clr |
88 | mtc0 t0, CP0_STATUS | 109 | mtc0 t0, CP0_STATUS |
89 | .set noreorder | 110 | .set noreorder |
90 | sll zero,3 # ehb | 111 | sll zero,3 # ehb |
112 | #endif | ||
91 | .set pop | 113 | .set pop |
92 | .endm | 114 | .endm |
93 | 115 | ||
@@ -134,6 +156,24 @@ NESTED(kernel_entry, 16, sp) # kernel entry point | |||
134 | 156 | ||
135 | ARC64_TWIDDLE_PC | 157 | ARC64_TWIDDLE_PC |
136 | 158 | ||
159 | #ifdef CONFIG_MIPS_MT_SMTC | ||
160 | /* | ||
161 | * In SMTC kernel, "CLI" is thread-specific, in TCStatus. | ||
162 | * We still need to enable interrupts globally in Status, | ||
163 | * and clear EXL/ERL. | ||
164 | * | ||
165 | * TCContext is used to track interrupt levels under | ||
166 | * service in SMTC kernel. Clear for boot TC before | ||
167 | * allowing any interrupts. | ||
168 | */ | ||
169 | mtc0 zero, CP0_TCCONTEXT | ||
170 | |||
171 | mfc0 t0, CP0_STATUS | ||
172 | ori t0, t0, 0xff1f | ||
173 | xori t0, t0, 0x001e | ||
174 | mtc0 t0, CP0_STATUS | ||
175 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
176 | |||
137 | PTR_LA t0, __bss_start # clear .bss | 177 | PTR_LA t0, __bss_start # clear .bss |
138 | LONG_S zero, (t0) | 178 | LONG_S zero, (t0) |
139 | PTR_LA t1, __bss_stop - LONGSIZE | 179 | PTR_LA t1, __bss_stop - LONGSIZE |
@@ -166,8 +206,25 @@ NESTED(kernel_entry, 16, sp) # kernel entry point | |||
166 | * function after setting up the stack and gp registers. | 206 | * function after setting up the stack and gp registers. |
167 | */ | 207 | */ |
168 | NESTED(smp_bootstrap, 16, sp) | 208 | NESTED(smp_bootstrap, 16, sp) |
209 | #ifdef CONFIG_MIPS_MT_SMTC | ||
210 | /* | ||
211 | * Read-modify-writes of Status must be atomic, and this | ||
212 | * is one case where CLI is invoked without EXL being | ||
213 | * necessarily set. The CLI and setup_c0_status will | ||
214 | * in fact be redundant for all but the first TC of | ||
215 | * each VPE being booted. | ||
216 | */ | ||
217 | DMT 10 # dmt t2 /* t0, t1 are used by CLI and setup_c0_status() */ | ||
218 | jal mips_ihb | ||
219 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
169 | setup_c0_status_sec | 220 | setup_c0_status_sec |
170 | smp_slave_setup | 221 | smp_slave_setup |
222 | #ifdef CONFIG_MIPS_MT_SMTC | ||
223 | andi t2, t2, VPECONTROL_TE | ||
224 | beqz t2, 2f | ||
225 | EMT # emt | ||
226 | 2: | ||
227 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
171 | j start_secondary | 228 | j start_secondary |
172 | END(smp_bootstrap) | 229 | END(smp_bootstrap) |
173 | #endif /* CONFIG_SMP */ | 230 | #endif /* CONFIG_SMP */ |
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index b974ac9057f6..2125ba5f1d9b 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c | |||
@@ -187,6 +187,10 @@ handle_real_irq: | |||
187 | outb(cached_21,0x21); | 187 | outb(cached_21,0x21); |
188 | outb(0x60+irq,0x20); /* 'Specific EOI' to master */ | 188 | outb(0x60+irq,0x20); /* 'Specific EOI' to master */ |
189 | } | 189 | } |
190 | #ifdef CONFIG_MIPS_MT_SMTC | ||
191 | if (irq_hwmask[irq] & ST0_IM) | ||
192 | set_c0_status(irq_hwmask[irq] & ST0_IM); | ||
193 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
190 | spin_unlock_irqrestore(&i8259A_lock, flags); | 194 | spin_unlock_irqrestore(&i8259A_lock, flags); |
191 | return; | 195 | return; |
192 | 196 | ||
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index 3f653c7cfbf3..97ebdc754b9e 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c | |||
@@ -76,6 +76,11 @@ static void level_mask_and_ack_msc_irq(unsigned int irq) | |||
76 | mask_msc_irq(irq); | 76 | mask_msc_irq(irq); |
77 | if (!cpu_has_veic) | 77 | if (!cpu_has_veic) |
78 | MSCIC_WRITE(MSC01_IC_EOI, 0); | 78 | MSCIC_WRITE(MSC01_IC_EOI, 0); |
79 | #ifdef CONFIG_MIPS_MT_SMTC | ||
80 | /* This actually needs to be a call into platform code */ | ||
81 | if (irq_hwmask[irq] & ST0_IM) | ||
82 | set_c0_status(irq_hwmask[irq] & ST0_IM); | ||
83 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
79 | } | 84 | } |
80 | 85 | ||
81 | /* | 86 | /* |
@@ -92,6 +97,10 @@ static void edge_mask_and_ack_msc_irq(unsigned int irq) | |||
92 | MSCIC_WRITE(MSC01_IC_SUP+irq*8, r | ~MSC01_IC_SUP_EDGE_BIT); | 97 | MSCIC_WRITE(MSC01_IC_SUP+irq*8, r | ~MSC01_IC_SUP_EDGE_BIT); |
93 | MSCIC_WRITE(MSC01_IC_SUP+irq*8, r); | 98 | MSCIC_WRITE(MSC01_IC_SUP+irq*8, r); |
94 | } | 99 | } |
100 | #ifdef CONFIG_MIPS_MT_SMTC | ||
101 | if (irq_hwmask[irq] & ST0_IM) | ||
102 | set_c0_status(irq_hwmask[irq] & ST0_IM); | ||
103 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
95 | } | 104 | } |
96 | 105 | ||
97 | /* | 106 | /* |
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 3dd76b3d2967..3dce742e716f 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c | |||
@@ -38,6 +38,15 @@ void ack_bad_irq(unsigned int irq) | |||
38 | 38 | ||
39 | atomic_t irq_err_count; | 39 | atomic_t irq_err_count; |
40 | 40 | ||
41 | #ifdef CONFIG_MIPS_MT_SMTC | ||
42 | /* | ||
43 | * SMTC Kernel needs to manipulate low-level CPU interrupt mask | ||
44 | * in do_IRQ. These are passed in setup_irq_smtc() and stored | ||
45 | * in this table. | ||
46 | */ | ||
47 | unsigned long irq_hwmask[NR_IRQS]; | ||
48 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
49 | |||
41 | #undef do_IRQ | 50 | #undef do_IRQ |
42 | 51 | ||
43 | /* | 52 | /* |
@@ -49,6 +58,7 @@ asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs) | |||
49 | { | 58 | { |
50 | irq_enter(); | 59 | irq_enter(); |
51 | 60 | ||
61 | __DO_IRQ_SMTC_HOOK(); | ||
52 | __do_IRQ(irq, regs); | 62 | __do_IRQ(irq, regs); |
53 | 63 | ||
54 | irq_exit(); | 64 | irq_exit(); |
@@ -101,6 +111,11 @@ skip: | |||
101 | return 0; | 111 | return 0; |
102 | } | 112 | } |
103 | 113 | ||
114 | asmlinkage void spurious_interrupt(struct pt_regs *regs) | ||
115 | { | ||
116 | atomic_inc(&irq_err_count); | ||
117 | } | ||
118 | |||
104 | #ifdef CONFIG_KGDB | 119 | #ifdef CONFIG_KGDB |
105 | extern void breakpoint(void); | 120 | extern void breakpoint(void); |
106 | extern void set_debug_traps(void); | 121 | extern void set_debug_traps(void); |
@@ -124,6 +139,9 @@ void __init init_IRQ(void) | |||
124 | irq_desc[i].depth = 1; | 139 | irq_desc[i].depth = 1; |
125 | irq_desc[i].handler = &no_irq_type; | 140 | irq_desc[i].handler = &no_irq_type; |
126 | spin_lock_init(&irq_desc[i].lock); | 141 | spin_lock_init(&irq_desc[i].lock); |
142 | #ifdef CONFIG_MIPS_MT_SMTC | ||
143 | irq_hwmask[i] = 0; | ||
144 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
127 | } | 145 | } |
128 | 146 | ||
129 | arch_init_irq(); | 147 | arch_init_irq(); |
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c new file mode 100644 index 000000000000..f06a144c7881 --- /dev/null +++ b/arch/mips/kernel/kspd.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can distribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License (Version 2) as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
11 | * for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
16 | * | ||
17 | */ | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/unistd.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/syscalls.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/list.h> | ||
27 | |||
28 | #include <asm/vpe.h> | ||
29 | #include <asm/rtlx.h> | ||
30 | #include <asm/kspd.h> | ||
31 | |||
32 | static struct workqueue_struct *workqueue = NULL; | ||
33 | static struct work_struct work; | ||
34 | |||
35 | extern unsigned long cpu_khz; | ||
36 | |||
37 | struct mtsp_syscall { | ||
38 | int cmd; | ||
39 | unsigned char abi; | ||
40 | unsigned char size; | ||
41 | }; | ||
42 | |||
43 | struct mtsp_syscall_ret { | ||
44 | int retval; | ||
45 | int errno; | ||
46 | }; | ||
47 | |||
48 | struct mtsp_syscall_generic { | ||
49 | int arg0; | ||
50 | int arg1; | ||
51 | int arg2; | ||
52 | int arg3; | ||
53 | int arg4; | ||
54 | int arg5; | ||
55 | int arg6; | ||
56 | }; | ||
57 | |||
58 | static struct list_head kspd_notifylist; | ||
59 | static int sp_stopping = 0; | ||
60 | |||
61 | /* these should match with those in the SDE kit */ | ||
62 | #define MTSP_SYSCALL_BASE 0 | ||
63 | #define MTSP_SYSCALL_EXIT (MTSP_SYSCALL_BASE + 0) | ||
64 | #define MTSP_SYSCALL_OPEN (MTSP_SYSCALL_BASE + 1) | ||
65 | #define MTSP_SYSCALL_READ (MTSP_SYSCALL_BASE + 2) | ||
66 | #define MTSP_SYSCALL_WRITE (MTSP_SYSCALL_BASE + 3) | ||
67 | #define MTSP_SYSCALL_CLOSE (MTSP_SYSCALL_BASE + 4) | ||
68 | #define MTSP_SYSCALL_LSEEK32 (MTSP_SYSCALL_BASE + 5) | ||
69 | #define MTSP_SYSCALL_ISATTY (MTSP_SYSCALL_BASE + 6) | ||
70 | #define MTSP_SYSCALL_GETTIME (MTSP_SYSCALL_BASE + 7) | ||
71 | #define MTSP_SYSCALL_PIPEFREQ (MTSP_SYSCALL_BASE + 8) | ||
72 | #define MTSP_SYSCALL_GETTOD (MTSP_SYSCALL_BASE + 9) | ||
73 | |||
74 | #define MTSP_O_RDONLY 0x0000 | ||
75 | #define MTSP_O_WRONLY 0x0001 | ||
76 | #define MTSP_O_RDWR 0x0002 | ||
77 | #define MTSP_O_NONBLOCK 0x0004 | ||
78 | #define MTSP_O_APPEND 0x0008 | ||
79 | #define MTSP_O_SHLOCK 0x0010 | ||
80 | #define MTSP_O_EXLOCK 0x0020 | ||
81 | #define MTSP_O_ASYNC 0x0040 | ||
82 | #define MTSP_O_FSYNC O_SYNC | ||
83 | #define MTSP_O_NOFOLLOW 0x0100 | ||
84 | #define MTSP_O_SYNC 0x0080 | ||
85 | #define MTSP_O_CREAT 0x0200 | ||
86 | #define MTSP_O_TRUNC 0x0400 | ||
87 | #define MTSP_O_EXCL 0x0800 | ||
88 | #define MTSP_O_BINARY 0x8000 | ||
89 | |||
90 | #define SP_VPE 1 | ||
91 | |||
92 | struct apsp_table { | ||
93 | int sp; | ||
94 | int ap; | ||
95 | }; | ||
96 | |||
97 | /* we might want to do the mode flags too */ | ||
98 | struct apsp_table open_flags_table[] = { | ||
99 | { MTSP_O_RDWR, O_RDWR }, | ||
100 | { MTSP_O_WRONLY, O_WRONLY }, | ||
101 | { MTSP_O_CREAT, O_CREAT }, | ||
102 | { MTSP_O_TRUNC, O_TRUNC }, | ||
103 | { MTSP_O_NONBLOCK, O_NONBLOCK }, | ||
104 | { MTSP_O_APPEND, O_APPEND }, | ||
105 | { MTSP_O_NOFOLLOW, O_NOFOLLOW } | ||
106 | }; | ||
107 | |||
108 | struct apsp_table syscall_command_table[] = { | ||
109 | { MTSP_SYSCALL_OPEN, __NR_open }, | ||
110 | { MTSP_SYSCALL_CLOSE, __NR_close }, | ||
111 | { MTSP_SYSCALL_READ, __NR_read }, | ||
112 | { MTSP_SYSCALL_WRITE, __NR_write }, | ||
113 | { MTSP_SYSCALL_LSEEK32, __NR_lseek } | ||
114 | }; | ||
115 | |||
116 | static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3) | ||
117 | { | ||
118 | register long int _num __asm__ ("$2") = num; | ||
119 | register long int _arg0 __asm__ ("$4") = arg0; | ||
120 | register long int _arg1 __asm__ ("$5") = arg1; | ||
121 | register long int _arg2 __asm__ ("$6") = arg2; | ||
122 | register long int _arg3 __asm__ ("$7") = arg3; | ||
123 | |||
124 | mm_segment_t old_fs; | ||
125 | |||
126 | old_fs = get_fs(); | ||
127 | set_fs(KERNEL_DS); | ||
128 | |||
129 | __asm__ __volatile__ ( | ||
130 | " syscall \n" | ||
131 | : "=r" (_num), "=r" (_arg3) | ||
132 | : "r" (_num), "r" (_arg0), "r" (_arg1), "r" (_arg2), "r" (_arg3)); | ||
133 | |||
134 | set_fs(old_fs); | ||
135 | |||
136 | /* $a3 is error flag */ | ||
137 | if (_arg3) | ||
138 | return -_num; | ||
139 | |||
140 | return _num; | ||
141 | } | ||
142 | |||
143 | static int translate_syscall_command(int cmd) | ||
144 | { | ||
145 | int i; | ||
146 | int ret = -1; | ||
147 | |||
148 | for (i = 0; i < ARRAY_SIZE(syscall_command_table); i++) { | ||
149 | if ((cmd == syscall_command_table[i].sp)) | ||
150 | return syscall_command_table[i].ap; | ||
151 | } | ||
152 | |||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | static unsigned int translate_open_flags(int flags) | ||
157 | { | ||
158 | int i; | ||
159 | unsigned int ret = 0; | ||
160 | |||
161 | for (i = 0; i < (sizeof(open_flags_table) / sizeof(struct apsp_table)); | ||
162 | i++) { | ||
163 | if( (flags & open_flags_table[i].sp) ) { | ||
164 | ret |= open_flags_table[i].ap; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | |||
172 | static void sp_setfsuidgid( uid_t uid, gid_t gid) | ||
173 | { | ||
174 | current->fsuid = uid; | ||
175 | current->fsgid = gid; | ||
176 | |||
177 | key_fsuid_changed(current); | ||
178 | key_fsgid_changed(current); | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * Expects a request to be on the sysio channel. Reads it. Decides whether | ||
183 | * its a linux syscall and runs it, or whatever. Puts the return code back | ||
184 | * into the request and sends the whole thing back. | ||
185 | */ | ||
186 | void sp_work_handle_request(void) | ||
187 | { | ||
188 | struct mtsp_syscall sc; | ||
189 | struct mtsp_syscall_generic generic; | ||
190 | struct mtsp_syscall_ret ret; | ||
191 | struct kspd_notifications *n; | ||
192 | struct timeval tv; | ||
193 | struct timezone tz; | ||
194 | int cmd; | ||
195 | |||
196 | char *vcwd; | ||
197 | mm_segment_t old_fs; | ||
198 | int size; | ||
199 | |||
200 | ret.retval = -1; | ||
201 | |||
202 | if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall), 0)) { | ||
203 | printk(KERN_ERR "Expected request but nothing to read\n"); | ||
204 | return; | ||
205 | } | ||
206 | |||
207 | size = sc.size; | ||
208 | |||
209 | if (size) { | ||
210 | if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size, 0)) { | ||
211 | printk(KERN_ERR "Expected request but nothing to read\n"); | ||
212 | return; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | /* Run the syscall at the priviledge of the user who loaded the | ||
217 | SP program */ | ||
218 | |||
219 | if (vpe_getuid(SP_VPE)) | ||
220 | sp_setfsuidgid( vpe_getuid(SP_VPE), vpe_getgid(SP_VPE)); | ||
221 | |||
222 | switch (sc.cmd) { | ||
223 | /* needs the flags argument translating from SDE kit to | ||
224 | linux */ | ||
225 | case MTSP_SYSCALL_PIPEFREQ: | ||
226 | ret.retval = cpu_khz * 1000; | ||
227 | ret.errno = 0; | ||
228 | break; | ||
229 | |||
230 | case MTSP_SYSCALL_GETTOD: | ||
231 | memset(&tz, 0, sizeof(tz)); | ||
232 | if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv, | ||
233 | (int)&tz, 0,0)) == 0) | ||
234 | ret.retval = tv.tv_sec; | ||
235 | |||
236 | ret.errno = errno; | ||
237 | break; | ||
238 | |||
239 | case MTSP_SYSCALL_EXIT: | ||
240 | list_for_each_entry(n, &kspd_notifylist, list) | ||
241 | n->kspd_sp_exit(SP_VPE); | ||
242 | sp_stopping = 1; | ||
243 | |||
244 | printk(KERN_DEBUG "KSPD got exit syscall from SP exitcode %d\n", | ||
245 | generic.arg0); | ||
246 | break; | ||
247 | |||
248 | case MTSP_SYSCALL_OPEN: | ||
249 | generic.arg1 = translate_open_flags(generic.arg1); | ||
250 | |||
251 | vcwd = vpe_getcwd(SP_VPE); | ||
252 | |||
253 | /* change to the cwd of the process that loaded the SP program */ | ||
254 | old_fs = get_fs(); | ||
255 | set_fs(KERNEL_DS); | ||
256 | sys_chdir(vcwd); | ||
257 | set_fs(old_fs); | ||
258 | |||
259 | sc.cmd = __NR_open; | ||
260 | |||
261 | /* fall through */ | ||
262 | |||
263 | default: | ||
264 | if ((sc.cmd >= __NR_Linux) && | ||
265 | (sc.cmd <= (__NR_Linux + __NR_Linux_syscalls)) ) | ||
266 | cmd = sc.cmd; | ||
267 | else | ||
268 | cmd = translate_syscall_command(sc.cmd); | ||
269 | |||
270 | if (cmd >= 0) { | ||
271 | ret.retval = sp_syscall(cmd, generic.arg0, generic.arg1, | ||
272 | generic.arg2, generic.arg3); | ||
273 | ret.errno = errno; | ||
274 | } else | ||
275 | printk(KERN_WARNING | ||
276 | "KSPD: Unknown SP syscall number %d\n", sc.cmd); | ||
277 | break; | ||
278 | } /* switch */ | ||
279 | |||
280 | if (vpe_getuid(SP_VPE)) | ||
281 | sp_setfsuidgid( 0, 0); | ||
282 | |||
283 | if ((rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(struct mtsp_syscall_ret), 0)) | ||
284 | < sizeof(struct mtsp_syscall_ret)) | ||
285 | printk("KSPD: sp_work_handle_request failed to send to SP\n"); | ||
286 | } | ||
287 | |||
288 | static void sp_cleanup(void) | ||
289 | { | ||
290 | struct files_struct *files = current->files; | ||
291 | int i, j; | ||
292 | struct fdtable *fdt; | ||
293 | |||
294 | j = 0; | ||
295 | |||
296 | /* | ||
297 | * It is safe to dereference the fd table without RCU or | ||
298 | * ->file_lock | ||
299 | */ | ||
300 | fdt = files_fdtable(files); | ||
301 | for (;;) { | ||
302 | unsigned long set; | ||
303 | i = j * __NFDBITS; | ||
304 | if (i >= fdt->max_fdset || i >= fdt->max_fds) | ||
305 | break; | ||
306 | set = fdt->open_fds->fds_bits[j++]; | ||
307 | while (set) { | ||
308 | if (set & 1) { | ||
309 | struct file * file = xchg(&fdt->fd[i], NULL); | ||
310 | if (file) | ||
311 | filp_close(file, files); | ||
312 | } | ||
313 | i++; | ||
314 | set >>= 1; | ||
315 | } | ||
316 | } | ||
317 | } | ||
318 | |||
319 | static int channel_open = 0; | ||
320 | |||
321 | /* the work handler */ | ||
322 | static void sp_work(void *data) | ||
323 | { | ||
324 | if (!channel_open) { | ||
325 | if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) { | ||
326 | printk("KSPD: unable to open sp channel\n"); | ||
327 | sp_stopping = 1; | ||
328 | } else { | ||
329 | channel_open++; | ||
330 | printk(KERN_DEBUG "KSPD: SP channel opened\n"); | ||
331 | } | ||
332 | } else { | ||
333 | /* wait for some data, allow it to sleep */ | ||
334 | rtlx_read_poll(RTLX_CHANNEL_SYSIO, 1); | ||
335 | |||
336 | /* Check we haven't been woken because we are stopping */ | ||
337 | if (!sp_stopping) | ||
338 | sp_work_handle_request(); | ||
339 | } | ||
340 | |||
341 | if (!sp_stopping) | ||
342 | queue_work(workqueue, &work); | ||
343 | else | ||
344 | sp_cleanup(); | ||
345 | } | ||
346 | |||
347 | static void startwork(int vpe) | ||
348 | { | ||
349 | sp_stopping = channel_open = 0; | ||
350 | |||
351 | if (workqueue == NULL) { | ||
352 | if ((workqueue = create_singlethread_workqueue("kspd")) == NULL) { | ||
353 | printk(KERN_ERR "unable to start kspd\n"); | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | INIT_WORK(&work, sp_work, NULL); | ||
358 | queue_work(workqueue, &work); | ||
359 | } else | ||
360 | queue_work(workqueue, &work); | ||
361 | |||
362 | } | ||
363 | |||
364 | static void stopwork(int vpe) | ||
365 | { | ||
366 | sp_stopping = 1; | ||
367 | |||
368 | printk(KERN_DEBUG "KSPD: SP stopping\n"); | ||
369 | } | ||
370 | |||
371 | void kspd_notify(struct kspd_notifications *notify) | ||
372 | { | ||
373 | list_add(¬ify->list, &kspd_notifylist); | ||
374 | } | ||
375 | |||
376 | static struct vpe_notifications notify; | ||
377 | static int kspd_module_init(void) | ||
378 | { | ||
379 | INIT_LIST_HEAD(&kspd_notifylist); | ||
380 | |||
381 | notify.start = startwork; | ||
382 | notify.stop = stopwork; | ||
383 | vpe_notify(SP_VPE, ¬ify); | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static void kspd_module_exit(void) | ||
389 | { | ||
390 | |||
391 | } | ||
392 | |||
393 | module_init(kspd_module_init); | ||
394 | module_exit(kspd_module_exit); | ||
395 | |||
396 | MODULE_DESCRIPTION("MIPS KSPD"); | ||
397 | MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc."); | ||
398 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 3f40c37a9ee6..7c953bcc5f6a 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -1182,6 +1182,16 @@ asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3, | |||
1182 | return sys_readahead(fd, merge_64(a2, a3), count); | 1182 | return sys_readahead(fd, merge_64(a2, a3), count); |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | asmlinkage long sys32_sync_file_range(int fd, int __pad, | ||
1186 | unsigned long a2, unsigned long a3, | ||
1187 | unsigned long a4, unsigned long a5, | ||
1188 | int flags) | ||
1189 | { | ||
1190 | return sys_sync_file_range(fd, | ||
1191 | merge_64(a2, a3), merge_64(a4, a5), | ||
1192 | flags); | ||
1193 | } | ||
1194 | |||
1185 | /* Argument list sizes for sys_socketcall */ | 1195 | /* Argument list sizes for sys_socketcall */ |
1186 | #define AL(x) ((x) * sizeof(unsigned int)) | 1196 | #define AL(x) ((x) * sizeof(unsigned int)) |
1187 | static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), | 1197 | static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), |
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c new file mode 100644 index 000000000000..02237a685ec7 --- /dev/null +++ b/arch/mips/kernel/mips-mt.c | |||
@@ -0,0 +1,449 @@ | |||
1 | /* | ||
2 | * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels | ||
3 | * Copyright (C) 2005 Mips Technologies, Inc | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/sched.h> | ||
8 | #include <linux/cpumask.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | |||
11 | #include <asm/cpu.h> | ||
12 | #include <asm/processor.h> | ||
13 | #include <asm/atomic.h> | ||
14 | #include <asm/system.h> | ||
15 | #include <asm/hardirq.h> | ||
16 | #include <asm/mmu_context.h> | ||
17 | #include <asm/smp.h> | ||
18 | #include <asm/mipsmtregs.h> | ||
19 | #include <asm/r4kcache.h> | ||
20 | #include <asm/cacheflush.h> | ||
21 | |||
22 | /* | ||
23 | * CPU mask used to set process affinity for MT VPEs/TCs with FPUs | ||
24 | */ | ||
25 | |||
26 | cpumask_t mt_fpu_cpumask; | ||
27 | |||
28 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
29 | |||
30 | #include <linux/cpu.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <asm/uaccess.h> | ||
33 | |||
34 | unsigned long mt_fpemul_threshold = 0; | ||
35 | |||
36 | /* | ||
37 | * Replacement functions for the sys_sched_setaffinity() and | ||
38 | * sys_sched_getaffinity() system calls, so that we can integrate | ||
39 | * FPU affinity with the user's requested processor affinity. | ||
40 | * This code is 98% identical with the sys_sched_setaffinity() | ||
41 | * and sys_sched_getaffinity() system calls, and should be | ||
42 | * updated when kernel/sched.c changes. | ||
43 | */ | ||
44 | |||
45 | /* | ||
46 | * find_process_by_pid - find a process with a matching PID value. | ||
47 | * used in sys_sched_set/getaffinity() in kernel/sched.c, so | ||
48 | * cloned here. | ||
49 | */ | ||
50 | static inline task_t *find_process_by_pid(pid_t pid) | ||
51 | { | ||
52 | return pid ? find_task_by_pid(pid) : current; | ||
53 | } | ||
54 | |||
55 | |||
56 | /* | ||
57 | * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process | ||
58 | */ | ||
59 | asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, | ||
60 | unsigned long __user *user_mask_ptr) | ||
61 | { | ||
62 | cpumask_t new_mask; | ||
63 | cpumask_t effective_mask; | ||
64 | int retval; | ||
65 | task_t *p; | ||
66 | |||
67 | if (len < sizeof(new_mask)) | ||
68 | return -EINVAL; | ||
69 | |||
70 | if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask))) | ||
71 | return -EFAULT; | ||
72 | |||
73 | lock_cpu_hotplug(); | ||
74 | read_lock(&tasklist_lock); | ||
75 | |||
76 | p = find_process_by_pid(pid); | ||
77 | if (!p) { | ||
78 | read_unlock(&tasklist_lock); | ||
79 | unlock_cpu_hotplug(); | ||
80 | return -ESRCH; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * It is not safe to call set_cpus_allowed with the | ||
85 | * tasklist_lock held. We will bump the task_struct's | ||
86 | * usage count and drop tasklist_lock before invoking | ||
87 | * set_cpus_allowed. | ||
88 | */ | ||
89 | get_task_struct(p); | ||
90 | |||
91 | retval = -EPERM; | ||
92 | if ((current->euid != p->euid) && (current->euid != p->uid) && | ||
93 | !capable(CAP_SYS_NICE)) { | ||
94 | read_unlock(&tasklist_lock); | ||
95 | goto out_unlock; | ||
96 | } | ||
97 | |||
98 | /* Record new user-specified CPU set for future reference */ | ||
99 | p->thread.user_cpus_allowed = new_mask; | ||
100 | |||
101 | /* Unlock the task list */ | ||
102 | read_unlock(&tasklist_lock); | ||
103 | |||
104 | /* Compute new global allowed CPU set if necessary */ | ||
105 | if( (p->thread.mflags & MF_FPUBOUND) | ||
106 | && cpus_intersects(new_mask, mt_fpu_cpumask)) { | ||
107 | cpus_and(effective_mask, new_mask, mt_fpu_cpumask); | ||
108 | retval = set_cpus_allowed(p, effective_mask); | ||
109 | } else { | ||
110 | p->thread.mflags &= ~MF_FPUBOUND; | ||
111 | retval = set_cpus_allowed(p, new_mask); | ||
112 | } | ||
113 | |||
114 | |||
115 | out_unlock: | ||
116 | put_task_struct(p); | ||
117 | unlock_cpu_hotplug(); | ||
118 | return retval; | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process | ||
123 | */ | ||
124 | asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, | ||
125 | unsigned long __user *user_mask_ptr) | ||
126 | { | ||
127 | unsigned int real_len; | ||
128 | cpumask_t mask; | ||
129 | int retval; | ||
130 | task_t *p; | ||
131 | |||
132 | real_len = sizeof(mask); | ||
133 | if (len < real_len) | ||
134 | return -EINVAL; | ||
135 | |||
136 | lock_cpu_hotplug(); | ||
137 | read_lock(&tasklist_lock); | ||
138 | |||
139 | retval = -ESRCH; | ||
140 | p = find_process_by_pid(pid); | ||
141 | if (!p) | ||
142 | goto out_unlock; | ||
143 | |||
144 | retval = 0; | ||
145 | |||
146 | cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map); | ||
147 | |||
148 | out_unlock: | ||
149 | read_unlock(&tasklist_lock); | ||
150 | unlock_cpu_hotplug(); | ||
151 | if (retval) | ||
152 | return retval; | ||
153 | if (copy_to_user(user_mask_ptr, &mask, real_len)) | ||
154 | return -EFAULT; | ||
155 | return real_len; | ||
156 | } | ||
157 | |||
158 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
159 | |||
160 | /* | ||
161 | * Dump new MIPS MT state for the core. Does not leave TCs halted. | ||
162 | * Takes an argument which taken to be a pre-call MVPControl value. | ||
163 | */ | ||
164 | |||
165 | void mips_mt_regdump(unsigned long mvpctl) | ||
166 | { | ||
167 | unsigned long flags; | ||
168 | unsigned long vpflags; | ||
169 | unsigned long mvpconf0; | ||
170 | int nvpe; | ||
171 | int ntc; | ||
172 | int i; | ||
173 | int tc; | ||
174 | unsigned long haltval; | ||
175 | unsigned long tcstatval; | ||
176 | #ifdef CONFIG_MIPS_MT_SMTC | ||
177 | void smtc_soft_dump(void); | ||
178 | #endif /* CONFIG_MIPT_MT_SMTC */ | ||
179 | |||
180 | local_irq_save(flags); | ||
181 | vpflags = dvpe(); | ||
182 | printk("=== MIPS MT State Dump ===\n"); | ||
183 | printk("-- Global State --\n"); | ||
184 | printk(" MVPControl Passed: %08lx\n", mvpctl); | ||
185 | printk(" MVPControl Read: %08lx\n", vpflags); | ||
186 | printk(" MVPConf0 : %08lx\n", (mvpconf0 = read_c0_mvpconf0())); | ||
187 | nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; | ||
188 | ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; | ||
189 | printk("-- per-VPE State --\n"); | ||
190 | for(i = 0; i < nvpe; i++) { | ||
191 | for(tc = 0; tc < ntc; tc++) { | ||
192 | settc(tc); | ||
193 | if((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) { | ||
194 | printk(" VPE %d\n", i); | ||
195 | printk(" VPEControl : %08lx\n", read_vpe_c0_vpecontrol()); | ||
196 | printk(" VPEConf0 : %08lx\n", read_vpe_c0_vpeconf0()); | ||
197 | printk(" VPE%d.Status : %08lx\n", | ||
198 | i, read_vpe_c0_status()); | ||
199 | printk(" VPE%d.EPC : %08lx\n", i, read_vpe_c0_epc()); | ||
200 | printk(" VPE%d.Cause : %08lx\n", i, read_vpe_c0_cause()); | ||
201 | printk(" VPE%d.Config7 : %08lx\n", | ||
202 | i, read_vpe_c0_config7()); | ||
203 | break; /* Next VPE */ | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | printk("-- per-TC State --\n"); | ||
208 | for(tc = 0; tc < ntc; tc++) { | ||
209 | settc(tc); | ||
210 | if(read_tc_c0_tcbind() == read_c0_tcbind()) { | ||
211 | /* Are we dumping ourself? */ | ||
212 | haltval = 0; /* Then we're not halted, and mustn't be */ | ||
213 | tcstatval = flags; /* And pre-dump TCStatus is flags */ | ||
214 | printk(" TC %d (current TC with VPE EPC above)\n", tc); | ||
215 | } else { | ||
216 | haltval = read_tc_c0_tchalt(); | ||
217 | write_tc_c0_tchalt(1); | ||
218 | tcstatval = read_tc_c0_tcstatus(); | ||
219 | printk(" TC %d\n", tc); | ||
220 | } | ||
221 | printk(" TCStatus : %08lx\n", tcstatval); | ||
222 | printk(" TCBind : %08lx\n", read_tc_c0_tcbind()); | ||
223 | printk(" TCRestart : %08lx\n", read_tc_c0_tcrestart()); | ||
224 | printk(" TCHalt : %08lx\n", haltval); | ||
225 | printk(" TCContext : %08lx\n", read_tc_c0_tccontext()); | ||
226 | if (!haltval) | ||
227 | write_tc_c0_tchalt(0); | ||
228 | } | ||
229 | #ifdef CONFIG_MIPS_MT_SMTC | ||
230 | smtc_soft_dump(); | ||
231 | #endif /* CONFIG_MIPT_MT_SMTC */ | ||
232 | printk("===========================\n"); | ||
233 | evpe(vpflags); | ||
234 | local_irq_restore(flags); | ||
235 | } | ||
236 | |||
237 | static int mt_opt_norps = 0; | ||
238 | static int mt_opt_rpsctl = -1; | ||
239 | static int mt_opt_nblsu = -1; | ||
240 | static int mt_opt_forceconfig7 = 0; | ||
241 | static int mt_opt_config7 = -1; | ||
242 | |||
243 | static int __init rps_disable(char *s) | ||
244 | { | ||
245 | mt_opt_norps = 1; | ||
246 | return 1; | ||
247 | } | ||
248 | __setup("norps", rps_disable); | ||
249 | |||
250 | static int __init rpsctl_set(char *str) | ||
251 | { | ||
252 | get_option(&str, &mt_opt_rpsctl); | ||
253 | return 1; | ||
254 | } | ||
255 | __setup("rpsctl=", rpsctl_set); | ||
256 | |||
257 | static int __init nblsu_set(char *str) | ||
258 | { | ||
259 | get_option(&str, &mt_opt_nblsu); | ||
260 | return 1; | ||
261 | } | ||
262 | __setup("nblsu=", nblsu_set); | ||
263 | |||
264 | static int __init config7_set(char *str) | ||
265 | { | ||
266 | get_option(&str, &mt_opt_config7); | ||
267 | mt_opt_forceconfig7 = 1; | ||
268 | return 1; | ||
269 | } | ||
270 | __setup("config7=", config7_set); | ||
271 | |||
272 | /* Experimental cache flush control parameters that should go away some day */ | ||
273 | int mt_protiflush = 0; | ||
274 | int mt_protdflush = 0; | ||
275 | int mt_n_iflushes = 1; | ||
276 | int mt_n_dflushes = 1; | ||
277 | |||
278 | static int __init set_protiflush(char *s) | ||
279 | { | ||
280 | mt_protiflush = 1; | ||
281 | return 1; | ||
282 | } | ||
283 | __setup("protiflush", set_protiflush); | ||
284 | |||
285 | static int __init set_protdflush(char *s) | ||
286 | { | ||
287 | mt_protdflush = 1; | ||
288 | return 1; | ||
289 | } | ||
290 | __setup("protdflush", set_protdflush); | ||
291 | |||
292 | static int __init niflush(char *s) | ||
293 | { | ||
294 | get_option(&s, &mt_n_iflushes); | ||
295 | return 1; | ||
296 | } | ||
297 | __setup("niflush=", niflush); | ||
298 | |||
299 | static int __init ndflush(char *s) | ||
300 | { | ||
301 | get_option(&s, &mt_n_dflushes); | ||
302 | return 1; | ||
303 | } | ||
304 | __setup("ndflush=", ndflush); | ||
305 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
306 | static int fpaff_threshold = -1; | ||
307 | |||
308 | static int __init fpaff_thresh(char *str) | ||
309 | { | ||
310 | get_option(&str, &fpaff_threshold); | ||
311 | return 1; | ||
312 | } | ||
313 | |||
314 | __setup("fpaff=", fpaff_thresh); | ||
315 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
316 | |||
317 | static unsigned int itc_base = 0; | ||
318 | |||
319 | static int __init set_itc_base(char *str) | ||
320 | { | ||
321 | get_option(&str, &itc_base); | ||
322 | return 1; | ||
323 | } | ||
324 | |||
325 | __setup("itcbase=", set_itc_base); | ||
326 | |||
327 | void mips_mt_set_cpuoptions(void) | ||
328 | { | ||
329 | unsigned int oconfig7 = read_c0_config7(); | ||
330 | unsigned int nconfig7 = oconfig7; | ||
331 | |||
332 | if (mt_opt_norps) { | ||
333 | printk("\"norps\" option deprectated: use \"rpsctl=\"\n"); | ||
334 | } | ||
335 | if (mt_opt_rpsctl >= 0) { | ||
336 | printk("34K return prediction stack override set to %d.\n", | ||
337 | mt_opt_rpsctl); | ||
338 | if (mt_opt_rpsctl) | ||
339 | nconfig7 |= (1 << 2); | ||
340 | else | ||
341 | nconfig7 &= ~(1 << 2); | ||
342 | } | ||
343 | if (mt_opt_nblsu >= 0) { | ||
344 | printk("34K ALU/LSU sync override set to %d.\n", mt_opt_nblsu); | ||
345 | if (mt_opt_nblsu) | ||
346 | nconfig7 |= (1 << 5); | ||
347 | else | ||
348 | nconfig7 &= ~(1 << 5); | ||
349 | } | ||
350 | if (mt_opt_forceconfig7) { | ||
351 | printk("CP0.Config7 forced to 0x%08x.\n", mt_opt_config7); | ||
352 | nconfig7 = mt_opt_config7; | ||
353 | } | ||
354 | if (oconfig7 != nconfig7) { | ||
355 | __asm__ __volatile("sync"); | ||
356 | write_c0_config7(nconfig7); | ||
357 | ehb (); | ||
358 | printk("Config7: 0x%08x\n", read_c0_config7()); | ||
359 | } | ||
360 | |||
361 | /* Report Cache management debug options */ | ||
362 | if (mt_protiflush) | ||
363 | printk("I-cache flushes single-threaded\n"); | ||
364 | if (mt_protdflush) | ||
365 | printk("D-cache flushes single-threaded\n"); | ||
366 | if (mt_n_iflushes != 1) | ||
367 | printk("I-Cache Flushes Repeated %d times\n", mt_n_iflushes); | ||
368 | if (mt_n_dflushes != 1) | ||
369 | printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes); | ||
370 | |||
371 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
372 | /* FPU Use Factor empirically derived from experiments on 34K */ | ||
373 | #define FPUSEFACTOR 333 | ||
374 | |||
375 | if (fpaff_threshold >= 0) { | ||
376 | mt_fpemul_threshold = fpaff_threshold; | ||
377 | } else { | ||
378 | mt_fpemul_threshold = | ||
379 | (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ; | ||
380 | } | ||
381 | printk("FPU Affinity set after %ld emulations\n", | ||
382 | mt_fpemul_threshold); | ||
383 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
384 | |||
385 | if (itc_base != 0) { | ||
386 | /* | ||
387 | * Configure ITC mapping. This code is very | ||
388 | * specific to the 34K core family, which uses | ||
389 | * a special mode bit ("ITC") in the ErrCtl | ||
390 | * register to enable access to ITC control | ||
391 | * registers via cache "tag" operations. | ||
392 | */ | ||
393 | unsigned long ectlval; | ||
394 | unsigned long itcblkgrn; | ||
395 | |||
396 | /* ErrCtl register is known as "ecc" to Linux */ | ||
397 | ectlval = read_c0_ecc(); | ||
398 | write_c0_ecc(ectlval | (0x1 << 26)); | ||
399 | ehb(); | ||
400 | #define INDEX_0 (0x80000000) | ||
401 | #define INDEX_8 (0x80000008) | ||
402 | /* Read "cache tag" for Dcache pseudo-index 8 */ | ||
403 | cache_op(Index_Load_Tag_D, INDEX_8); | ||
404 | ehb(); | ||
405 | itcblkgrn = read_c0_dtaglo(); | ||
406 | itcblkgrn &= 0xfffe0000; | ||
407 | /* Set for 128 byte pitch of ITC cells */ | ||
408 | itcblkgrn |= 0x00000c00; | ||
409 | /* Stage in Tag register */ | ||
410 | write_c0_dtaglo(itcblkgrn); | ||
411 | ehb(); | ||
412 | /* Write out to ITU with CACHE op */ | ||
413 | cache_op(Index_Store_Tag_D, INDEX_8); | ||
414 | /* Now set base address, and turn ITC on with 0x1 bit */ | ||
415 | write_c0_dtaglo((itc_base & 0xfffffc00) | 0x1 ); | ||
416 | ehb(); | ||
417 | /* Write out to ITU with CACHE op */ | ||
418 | cache_op(Index_Store_Tag_D, INDEX_0); | ||
419 | write_c0_ecc(ectlval); | ||
420 | ehb(); | ||
421 | printk("Mapped %ld ITC cells starting at 0x%08x\n", | ||
422 | ((itcblkgrn & 0x7fe00000) >> 20), itc_base); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | /* | ||
427 | * Function to protect cache flushes from concurrent execution | ||
428 | * depends on MP software model chosen. | ||
429 | */ | ||
430 | |||
431 | void mt_cflush_lockdown(void) | ||
432 | { | ||
433 | #ifdef CONFIG_MIPS_MT_SMTC | ||
434 | void smtc_cflush_lockdown(void); | ||
435 | |||
436 | smtc_cflush_lockdown(); | ||
437 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
438 | /* FILL IN VSMP and AP/SP VERSIONS HERE */ | ||
439 | } | ||
440 | |||
441 | void mt_cflush_release(void) | ||
442 | { | ||
443 | #ifdef CONFIG_MIPS_MT_SMTC | ||
444 | void smtc_cflush_release(void); | ||
445 | |||
446 | smtc_cflush_release(); | ||
447 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
448 | /* FILL IN VSMP and AP/SP VERSIONS HERE */ | ||
449 | } | ||
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 86e42c633f73..0a71a4c33716 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c | |||
@@ -28,22 +28,9 @@ extern long __strnlen_user_asm(const char *s); | |||
28 | /* | 28 | /* |
29 | * String functions | 29 | * String functions |
30 | */ | 30 | */ |
31 | EXPORT_SYMBOL(memchr); | ||
32 | EXPORT_SYMBOL(memcmp); | ||
33 | EXPORT_SYMBOL(memset); | 31 | EXPORT_SYMBOL(memset); |
34 | EXPORT_SYMBOL(memcpy); | 32 | EXPORT_SYMBOL(memcpy); |
35 | EXPORT_SYMBOL(memmove); | 33 | EXPORT_SYMBOL(memmove); |
36 | EXPORT_SYMBOL(strcat); | ||
37 | EXPORT_SYMBOL(strchr); | ||
38 | #ifdef CONFIG_64BIT | ||
39 | EXPORT_SYMBOL(strncmp); | ||
40 | #endif | ||
41 | EXPORT_SYMBOL(strlen); | ||
42 | EXPORT_SYMBOL(strpbrk); | ||
43 | EXPORT_SYMBOL(strncat); | ||
44 | EXPORT_SYMBOL(strnlen); | ||
45 | EXPORT_SYMBOL(strrchr); | ||
46 | EXPORT_SYMBOL(strstr); | ||
47 | 34 | ||
48 | EXPORT_SYMBOL(kernel_thread); | 35 | EXPORT_SYMBOL(kernel_thread); |
49 | 36 | ||
@@ -62,6 +49,3 @@ EXPORT_SYMBOL(__strnlen_user_asm); | |||
62 | EXPORT_SYMBOL(csum_partial); | 49 | EXPORT_SYMBOL(csum_partial); |
63 | 50 | ||
64 | EXPORT_SYMBOL(invalid_pte_table); | 51 | EXPORT_SYMBOL(invalid_pte_table); |
65 | #ifdef CONFIG_GENERIC_IRQ_PROBE | ||
66 | EXPORT_SYMBOL(probe_irq_mask); | ||
67 | #endif | ||
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index c66db5e5ab62..199a06e873c6 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -41,6 +41,10 @@ | |||
41 | #include <asm/elf.h> | 41 | #include <asm/elf.h> |
42 | #include <asm/isadep.h> | 42 | #include <asm/isadep.h> |
43 | #include <asm/inst.h> | 43 | #include <asm/inst.h> |
44 | #ifdef CONFIG_MIPS_MT_SMTC | ||
45 | #include <asm/mipsmtregs.h> | ||
46 | extern void smtc_idle_loop_hook(void); | ||
47 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
44 | 48 | ||
45 | /* | 49 | /* |
46 | * The idle thread. There's no useful work to be done, so just try to conserve | 50 | * The idle thread. There's no useful work to be done, so just try to conserve |
@@ -51,9 +55,13 @@ ATTRIB_NORET void cpu_idle(void) | |||
51 | { | 55 | { |
52 | /* endless idle loop with no priority at all */ | 56 | /* endless idle loop with no priority at all */ |
53 | while (1) { | 57 | while (1) { |
54 | while (!need_resched()) | 58 | while (!need_resched()) { |
59 | #ifdef CONFIG_MIPS_MT_SMTC | ||
60 | smtc_idle_loop_hook(); | ||
61 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
55 | if (cpu_wait) | 62 | if (cpu_wait) |
56 | (*cpu_wait)(); | 63 | (*cpu_wait)(); |
64 | } | ||
57 | preempt_enable_no_resched(); | 65 | preempt_enable_no_resched(); |
58 | schedule(); | 66 | schedule(); |
59 | preempt_disable(); | 67 | preempt_disable(); |
@@ -177,6 +185,17 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | |||
177 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); | 185 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); |
178 | clear_tsk_thread_flag(p, TIF_USEDFPU); | 186 | clear_tsk_thread_flag(p, TIF_USEDFPU); |
179 | 187 | ||
188 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
189 | /* | ||
190 | * FPU affinity support is cleaner if we track the | ||
191 | * user-visible CPU affinity from the very beginning. | ||
192 | * The generic cpus_allowed mask will already have | ||
193 | * been copied from the parent before copy_thread | ||
194 | * is invoked. | ||
195 | */ | ||
196 | p->thread.user_cpus_allowed = p->cpus_allowed; | ||
197 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
198 | |||
180 | if (clone_flags & CLONE_SETTLS) | 199 | if (clone_flags & CLONE_SETTLS) |
181 | ti->tp_value = regs->regs[7]; | 200 | ti->tp_value = regs->regs[7]; |
182 | 201 | ||
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index f838b36cc765..f3106d0771b0 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -248,10 +248,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
248 | break; | 248 | break; |
249 | case FPC_EIR: { /* implementation / version register */ | 249 | case FPC_EIR: { /* implementation / version register */ |
250 | unsigned int flags; | 250 | unsigned int flags; |
251 | #ifdef CONFIG_MIPS_MT_SMTC | ||
252 | unsigned int irqflags; | ||
253 | unsigned int mtflags; | ||
254 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
251 | 255 | ||
252 | if (!cpu_has_fpu) | 256 | if (!cpu_has_fpu) |
253 | break; | 257 | break; |
254 | 258 | ||
259 | #ifdef CONFIG_MIPS_MT_SMTC | ||
260 | /* Read-modify-write of Status must be atomic */ | ||
261 | local_irq_save(irqflags); | ||
262 | mtflags = dmt(); | ||
263 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
264 | |||
255 | preempt_disable(); | 265 | preempt_disable(); |
256 | if (cpu_has_mipsmt) { | 266 | if (cpu_has_mipsmt) { |
257 | unsigned int vpflags = dvpe(); | 267 | unsigned int vpflags = dvpe(); |
@@ -266,6 +276,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
266 | __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); | 276 | __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); |
267 | write_c0_status(flags); | 277 | write_c0_status(flags); |
268 | } | 278 | } |
279 | #ifdef CONFIG_MIPS_MT_SMTC | ||
280 | emt(mtflags); | ||
281 | local_irq_restore(irqflags); | ||
282 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
269 | preempt_enable(); | 283 | preempt_enable(); |
270 | break; | 284 | break; |
271 | } | 285 | } |
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index 0d5cf97af727..8704dc0496ea 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c | |||
@@ -173,12 +173,22 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
173 | break; | 173 | break; |
174 | case FPC_EIR: { /* implementation / version register */ | 174 | case FPC_EIR: { /* implementation / version register */ |
175 | unsigned int flags; | 175 | unsigned int flags; |
176 | #ifdef CONFIG_MIPS_MT_SMTC | ||
177 | unsigned int irqflags; | ||
178 | unsigned int mtflags; | ||
179 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
176 | 180 | ||
177 | if (!cpu_has_fpu) { | 181 | if (!cpu_has_fpu) { |
178 | tmp = 0; | 182 | tmp = 0; |
179 | break; | 183 | break; |
180 | } | 184 | } |
181 | 185 | ||
186 | #ifdef CONFIG_MIPS_MT_SMTC | ||
187 | /* Read-modify-write of Status must be atomic */ | ||
188 | local_irq_save(irqflags); | ||
189 | mtflags = dmt(); | ||
190 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
191 | |||
182 | preempt_disable(); | 192 | preempt_disable(); |
183 | if (cpu_has_mipsmt) { | 193 | if (cpu_has_mipsmt) { |
184 | unsigned int vpflags = dvpe(); | 194 | unsigned int vpflags = dvpe(); |
@@ -193,6 +203,10 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
193 | __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); | 203 | __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); |
194 | write_c0_status(flags); | 204 | write_c0_status(flags); |
195 | } | 205 | } |
206 | #ifdef CONFIG_MIPS_MT_SMTC | ||
207 | emt(mtflags); | ||
208 | local_irq_restore(irqflags); | ||
209 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
196 | preempt_enable(); | 210 | preempt_enable(); |
197 | break; | 211 | break; |
198 | } | 212 | } |
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index d2afbd19a9c8..0b1b54acee9f 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S | |||
@@ -88,7 +88,18 @@ | |||
88 | 88 | ||
89 | PTR_ADDIU t0, $28, _THREAD_SIZE - 32 | 89 | PTR_ADDIU t0, $28, _THREAD_SIZE - 32 |
90 | set_saved_sp t0, t1, t2 | 90 | set_saved_sp t0, t1, t2 |
91 | 91 | #ifdef CONFIG_MIPS_MT_SMTC | |
92 | /* Read-modify-writes of Status must be atomic on a VPE */ | ||
93 | mfc0 t2, CP0_TCSTATUS | ||
94 | ori t1, t2, TCSTATUS_IXMT | ||
95 | mtc0 t1, CP0_TCSTATUS | ||
96 | andi t2, t2, TCSTATUS_IXMT | ||
97 | ehb | ||
98 | DMT 8 # dmt t0 | ||
99 | move t1,ra | ||
100 | jal mips_ihb | ||
101 | move ra,t1 | ||
102 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
92 | mfc0 t1, CP0_STATUS /* Do we really need this? */ | 103 | mfc0 t1, CP0_STATUS /* Do we really need this? */ |
93 | li a3, 0xff01 | 104 | li a3, 0xff01 |
94 | and t1, a3 | 105 | and t1, a3 |
@@ -97,6 +108,18 @@ | |||
97 | and a2, a3 | 108 | and a2, a3 |
98 | or a2, t1 | 109 | or a2, t1 |
99 | mtc0 a2, CP0_STATUS | 110 | mtc0 a2, CP0_STATUS |
111 | #ifdef CONFIG_MIPS_MT_SMTC | ||
112 | ehb | ||
113 | andi t0, t0, VPECONTROL_TE | ||
114 | beqz t0, 1f | ||
115 | emt | ||
116 | 1: | ||
117 | mfc0 t1, CP0_TCSTATUS | ||
118 | xori t1, t1, TCSTATUS_IXMT | ||
119 | or t1, t1, t2 | ||
120 | mtc0 t1, CP0_TCSTATUS | ||
121 | ehb | ||
122 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
100 | move v0, a0 | 123 | move v0, a0 |
101 | jr ra | 124 | jr ra |
102 | END(resume) | 125 | END(resume) |
@@ -131,10 +154,19 @@ LEAF(_restore_fp) | |||
131 | #define FPU_DEFAULT 0x00000000 | 154 | #define FPU_DEFAULT 0x00000000 |
132 | 155 | ||
133 | LEAF(_init_fpu) | 156 | LEAF(_init_fpu) |
157 | #ifdef CONFIG_MIPS_MT_SMTC | ||
158 | /* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */ | ||
159 | mfc0 t0, CP0_TCSTATUS | ||
160 | /* Bit position is the same for Status, TCStatus */ | ||
161 | li t1, ST0_CU1 | ||
162 | or t0, t1 | ||
163 | mtc0 t0, CP0_TCSTATUS | ||
164 | #else /* Normal MIPS CU1 enable */ | ||
134 | mfc0 t0, CP0_STATUS | 165 | mfc0 t0, CP0_STATUS |
135 | li t1, ST0_CU1 | 166 | li t1, ST0_CU1 |
136 | or t0, t1 | 167 | or t0, t1 |
137 | mtc0 t0, CP0_STATUS | 168 | mtc0 t0, CP0_STATUS |
169 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
138 | fpu_enable_hazard | 170 | fpu_enable_hazard |
139 | 171 | ||
140 | li t1, FPU_DEFAULT | 172 | li t1, FPU_DEFAULT |
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 986a9cf23067..6179805af9f0 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c | |||
@@ -21,45 +21,44 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <asm/uaccess.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/list.h> | ||
27 | #include <linux/vmalloc.h> | ||
28 | #include <linux/elf.h> | ||
29 | #include <linux/seq_file.h> | ||
30 | #include <linux/syscalls.h> | ||
31 | #include <linux/moduleloader.h> | ||
24 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
25 | #include <linux/irq.h> | ||
26 | #include <linux/poll.h> | 33 | #include <linux/poll.h> |
27 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
28 | #include <linux/wait.h> | 35 | #include <linux/wait.h> |
29 | |||
30 | #include <asm/mipsmtregs.h> | 36 | #include <asm/mipsmtregs.h> |
31 | #include <asm/bitops.h> | 37 | #include <asm/cacheflush.h> |
38 | #include <asm/atomic.h> | ||
32 | #include <asm/cpu.h> | 39 | #include <asm/cpu.h> |
33 | #include <asm/processor.h> | 40 | #include <asm/processor.h> |
41 | #include <asm/system.h> | ||
42 | #include <asm/vpe.h> | ||
34 | #include <asm/rtlx.h> | 43 | #include <asm/rtlx.h> |
35 | #include <asm/uaccess.h> | ||
36 | 44 | ||
37 | #define RTLX_TARG_VPE 1 | 45 | #define RTLX_TARG_VPE 1 |
38 | 46 | ||
39 | static struct rtlx_info *rtlx; | 47 | static struct rtlx_info *rtlx; |
40 | static int major; | 48 | static int major; |
41 | static char module_name[] = "rtlx"; | 49 | static char module_name[] = "rtlx"; |
42 | static struct irqaction irq; | ||
43 | static int irq_num; | ||
44 | |||
45 | static inline int spacefree(int read, int write, int size) | ||
46 | { | ||
47 | if (read == write) { | ||
48 | /* | ||
49 | * never fill the buffer completely, so indexes are always | ||
50 | * equal if empty and only empty, or !equal if data available | ||
51 | */ | ||
52 | return size - 1; | ||
53 | } | ||
54 | |||
55 | return ((read + size - write) % size) - 1; | ||
56 | } | ||
57 | 50 | ||
58 | static struct chan_waitqueues { | 51 | static struct chan_waitqueues { |
59 | wait_queue_head_t rt_queue; | 52 | wait_queue_head_t rt_queue; |
60 | wait_queue_head_t lx_queue; | 53 | wait_queue_head_t lx_queue; |
54 | int in_open; | ||
61 | } channel_wqs[RTLX_CHANNELS]; | 55 | } channel_wqs[RTLX_CHANNELS]; |
62 | 56 | ||
57 | static struct irqaction irq; | ||
58 | static int irq_num; | ||
59 | static struct vpe_notifications notify; | ||
60 | static int sp_stopping = 0; | ||
61 | |||
63 | extern void *vpe_get_shared(int index); | 62 | extern void *vpe_get_shared(int index); |
64 | 63 | ||
65 | static void rtlx_dispatch(struct pt_regs *regs) | 64 | static void rtlx_dispatch(struct pt_regs *regs) |
@@ -67,174 +66,298 @@ static void rtlx_dispatch(struct pt_regs *regs) | |||
67 | do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs); | 66 | do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs); |
68 | } | 67 | } |
69 | 68 | ||
69 | |||
70 | /* Interrupt handler may be called before rtlx_init has otherwise had | ||
71 | a chance to run. | ||
72 | */ | ||
70 | static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 73 | static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
71 | { | 74 | { |
72 | int i; | 75 | int i; |
73 | 76 | ||
74 | for (i = 0; i < RTLX_CHANNELS; i++) { | 77 | for (i = 0; i < RTLX_CHANNELS; i++) { |
75 | struct rtlx_channel *chan = &rtlx->channel[i]; | 78 | wake_up(&channel_wqs[i].lx_queue); |
76 | 79 | wake_up(&channel_wqs[i].rt_queue); | |
77 | if (chan->lx_read != chan->lx_write) | ||
78 | wake_up_interruptible(&channel_wqs[i].lx_queue); | ||
79 | } | 80 | } |
80 | 81 | ||
81 | return IRQ_HANDLED; | 82 | return IRQ_HANDLED; |
82 | } | 83 | } |
83 | 84 | ||
84 | /* call when we have the address of the shared structure from the SP side. */ | 85 | static __attribute_used__ void dump_rtlx(void) |
85 | static int rtlx_init(struct rtlx_info *rtlxi) | ||
86 | { | 86 | { |
87 | int i; | 87 | int i; |
88 | 88 | ||
89 | if (rtlxi->id != RTLX_ID) { | 89 | printk("id 0x%lx state %d\n", rtlx->id, rtlx->state); |
90 | printk(KERN_WARNING "no valid RTLX id at 0x%p\n", rtlxi); | ||
91 | return -ENOEXEC; | ||
92 | } | ||
93 | 90 | ||
94 | /* initialise the wait queues */ | ||
95 | for (i = 0; i < RTLX_CHANNELS; i++) { | 91 | for (i = 0; i < RTLX_CHANNELS; i++) { |
96 | init_waitqueue_head(&channel_wqs[i].rt_queue); | 92 | struct rtlx_channel *chan = &rtlx->channel[i]; |
97 | init_waitqueue_head(&channel_wqs[i].lx_queue); | ||
98 | } | ||
99 | 93 | ||
100 | /* set up for interrupt handling */ | 94 | printk(" rt_state %d lx_state %d buffer_size %d\n", |
101 | memset(&irq, 0, sizeof(struct irqaction)); | 95 | chan->rt_state, chan->lx_state, chan->buffer_size); |
102 | 96 | ||
103 | if (cpu_has_vint) | 97 | printk(" rt_read %d rt_write %d\n", |
104 | set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); | 98 | chan->rt_read, chan->rt_write); |
105 | 99 | ||
106 | irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ; | 100 | printk(" lx_read %d lx_write %d\n", |
107 | irq.handler = rtlx_interrupt; | 101 | chan->lx_read, chan->lx_write); |
108 | irq.flags = SA_INTERRUPT; | 102 | |
109 | irq.name = "RTLX"; | 103 | printk(" rt_buffer <%s>\n", chan->rt_buffer); |
110 | irq.dev_id = rtlx; | 104 | printk(" lx_buffer <%s>\n", chan->lx_buffer); |
111 | setup_irq(irq_num, &irq); | 105 | } |
106 | } | ||
107 | |||
108 | /* call when we have the address of the shared structure from the SP side. */ | ||
109 | static int rtlx_init(struct rtlx_info *rtlxi) | ||
110 | { | ||
111 | if (rtlxi->id != RTLX_ID) { | ||
112 | printk(KERN_ERR "no valid RTLX id at 0x%p 0x%x\n", rtlxi, rtlxi->id); | ||
113 | return -ENOEXEC; | ||
114 | } | ||
112 | 115 | ||
113 | rtlx = rtlxi; | 116 | rtlx = rtlxi; |
114 | 117 | ||
115 | return 0; | 118 | return 0; |
116 | } | 119 | } |
117 | 120 | ||
118 | /* only allow one open process at a time to open each channel */ | 121 | /* notifications */ |
119 | static int rtlx_open(struct inode *inode, struct file *filp) | 122 | static void starting(int vpe) |
120 | { | 123 | { |
121 | int minor, ret; | 124 | int i; |
125 | sp_stopping = 0; | ||
126 | |||
127 | /* force a reload of rtlx */ | ||
128 | rtlx=NULL; | ||
129 | |||
130 | /* wake up any sleeping rtlx_open's */ | ||
131 | for (i = 0; i < RTLX_CHANNELS; i++) | ||
132 | wake_up_interruptible(&channel_wqs[i].lx_queue); | ||
133 | } | ||
134 | |||
135 | static void stopping(int vpe) | ||
136 | { | ||
137 | int i; | ||
138 | |||
139 | sp_stopping = 1; | ||
140 | for (i = 0; i < RTLX_CHANNELS; i++) | ||
141 | wake_up_interruptible(&channel_wqs[i].lx_queue); | ||
142 | } | ||
143 | |||
144 | |||
145 | int rtlx_open(int index, int can_sleep) | ||
146 | { | ||
147 | int ret; | ||
122 | struct rtlx_channel *chan; | 148 | struct rtlx_channel *chan; |
149 | volatile struct rtlx_info **p; | ||
123 | 150 | ||
124 | /* assume only 1 device at the mo. */ | 151 | if (index >= RTLX_CHANNELS) { |
125 | minor = MINOR(inode->i_rdev); | 152 | printk(KERN_DEBUG "rtlx_open index out of range\n"); |
153 | return -ENOSYS; | ||
154 | } | ||
155 | |||
156 | if (channel_wqs[index].in_open) { | ||
157 | printk(KERN_DEBUG "rtlx_open channel %d already opened\n", index); | ||
158 | return -EBUSY; | ||
159 | } | ||
160 | |||
161 | channel_wqs[index].in_open++; | ||
126 | 162 | ||
127 | if (rtlx == NULL) { | 163 | if (rtlx == NULL) { |
128 | struct rtlx_info **p; | ||
129 | if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) { | 164 | if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) { |
130 | printk(KERN_ERR "vpe_get_shared is NULL. " | 165 | if (can_sleep) { |
131 | "Has an SP program been loaded?\n"); | 166 | DECLARE_WAITQUEUE(wait, current); |
132 | return -EFAULT; | 167 | |
168 | /* go to sleep */ | ||
169 | add_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
170 | |||
171 | set_current_state(TASK_INTERRUPTIBLE); | ||
172 | while ((p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) { | ||
173 | schedule(); | ||
174 | set_current_state(TASK_INTERRUPTIBLE); | ||
175 | } | ||
176 | |||
177 | set_current_state(TASK_RUNNING); | ||
178 | remove_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
179 | |||
180 | /* back running */ | ||
181 | } else { | ||
182 | printk( KERN_DEBUG "No SP program loaded, and device " | ||
183 | "opened with O_NONBLOCK\n"); | ||
184 | channel_wqs[index].in_open = 0; | ||
185 | return -ENOSYS; | ||
186 | } | ||
133 | } | 187 | } |
134 | 188 | ||
135 | if (*p == NULL) { | 189 | if (*p == NULL) { |
136 | printk(KERN_ERR "vpe_shared %p %p\n", p, *p); | 190 | if (can_sleep) { |
137 | return -EFAULT; | 191 | DECLARE_WAITQUEUE(wait, current); |
192 | |||
193 | /* go to sleep */ | ||
194 | add_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
195 | |||
196 | set_current_state(TASK_INTERRUPTIBLE); | ||
197 | while (*p == NULL) { | ||
198 | schedule(); | ||
199 | |||
200 | /* reset task state to interruptable otherwise | ||
201 | we'll whizz round here like a very fast loopy | ||
202 | thing. schedule() appears to return with state | ||
203 | set to TASK_RUNNING. | ||
204 | |||
205 | If the loaded SP program, for whatever reason, | ||
206 | doesn't set up the shared structure *p will never | ||
207 | become true. So whoever connected to either /dev/rt? | ||
208 | or if it was kspd, will then take up rather a lot of | ||
209 | processor cycles. | ||
210 | */ | ||
211 | |||
212 | set_current_state(TASK_INTERRUPTIBLE); | ||
213 | } | ||
214 | |||
215 | set_current_state(TASK_RUNNING); | ||
216 | remove_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
217 | |||
218 | /* back running */ | ||
219 | } | ||
220 | else { | ||
221 | printk(" *vpe_get_shared is NULL. " | ||
222 | "Has an SP program been loaded?\n"); | ||
223 | channel_wqs[index].in_open = 0; | ||
224 | return -ENOSYS; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | if ((unsigned int)*p < KSEG0) { | ||
229 | printk(KERN_WARNING "vpe_get_shared returned an invalid pointer " | ||
230 | "maybe an error code %d\n", (int)*p); | ||
231 | channel_wqs[index].in_open = 0; | ||
232 | return -ENOSYS; | ||
138 | } | 233 | } |
139 | 234 | ||
140 | if ((ret = rtlx_init(*p)) < 0) | 235 | if ((ret = rtlx_init(*p)) < 0) { |
141 | return ret; | 236 | channel_wqs[index].in_open = 0; |
237 | return ret; | ||
238 | } | ||
142 | } | 239 | } |
143 | 240 | ||
144 | chan = &rtlx->channel[minor]; | 241 | chan = &rtlx->channel[index]; |
145 | 242 | ||
146 | if (test_and_set_bit(RTLX_STATE_OPENED, &chan->lx_state)) | 243 | if (chan->lx_state == RTLX_STATE_OPENED) { |
147 | return -EBUSY; | 244 | channel_wqs[index].in_open = 0; |
245 | return -EBUSY; | ||
246 | } | ||
148 | 247 | ||
248 | chan->lx_state = RTLX_STATE_OPENED; | ||
249 | channel_wqs[index].in_open = 0; | ||
149 | return 0; | 250 | return 0; |
150 | } | 251 | } |
151 | 252 | ||
152 | static int rtlx_release(struct inode *inode, struct file *filp) | 253 | int rtlx_release(int index) |
153 | { | 254 | { |
154 | int minor = MINOR(inode->i_rdev); | 255 | rtlx->channel[index].lx_state = RTLX_STATE_UNUSED; |
155 | |||
156 | clear_bit(RTLX_STATE_OPENED, &rtlx->channel[minor].lx_state); | ||
157 | smp_mb__after_clear_bit(); | ||
158 | |||
159 | return 0; | 256 | return 0; |
160 | } | 257 | } |
161 | 258 | ||
162 | static unsigned int rtlx_poll(struct file *file, poll_table * wait) | 259 | unsigned int rtlx_read_poll(int index, int can_sleep) |
163 | { | 260 | { |
164 | int minor; | 261 | struct rtlx_channel *chan; |
165 | unsigned int mask = 0; | ||
166 | struct rtlx_channel *chan; | ||
167 | 262 | ||
168 | minor = MINOR(file->f_dentry->d_inode->i_rdev); | 263 | if (rtlx == NULL) |
169 | chan = &rtlx->channel[minor]; | 264 | return 0; |
170 | 265 | ||
171 | poll_wait(file, &channel_wqs[minor].rt_queue, wait); | 266 | chan = &rtlx->channel[index]; |
172 | poll_wait(file, &channel_wqs[minor].lx_queue, wait); | ||
173 | 267 | ||
174 | /* data available to read? */ | 268 | /* data available to read? */ |
175 | if (chan->lx_read != chan->lx_write) | 269 | if (chan->lx_read == chan->lx_write) { |
176 | mask |= POLLIN | POLLRDNORM; | 270 | if (can_sleep) { |
271 | DECLARE_WAITQUEUE(wait, current); | ||
177 | 272 | ||
178 | /* space to write */ | 273 | /* go to sleep */ |
179 | if (spacefree(chan->rt_read, chan->rt_write, chan->buffer_size)) | 274 | add_wait_queue(&channel_wqs[index].lx_queue, &wait); |
180 | mask |= POLLOUT | POLLWRNORM; | ||
181 | 275 | ||
182 | return mask; | 276 | set_current_state(TASK_INTERRUPTIBLE); |
277 | while (chan->lx_read == chan->lx_write) { | ||
278 | schedule(); | ||
279 | |||
280 | set_current_state(TASK_INTERRUPTIBLE); | ||
281 | |||
282 | if (sp_stopping) { | ||
283 | set_current_state(TASK_RUNNING); | ||
284 | remove_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
285 | return 0; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | set_current_state(TASK_RUNNING); | ||
290 | remove_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
291 | |||
292 | /* back running */ | ||
293 | } | ||
294 | else | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | return (chan->lx_write + chan->buffer_size - chan->lx_read) | ||
299 | % chan->buffer_size; | ||
183 | } | 300 | } |
184 | 301 | ||
185 | static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count, | 302 | static inline int write_spacefree(int read, int write, int size) |
186 | loff_t * ppos) | ||
187 | { | 303 | { |
188 | unsigned long failed; | 304 | if (read == write) { |
189 | size_t fl = 0L; | 305 | /* |
190 | int minor; | 306 | * Never fill the buffer completely, so indexes are always |
191 | struct rtlx_channel *lx; | 307 | * equal if empty and only empty, or !equal if data available |
192 | DECLARE_WAITQUEUE(wait, current); | 308 | */ |
309 | return size - 1; | ||
310 | } | ||
193 | 311 | ||
194 | minor = MINOR(file->f_dentry->d_inode->i_rdev); | 312 | return ((read + size - write) % size) - 1; |
195 | lx = &rtlx->channel[minor]; | 313 | } |
196 | 314 | ||
197 | /* data available? */ | 315 | unsigned int rtlx_write_poll(int index) |
198 | if (lx->lx_write == lx->lx_read) { | 316 | { |
199 | if (file->f_flags & O_NONBLOCK) | 317 | struct rtlx_channel *chan = &rtlx->channel[index]; |
200 | return 0; /* -EAGAIN makes cat whinge */ | 318 | return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); |
319 | } | ||
201 | 320 | ||
202 | /* go to sleep */ | 321 | static inline void copy_to(void *dst, void *src, size_t count, int user) |
203 | add_wait_queue(&channel_wqs[minor].lx_queue, &wait); | 322 | { |
204 | set_current_state(TASK_INTERRUPTIBLE); | 323 | if (user) |
324 | copy_to_user(dst, src, count); | ||
325 | else | ||
326 | memcpy(dst, src, count); | ||
327 | } | ||
205 | 328 | ||
206 | while (lx->lx_write == lx->lx_read) | 329 | static inline void copy_from(void *dst, void *src, size_t count, int user) |
207 | schedule(); | 330 | { |
331 | if (user) | ||
332 | copy_from_user(dst, src, count); | ||
333 | else | ||
334 | memcpy(dst, src, count); | ||
335 | } | ||
208 | 336 | ||
209 | set_current_state(TASK_RUNNING); | 337 | ssize_t rtlx_read(int index, void *buff, size_t count, int user) |
210 | remove_wait_queue(&channel_wqs[minor].lx_queue, &wait); | 338 | { |
339 | size_t fl = 0L; | ||
340 | struct rtlx_channel *lx; | ||
211 | 341 | ||
212 | /* back running */ | 342 | if (rtlx == NULL) |
213 | } | 343 | return -ENOSYS; |
344 | |||
345 | lx = &rtlx->channel[index]; | ||
214 | 346 | ||
215 | /* find out how much in total */ | 347 | /* find out how much in total */ |
216 | count = min(count, | 348 | count = min(count, |
217 | (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size); | 349 | (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) |
350 | % lx->buffer_size); | ||
218 | 351 | ||
219 | /* then how much from the read pointer onwards */ | 352 | /* then how much from the read pointer onwards */ |
220 | fl = min(count, (size_t)lx->buffer_size - lx->lx_read); | 353 | fl = min( count, (size_t)lx->buffer_size - lx->lx_read); |
221 | 354 | ||
222 | failed = copy_to_user (buffer, &lx->lx_buffer[lx->lx_read], fl); | 355 | copy_to(buff, &lx->lx_buffer[lx->lx_read], fl, user); |
223 | if (failed) { | ||
224 | count = fl - failed; | ||
225 | goto out; | ||
226 | } | ||
227 | 356 | ||
228 | /* and if there is anything left at the beginning of the buffer */ | 357 | /* and if there is anything left at the beginning of the buffer */ |
229 | if (count - fl) { | 358 | if ( count - fl ) |
230 | failed = copy_to_user (buffer + fl, lx->lx_buffer, count - fl); | 359 | copy_to (buff + fl, lx->lx_buffer, count - fl, user); |
231 | if (failed) { | ||
232 | count -= failed; | ||
233 | goto out; | ||
234 | } | ||
235 | } | ||
236 | 360 | ||
237 | out: | ||
238 | /* update the index */ | 361 | /* update the index */ |
239 | lx->lx_read += count; | 362 | lx->lx_read += count; |
240 | lx->lx_read %= lx->buffer_size; | 363 | lx->lx_read %= lx->buffer_size; |
@@ -242,20 +365,101 @@ out: | |||
242 | return count; | 365 | return count; |
243 | } | 366 | } |
244 | 367 | ||
245 | static ssize_t rtlx_write(struct file *file, const char __user * buffer, | 368 | ssize_t rtlx_write(int index, void *buffer, size_t count, int user) |
369 | { | ||
370 | struct rtlx_channel *rt; | ||
371 | size_t fl; | ||
372 | |||
373 | if (rtlx == NULL) | ||
374 | return(-ENOSYS); | ||
375 | |||
376 | rt = &rtlx->channel[index]; | ||
377 | |||
378 | /* total number of bytes to copy */ | ||
379 | count = min(count, | ||
380 | (size_t)write_spacefree(rt->rt_read, rt->rt_write, | ||
381 | rt->buffer_size)); | ||
382 | |||
383 | /* first bit from write pointer to the end of the buffer, or count */ | ||
384 | fl = min(count, (size_t) rt->buffer_size - rt->rt_write); | ||
385 | |||
386 | copy_from (&rt->rt_buffer[rt->rt_write], buffer, fl, user); | ||
387 | |||
388 | /* if there's any left copy to the beginning of the buffer */ | ||
389 | if( count - fl ) | ||
390 | copy_from (rt->rt_buffer, buffer + fl, count - fl, user); | ||
391 | |||
392 | rt->rt_write += count; | ||
393 | rt->rt_write %= rt->buffer_size; | ||
394 | |||
395 | return(count); | ||
396 | } | ||
397 | |||
398 | |||
399 | static int file_open(struct inode *inode, struct file *filp) | ||
400 | { | ||
401 | int minor = MINOR(inode->i_rdev); | ||
402 | |||
403 | return rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1); | ||
404 | } | ||
405 | |||
406 | static int file_release(struct inode *inode, struct file *filp) | ||
407 | { | ||
408 | int minor; | ||
409 | minor = MINOR(inode->i_rdev); | ||
410 | |||
411 | return rtlx_release(minor); | ||
412 | } | ||
413 | |||
414 | static unsigned int file_poll(struct file *file, poll_table * wait) | ||
415 | { | ||
416 | int minor; | ||
417 | unsigned int mask = 0; | ||
418 | |||
419 | minor = MINOR(file->f_dentry->d_inode->i_rdev); | ||
420 | |||
421 | poll_wait(file, &channel_wqs[minor].rt_queue, wait); | ||
422 | poll_wait(file, &channel_wqs[minor].lx_queue, wait); | ||
423 | |||
424 | if (rtlx == NULL) | ||
425 | return 0; | ||
426 | |||
427 | /* data available to read? */ | ||
428 | if (rtlx_read_poll(minor, 0)) | ||
429 | mask |= POLLIN | POLLRDNORM; | ||
430 | |||
431 | /* space to write */ | ||
432 | if (rtlx_write_poll(minor)) | ||
433 | mask |= POLLOUT | POLLWRNORM; | ||
434 | |||
435 | return mask; | ||
436 | } | ||
437 | |||
438 | static ssize_t file_read(struct file *file, char __user * buffer, size_t count, | ||
439 | loff_t * ppos) | ||
440 | { | ||
441 | int minor = MINOR(file->f_dentry->d_inode->i_rdev); | ||
442 | |||
443 | /* data available? */ | ||
444 | if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) { | ||
445 | return 0; // -EAGAIN makes cat whinge | ||
446 | } | ||
447 | |||
448 | return rtlx_read(minor, buffer, count, 1); | ||
449 | } | ||
450 | |||
451 | static ssize_t file_write(struct file *file, const char __user * buffer, | ||
246 | size_t count, loff_t * ppos) | 452 | size_t count, loff_t * ppos) |
247 | { | 453 | { |
248 | unsigned long failed; | ||
249 | int minor; | 454 | int minor; |
250 | struct rtlx_channel *rt; | 455 | struct rtlx_channel *rt; |
251 | size_t fl; | ||
252 | DECLARE_WAITQUEUE(wait, current); | 456 | DECLARE_WAITQUEUE(wait, current); |
253 | 457 | ||
254 | minor = MINOR(file->f_dentry->d_inode->i_rdev); | 458 | minor = MINOR(file->f_dentry->d_inode->i_rdev); |
255 | rt = &rtlx->channel[minor]; | 459 | rt = &rtlx->channel[minor]; |
256 | 460 | ||
257 | /* any space left... */ | 461 | /* any space left... */ |
258 | if (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) { | 462 | if (!rtlx_write_poll(minor)) { |
259 | 463 | ||
260 | if (file->f_flags & O_NONBLOCK) | 464 | if (file->f_flags & O_NONBLOCK) |
261 | return -EAGAIN; | 465 | return -EAGAIN; |
@@ -263,61 +467,64 @@ static ssize_t rtlx_write(struct file *file, const char __user * buffer, | |||
263 | add_wait_queue(&channel_wqs[minor].rt_queue, &wait); | 467 | add_wait_queue(&channel_wqs[minor].rt_queue, &wait); |
264 | set_current_state(TASK_INTERRUPTIBLE); | 468 | set_current_state(TASK_INTERRUPTIBLE); |
265 | 469 | ||
266 | while (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) | 470 | while (!rtlx_write_poll(minor)) |
267 | schedule(); | 471 | schedule(); |
268 | 472 | ||
269 | set_current_state(TASK_RUNNING); | 473 | set_current_state(TASK_RUNNING); |
270 | remove_wait_queue(&channel_wqs[minor].rt_queue, &wait); | 474 | remove_wait_queue(&channel_wqs[minor].rt_queue, &wait); |
271 | } | 475 | } |
272 | 476 | ||
273 | /* total number of bytes to copy */ | 477 | return rtlx_write(minor, (void *)buffer, count, 1); |
274 | count = min(count, (size_t)spacefree(rt->rt_read, rt->rt_write, rt->buffer_size) ); | ||
275 | |||
276 | /* first bit from write pointer to the end of the buffer, or count */ | ||
277 | fl = min(count, (size_t) rt->buffer_size - rt->rt_write); | ||
278 | |||
279 | failed = copy_from_user(&rt->rt_buffer[rt->rt_write], buffer, fl); | ||
280 | if (failed) { | ||
281 | count = fl - failed; | ||
282 | goto out; | ||
283 | } | ||
284 | |||
285 | /* if there's any left copy to the beginning of the buffer */ | ||
286 | if (count - fl) { | ||
287 | failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl); | ||
288 | if (failed) { | ||
289 | count -= failed; | ||
290 | goto out; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | out: | ||
295 | rt->rt_write += count; | ||
296 | rt->rt_write %= rt->buffer_size; | ||
297 | |||
298 | return count; | ||
299 | } | 478 | } |
300 | 479 | ||
301 | static struct file_operations rtlx_fops = { | 480 | static struct file_operations rtlx_fops = { |
302 | .owner = THIS_MODULE, | 481 | .owner = THIS_MODULE, |
303 | .open = rtlx_open, | 482 | .open = file_open, |
304 | .release = rtlx_release, | 483 | .release = file_release, |
305 | .write = rtlx_write, | 484 | .write = file_write, |
306 | .read = rtlx_read, | 485 | .read = file_read, |
307 | .poll = rtlx_poll | 486 | .poll = file_poll |
308 | }; | 487 | }; |
309 | 488 | ||
489 | static struct irqaction rtlx_irq = { | ||
490 | .handler = rtlx_interrupt, | ||
491 | .flags = SA_INTERRUPT, | ||
492 | .name = "RTLX", | ||
493 | }; | ||
494 | |||
495 | static int rtlx_irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ; | ||
496 | |||
310 | static char register_chrdev_failed[] __initdata = | 497 | static char register_chrdev_failed[] __initdata = |
311 | KERN_ERR "rtlx_module_init: unable to register device\n"; | 498 | KERN_ERR "rtlx_module_init: unable to register device\n"; |
312 | 499 | ||
313 | static int __init rtlx_module_init(void) | 500 | static int rtlx_module_init(void) |
314 | { | 501 | { |
502 | int i; | ||
503 | |||
315 | major = register_chrdev(0, module_name, &rtlx_fops); | 504 | major = register_chrdev(0, module_name, &rtlx_fops); |
316 | if (major < 0) { | 505 | if (major < 0) { |
317 | printk(register_chrdev_failed); | 506 | printk(register_chrdev_failed); |
318 | return major; | 507 | return major; |
319 | } | 508 | } |
320 | 509 | ||
510 | /* initialise the wait queues */ | ||
511 | for (i = 0; i < RTLX_CHANNELS; i++) { | ||
512 | init_waitqueue_head(&channel_wqs[i].rt_queue); | ||
513 | init_waitqueue_head(&channel_wqs[i].lx_queue); | ||
514 | channel_wqs[i].in_open = 0; | ||
515 | } | ||
516 | |||
517 | /* set up notifiers */ | ||
518 | notify.start = starting; | ||
519 | notify.stop = stopping; | ||
520 | vpe_notify(RTLX_TARG_VPE, ¬ify); | ||
521 | |||
522 | if (cpu_has_vint) | ||
523 | set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); | ||
524 | |||
525 | rtlx_irq.dev_id = rtlx; | ||
526 | setup_irq(rtlx_irq_num, &rtlx_irq); | ||
527 | |||
321 | return 0; | 528 | return 0; |
322 | } | 529 | } |
323 | 530 | ||
@@ -330,5 +537,5 @@ module_init(rtlx_module_init); | |||
330 | module_exit(rtlx_module_exit); | 537 | module_exit(rtlx_module_exit); |
331 | 538 | ||
332 | MODULE_DESCRIPTION("MIPS RTLX"); | 539 | MODULE_DESCRIPTION("MIPS RTLX"); |
333 | MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc."); | 540 | MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc."); |
334 | MODULE_LICENSE("GPL"); | 541 | MODULE_LICENSE("GPL"); |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 2f2dc54b2e26..a0ac0e5f61ad 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -569,8 +569,19 @@ einval: li v0, -EINVAL | |||
569 | sys sys_tkill 2 | 569 | sys sys_tkill 2 |
570 | sys sys_sendfile64 5 | 570 | sys sys_sendfile64 5 |
571 | sys sys_futex 6 | 571 | sys sys_futex 6 |
572 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
573 | /* | ||
574 | * For FPU affinity scheduling on MIPS MT processors, we need to | ||
575 | * intercept sys_sched_xxxaffinity() calls until we get a proper hook | ||
576 | * in kernel/sched.c. Considered only temporary we only support these | ||
577 | * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm. | ||
578 | */ | ||
579 | sys mipsmt_sys_sched_setaffinity 3 | ||
580 | sys mipsmt_sys_sched_getaffinity 3 | ||
581 | #else | ||
572 | sys sys_sched_setaffinity 3 | 582 | sys sys_sched_setaffinity 3 |
573 | sys sys_sched_getaffinity 3 /* 4240 */ | 583 | sys sys_sched_getaffinity 3 /* 4240 */ |
584 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
574 | sys sys_io_setup 2 | 585 | sys sys_io_setup 2 |
575 | sys sys_io_destroy 1 | 586 | sys sys_io_destroy 1 |
576 | sys sys_io_getevents 5 | 587 | sys sys_io_getevents 5 |
@@ -634,6 +645,8 @@ einval: li v0, -EINVAL | |||
634 | sys sys_pselect6 6 | 645 | sys sys_pselect6 6 |
635 | sys sys_ppoll 5 | 646 | sys sys_ppoll 5 |
636 | sys sys_unshare 1 | 647 | sys sys_unshare 1 |
648 | sys sys_splice 4 | ||
649 | sys sys_sync_file_range 7 /* 4305 */ | ||
637 | .endm | 650 | .endm |
638 | 651 | ||
639 | /* We pre-compute the number of _instruction_ bytes needed to | 652 | /* We pre-compute the number of _instruction_ bytes needed to |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 98bf25df56f3..9ba750887377 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -460,3 +460,5 @@ sys_call_table: | |||
460 | PTR sys_pselect6 /* 5260 */ | 460 | PTR sys_pselect6 /* 5260 */ |
461 | PTR sys_ppoll | 461 | PTR sys_ppoll |
462 | PTR sys_unshare | 462 | PTR sys_unshare |
463 | PTR sys_splice | ||
464 | PTR sys_sync_file_range | ||
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 05a2c0567dae..942aca26f9c4 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -386,3 +386,5 @@ EXPORT(sysn32_call_table) | |||
386 | PTR sys_pselect6 | 386 | PTR sys_pselect6 |
387 | PTR sys_ppoll /* 6265 */ | 387 | PTR sys_ppoll /* 6265 */ |
388 | PTR sys_unshare | 388 | PTR sys_unshare |
389 | PTR sys_splice | ||
390 | PTR sys_sync_file_range | ||
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 19c4ca481b02..b53a9207f530 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -508,4 +508,6 @@ sys_call_table: | |||
508 | PTR sys_pselect6 | 508 | PTR sys_pselect6 |
509 | PTR sys_ppoll | 509 | PTR sys_ppoll |
510 | PTR sys_unshare | 510 | PTR sys_unshare |
511 | PTR sys_splice | ||
512 | PTR sys32_sync_file_range /* 4305 */ | ||
511 | .size sys_call_table,.-sys_call_table | 513 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index dcbfd27071f0..bcf1b10e518f 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -529,7 +529,10 @@ void __init setup_arch(char **cmdline_p) | |||
529 | 529 | ||
530 | int __init fpu_disable(char *s) | 530 | int __init fpu_disable(char *s) |
531 | { | 531 | { |
532 | cpu_data[0].options &= ~MIPS_CPU_FPU; | 532 | int i; |
533 | |||
534 | for (i = 0; i < NR_CPUS; i++) | ||
535 | cpu_data[i].options &= ~MIPS_CPU_FPU; | ||
533 | 536 | ||
534 | return 1; | 537 | return 1; |
535 | } | 538 | } |
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp-mt.c index 993b8bf56aaf..57770902b9ae 100644 --- a/arch/mips/kernel/smp_mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
@@ -1,8 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved. | ||
3 | * | ||
4 | * Elizabeth Clarke (beth@mips.com) | ||
5 | * | ||
6 | * This program is free software; you can distribute it and/or modify it | 2 | * This program is free software; you can distribute it and/or modify it |
7 | * under the terms of the GNU General Public License (Version 2) as | 3 | * under the terms of the GNU General Public License (Version 2) as |
8 | * published by the Free Software Foundation. | 4 | * published by the Free Software Foundation. |
@@ -16,6 +12,10 @@ | |||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | 12 | * with this program; if not, write to the Free Software Foundation, Inc., |
17 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 13 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
18 | * | 14 | * |
15 | * Copyright (C) 2004, 05, 06 MIPS Technologies, Inc. | ||
16 | * Elizabeth Clarke (beth@mips.com) | ||
17 | * Ralf Baechle (ralf@linux-mips.org) | ||
18 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | ||
19 | */ | 19 | */ |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | 25 | ||
26 | #include <asm/atomic.h> | 26 | #include <asm/atomic.h> |
27 | #include <asm/cacheflush.h> | ||
27 | #include <asm/cpu.h> | 28 | #include <asm/cpu.h> |
28 | #include <asm/processor.h> | 29 | #include <asm/processor.h> |
29 | #include <asm/system.h> | 30 | #include <asm/system.h> |
@@ -33,8 +34,8 @@ | |||
33 | #include <asm/time.h> | 34 | #include <asm/time.h> |
34 | #include <asm/mipsregs.h> | 35 | #include <asm/mipsregs.h> |
35 | #include <asm/mipsmtregs.h> | 36 | #include <asm/mipsmtregs.h> |
36 | #include <asm/cacheflush.h> | 37 | #include <asm/mips_mt.h> |
37 | #include <asm/mips-boards/maltaint.h> | 38 | #include <asm/mips-boards/maltaint.h> /* This is f*cking wrong */ |
38 | 39 | ||
39 | #define MIPS_CPU_IPI_RESCHED_IRQ 0 | 40 | #define MIPS_CPU_IPI_RESCHED_IRQ 0 |
40 | #define MIPS_CPU_IPI_CALL_IRQ 1 | 41 | #define MIPS_CPU_IPI_CALL_IRQ 1 |
@@ -66,6 +67,7 @@ void __init sanitize_tlb_entries(void) | |||
66 | if (!cpu_has_mipsmt) | 67 | if (!cpu_has_mipsmt) |
67 | return; | 68 | return; |
68 | 69 | ||
70 | /* Enable VPC */ | ||
69 | set_c0_mvpcontrol(MVPCONTROL_VPC); | 71 | set_c0_mvpcontrol(MVPCONTROL_VPC); |
70 | 72 | ||
71 | back_to_back_c0_hazard(); | 73 | back_to_back_c0_hazard(); |
@@ -106,12 +108,12 @@ void __init sanitize_tlb_entries(void) | |||
106 | 108 | ||
107 | static void ipi_resched_dispatch (struct pt_regs *regs) | 109 | static void ipi_resched_dispatch (struct pt_regs *regs) |
108 | { | 110 | { |
109 | do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs); | 111 | do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ, regs); |
110 | } | 112 | } |
111 | 113 | ||
112 | static void ipi_call_dispatch (struct pt_regs *regs) | 114 | static void ipi_call_dispatch (struct pt_regs *regs) |
113 | { | 115 | { |
114 | do_IRQ(MIPS_CPU_IPI_CALL_IRQ, regs); | 116 | do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ, regs); |
115 | } | 117 | } |
116 | 118 | ||
117 | irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 119 | irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
@@ -148,6 +150,11 @@ void plat_smp_setup(void) | |||
148 | unsigned long val; | 150 | unsigned long val; |
149 | int i, num; | 151 | int i, num; |
150 | 152 | ||
153 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
154 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ | ||
155 | if (cpu_has_fpu) | ||
156 | cpu_set(0, mt_fpu_cpumask); | ||
157 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
151 | if (!cpu_has_mipsmt) | 158 | if (!cpu_has_mipsmt) |
152 | return; | 159 | return; |
153 | 160 | ||
@@ -155,6 +162,8 @@ void plat_smp_setup(void) | |||
155 | dvpe(); | 162 | dvpe(); |
156 | dmt(); | 163 | dmt(); |
157 | 164 | ||
165 | mips_mt_set_cpuoptions(); | ||
166 | |||
158 | /* Put MVPE's into 'configuration state' */ | 167 | /* Put MVPE's into 'configuration state' */ |
159 | set_c0_mvpcontrol(MVPCONTROL_VPC); | 168 | set_c0_mvpcontrol(MVPCONTROL_VPC); |
160 | 169 | ||
@@ -189,11 +198,13 @@ void plat_smp_setup(void) | |||
189 | 198 | ||
190 | if (i != 0) { | 199 | if (i != 0) { |
191 | write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); | 200 | write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); |
192 | write_vpe_c0_cause(read_vpe_c0_cause() & ~CAUSEF_IP); | ||
193 | 201 | ||
194 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ | 202 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ |
195 | write_vpe_c0_config( read_c0_config()); | 203 | write_vpe_c0_config( read_c0_config()); |
196 | 204 | ||
205 | /* make sure there are no software interrupts pending */ | ||
206 | write_vpe_c0_cause(read_vpe_c0_cause() & ~(C_SW1|C_SW0)); | ||
207 | |||
197 | /* Propagate Config7 */ | 208 | /* Propagate Config7 */ |
198 | write_vpe_c0_config7(read_c0_config7()); | 209 | write_vpe_c0_config7(read_c0_config7()); |
199 | } | 210 | } |
@@ -233,16 +244,16 @@ void plat_smp_setup(void) | |||
233 | /* We'll wait until starting the secondaries before starting MVPE */ | 244 | /* We'll wait until starting the secondaries before starting MVPE */ |
234 | 245 | ||
235 | printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); | 246 | printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); |
247 | } | ||
236 | 248 | ||
249 | void __init plat_prepare_cpus(unsigned int max_cpus) | ||
250 | { | ||
237 | /* set up ipi interrupts */ | 251 | /* set up ipi interrupts */ |
238 | if (cpu_has_vint) { | 252 | if (cpu_has_vint) { |
239 | set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); | 253 | set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); |
240 | set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); | 254 | set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); |
241 | } | 255 | } |
242 | } | ||
243 | 256 | ||
244 | void __init plat_prepare_cpus(unsigned int max_cpus) | ||
245 | { | ||
246 | cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ; | 257 | cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ; |
247 | cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ; | 258 | cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ; |
248 | 259 | ||
@@ -287,7 +298,8 @@ void prom_boot_secondary(int cpu, struct task_struct *idle) | |||
287 | /* global pointer */ | 298 | /* global pointer */ |
288 | write_tc_gpr_gp((unsigned long)gp); | 299 | write_tc_gpr_gp((unsigned long)gp); |
289 | 300 | ||
290 | flush_icache_range((unsigned long)gp, (unsigned long)(gp + 1)); | 301 | flush_icache_range((unsigned long)gp, |
302 | (unsigned long)(gp + sizeof(struct thread_info))); | ||
291 | 303 | ||
292 | /* finally out of configuration and into chaos */ | 304 | /* finally out of configuration and into chaos */ |
293 | clear_c0_mvpcontrol(MVPCONTROL_VPC); | 305 | clear_c0_mvpcontrol(MVPCONTROL_VPC); |
@@ -305,6 +317,12 @@ void prom_smp_finish(void) | |||
305 | { | 317 | { |
306 | write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); | 318 | write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); |
307 | 319 | ||
320 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
321 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ | ||
322 | if (cpu_has_fpu) | ||
323 | cpu_set(smp_processor_id(), mt_fpu_cpumask); | ||
324 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
325 | |||
308 | local_irq_enable(); | 326 | local_irq_enable(); |
309 | } | 327 | } |
310 | 328 | ||
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 78d171bfa331..d42f358754ad 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -38,6 +38,10 @@ | |||
38 | #include <asm/mmu_context.h> | 38 | #include <asm/mmu_context.h> |
39 | #include <asm/smp.h> | 39 | #include <asm/smp.h> |
40 | 40 | ||
41 | #ifdef CONFIG_MIPS_MT_SMTC | ||
42 | #include <asm/mipsmtregs.h> | ||
43 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
44 | |||
41 | cpumask_t phys_cpu_present_map; /* Bitmask of available CPUs */ | 45 | cpumask_t phys_cpu_present_map; /* Bitmask of available CPUs */ |
42 | volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ | 46 | volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ |
43 | cpumask_t cpu_online_map; /* Bitmask of currently online CPUs */ | 47 | cpumask_t cpu_online_map; /* Bitmask of currently online CPUs */ |
@@ -85,6 +89,10 @@ asmlinkage void start_secondary(void) | |||
85 | { | 89 | { |
86 | unsigned int cpu; | 90 | unsigned int cpu; |
87 | 91 | ||
92 | #ifdef CONFIG_MIPS_MT_SMTC | ||
93 | /* Only do cpu_probe for first TC of CPU */ | ||
94 | if ((read_c0_tcbind() & TCBIND_CURTC) == 0) | ||
95 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
88 | cpu_probe(); | 96 | cpu_probe(); |
89 | cpu_report(); | 97 | cpu_report(); |
90 | per_cpu_trap_init(); | 98 | per_cpu_trap_init(); |
@@ -179,11 +187,13 @@ int smp_call_function (void (*func) (void *info), void *info, int retry, | |||
179 | if (wait) | 187 | if (wait) |
180 | while (atomic_read(&data.finished) != cpus) | 188 | while (atomic_read(&data.finished) != cpus) |
181 | barrier(); | 189 | barrier(); |
190 | call_data = NULL; | ||
182 | spin_unlock(&smp_call_lock); | 191 | spin_unlock(&smp_call_lock); |
183 | 192 | ||
184 | return 0; | 193 | return 0; |
185 | } | 194 | } |
186 | 195 | ||
196 | |||
187 | void smp_call_function_interrupt(void) | 197 | void smp_call_function_interrupt(void) |
188 | { | 198 | { |
189 | void (*func) (void *info) = call_data->func; | 199 | void (*func) (void *info) = call_data->func; |
@@ -446,5 +456,3 @@ subsys_initcall(topology_init); | |||
446 | 456 | ||
447 | EXPORT_SYMBOL(flush_tlb_page); | 457 | EXPORT_SYMBOL(flush_tlb_page); |
448 | EXPORT_SYMBOL(flush_tlb_one); | 458 | EXPORT_SYMBOL(flush_tlb_one); |
449 | EXPORT_SYMBOL(cpu_data); | ||
450 | EXPORT_SYMBOL(synchronize_irq); | ||
diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S new file mode 100644 index 000000000000..c9d65196d917 --- /dev/null +++ b/arch/mips/kernel/smtc-asm.S | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * Assembly Language Functions for MIPS MT SMTC support | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set. */ | ||
7 | |||
8 | #include <asm/regdef.h> | ||
9 | #include <asm/asmmacro.h> | ||
10 | #include <asm/stackframe.h> | ||
11 | #include <asm/stackframe.h> | ||
12 | |||
13 | /* | ||
14 | * "Software Interrupt" linkage. | ||
15 | * | ||
16 | * This is invoked when an "Interrupt" is sent from one TC to another, | ||
17 | * where the TC to be interrupted is halted, has it's Restart address | ||
18 | * and Status values saved by the "remote control" thread, then modified | ||
19 | * to cause execution to begin here, in kenel mode. This code then | ||
20 | * disguises the TC state as that of an exception and transfers | ||
21 | * control to the general exception or vectored interrupt handler. | ||
22 | */ | ||
23 | .set noreorder | ||
24 | |||
25 | /* | ||
26 | The __smtc_ipi_vector would use k0 and k1 as temporaries and | ||
27 | 1) Set EXL (this is per-VPE, so this can't be done by proxy!) | ||
28 | 2) Restore the K/CU and IXMT bits to the pre "exception" state | ||
29 | (EXL means no interrupts and access to the kernel map). | ||
30 | 3) Set EPC to be the saved value of TCRestart. | ||
31 | 4) Jump to the exception handler entry point passed by the sender. | ||
32 | |||
33 | CAN WE PROVE THAT WE WON'T DO THIS IF INTS DISABLED?? | ||
34 | */ | ||
35 | |||
36 | /* | ||
37 | * Reviled and slandered vision: Set EXL and restore K/CU/IXMT | ||
38 | * state of pre-halt thread, then save everything and call | ||
39 | * thought some function pointer to imaginary_exception, which | ||
40 | * will parse a register value or memory message queue to | ||
41 | * deliver things like interprocessor interrupts. On return | ||
42 | * from that function, jump to the global ret_from_irq code | ||
43 | * to invoke the scheduler and return as appropriate. | ||
44 | */ | ||
45 | |||
46 | #define PT_PADSLOT4 (PT_R0-8) | ||
47 | #define PT_PADSLOT5 (PT_R0-4) | ||
48 | |||
49 | .text | ||
50 | .align 5 | ||
51 | FEXPORT(__smtc_ipi_vector) | ||
52 | .set noat | ||
53 | /* Disable thread scheduling to make Status update atomic */ | ||
54 | DMT 27 # dmt k1 | ||
55 | ehb | ||
56 | /* Set EXL */ | ||
57 | mfc0 k0,CP0_STATUS | ||
58 | ori k0,k0,ST0_EXL | ||
59 | mtc0 k0,CP0_STATUS | ||
60 | ehb | ||
61 | /* Thread scheduling now inhibited by EXL. Restore TE state. */ | ||
62 | andi k1,k1,VPECONTROL_TE | ||
63 | beqz k1,1f | ||
64 | emt | ||
65 | 1: | ||
66 | /* | ||
67 | * The IPI sender has put some information on the anticipated | ||
68 | * kernel stack frame. If we were in user mode, this will be | ||
69 | * built above the saved kernel SP. If we were already in the | ||
70 | * kernel, it will be built above the current CPU SP. | ||
71 | * | ||
72 | * Were we in kernel mode, as indicated by CU0? | ||
73 | */ | ||
74 | sll k1,k0,3 | ||
75 | .set noreorder | ||
76 | bltz k1,2f | ||
77 | move k1,sp | ||
78 | .set reorder | ||
79 | /* | ||
80 | * If previously in user mode, set CU0 and use kernel stack. | ||
81 | */ | ||
82 | li k1,ST0_CU0 | ||
83 | or k1,k1,k0 | ||
84 | mtc0 k1,CP0_STATUS | ||
85 | ehb | ||
86 | get_saved_sp | ||
87 | /* Interrupting TC will have pre-set values in slots in the new frame */ | ||
88 | 2: subu k1,k1,PT_SIZE | ||
89 | /* Load TCStatus Value */ | ||
90 | lw k0,PT_TCSTATUS(k1) | ||
91 | /* Write it to TCStatus to restore CU/KSU/IXMT state */ | ||
92 | mtc0 k0,$2,1 | ||
93 | ehb | ||
94 | lw k0,PT_EPC(k1) | ||
95 | mtc0 k0,CP0_EPC | ||
96 | /* Save all will redundantly recompute the SP, but use it for now */ | ||
97 | SAVE_ALL | ||
98 | CLI | ||
99 | move a0,sp | ||
100 | /* Function to be invoked passed stack pad slot 5 */ | ||
101 | lw t0,PT_PADSLOT5(sp) | ||
102 | /* Argument from sender passed in stack pad slot 4 */ | ||
103 | lw a1,PT_PADSLOT4(sp) | ||
104 | jalr t0 | ||
105 | nop | ||
106 | j ret_from_irq | ||
107 | nop | ||
108 | |||
109 | /* | ||
110 | * Called from idle loop to provoke processing of queued IPIs | ||
111 | * First IPI message in queue passed as argument. | ||
112 | */ | ||
113 | |||
114 | LEAF(self_ipi) | ||
115 | /* Before anything else, block interrupts */ | ||
116 | mfc0 t0,CP0_TCSTATUS | ||
117 | ori t1,t0,TCSTATUS_IXMT | ||
118 | mtc0 t1,CP0_TCSTATUS | ||
119 | ehb | ||
120 | /* We know we're in kernel mode, so prepare stack frame */ | ||
121 | subu t1,sp,PT_SIZE | ||
122 | sw ra,PT_EPC(t1) | ||
123 | sw a0,PT_PADSLOT4(t1) | ||
124 | la t2,ipi_decode | ||
125 | sw t2,PT_PADSLOT5(t1) | ||
126 | /* Save pre-disable value of TCStatus */ | ||
127 | sw t0,PT_TCSTATUS(t1) | ||
128 | j __smtc_ipi_vector | ||
129 | nop | ||
130 | END(self_ipi) | ||
diff --git a/arch/mips/kernel/smtc-proc.c b/arch/mips/kernel/smtc-proc.c new file mode 100644 index 000000000000..6f3709996172 --- /dev/null +++ b/arch/mips/kernel/smtc-proc.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * /proc hooks for SMTC kernel | ||
3 | * Copyright (C) 2005 Mips Technologies, Inc | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/sched.h> | ||
8 | #include <linux/cpumask.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | |||
11 | #include <asm/cpu.h> | ||
12 | #include <asm/processor.h> | ||
13 | #include <asm/atomic.h> | ||
14 | #include <asm/system.h> | ||
15 | #include <asm/hardirq.h> | ||
16 | #include <asm/mmu_context.h> | ||
17 | #include <asm/smp.h> | ||
18 | #include <asm/mipsregs.h> | ||
19 | #include <asm/cacheflush.h> | ||
20 | #include <linux/proc_fs.h> | ||
21 | |||
22 | #include <asm/smtc_proc.h> | ||
23 | |||
24 | /* | ||
25 | * /proc diagnostic and statistics hooks | ||
26 | */ | ||
27 | |||
28 | /* | ||
29 | * Statistics gathered | ||
30 | */ | ||
31 | unsigned long selfipis[NR_CPUS]; | ||
32 | |||
33 | struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS]; | ||
34 | |||
35 | static struct proc_dir_entry *smtc_stats; | ||
36 | |||
37 | atomic_t smtc_fpu_recoveries; | ||
38 | |||
39 | static int proc_read_smtc(char *page, char **start, off_t off, | ||
40 | int count, int *eof, void *data) | ||
41 | { | ||
42 | int totalen = 0; | ||
43 | int len; | ||
44 | int i; | ||
45 | extern unsigned long ebase; | ||
46 | |||
47 | len = sprintf(page, "SMTC Status Word: 0x%08x\n", smtc_status); | ||
48 | totalen += len; | ||
49 | page += len; | ||
50 | len = sprintf(page, "Config7: 0x%08x\n", read_c0_config7()); | ||
51 | totalen += len; | ||
52 | page += len; | ||
53 | len = sprintf(page, "EBASE: 0x%08lx\n", ebase); | ||
54 | totalen += len; | ||
55 | page += len; | ||
56 | len = sprintf(page, "Counter Interrupts taken per CPU (TC)\n"); | ||
57 | totalen += len; | ||
58 | page += len; | ||
59 | for (i=0; i < NR_CPUS; i++) { | ||
60 | len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].timerints); | ||
61 | totalen += len; | ||
62 | page += len; | ||
63 | } | ||
64 | len = sprintf(page, "Self-IPIs by CPU:\n"); | ||
65 | totalen += len; | ||
66 | page += len; | ||
67 | for(i = 0; i < NR_CPUS; i++) { | ||
68 | len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].selfipis); | ||
69 | totalen += len; | ||
70 | page += len; | ||
71 | } | ||
72 | len = sprintf(page, "%d Recoveries of \"stolen\" FPU\n", | ||
73 | atomic_read(&smtc_fpu_recoveries)); | ||
74 | totalen += len; | ||
75 | page += len; | ||
76 | |||
77 | return totalen; | ||
78 | } | ||
79 | |||
80 | void init_smtc_stats(void) | ||
81 | { | ||
82 | int i; | ||
83 | |||
84 | for (i=0; i<NR_CPUS; i++) { | ||
85 | smtc_cpu_stats[i].timerints = 0; | ||
86 | smtc_cpu_stats[i].selfipis = 0; | ||
87 | } | ||
88 | |||
89 | atomic_set(&smtc_fpu_recoveries, 0); | ||
90 | |||
91 | smtc_stats = create_proc_read_entry("smtc", 0444, NULL, | ||
92 | proc_read_smtc, NULL); | ||
93 | } | ||
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c new file mode 100644 index 000000000000..2e8e52c135e6 --- /dev/null +++ b/arch/mips/kernel/smtc.c | |||
@@ -0,0 +1,1322 @@ | |||
1 | /* Copyright (C) 2004 Mips Technologies, Inc */ | ||
2 | |||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/sched.h> | ||
5 | #include <linux/cpumask.h> | ||
6 | #include <linux/interrupt.h> | ||
7 | |||
8 | #include <asm/cpu.h> | ||
9 | #include <asm/processor.h> | ||
10 | #include <asm/atomic.h> | ||
11 | #include <asm/system.h> | ||
12 | #include <asm/hardirq.h> | ||
13 | #include <asm/hazards.h> | ||
14 | #include <asm/mmu_context.h> | ||
15 | #include <asm/smp.h> | ||
16 | #include <asm/mipsregs.h> | ||
17 | #include <asm/cacheflush.h> | ||
18 | #include <asm/time.h> | ||
19 | #include <asm/addrspace.h> | ||
20 | #include <asm/smtc.h> | ||
21 | #include <asm/smtc_ipi.h> | ||
22 | #include <asm/smtc_proc.h> | ||
23 | |||
24 | /* | ||
25 | * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set. | ||
26 | */ | ||
27 | |||
28 | /* | ||
29 | * MIPSCPU_INT_BASE is identically defined in both | ||
30 | * asm-mips/mips-boards/maltaint.h and asm-mips/mips-boards/simint.h, | ||
31 | * but as yet there's no properly organized include structure that | ||
32 | * will ensure that the right *int.h file will be included for a | ||
33 | * given platform build. | ||
34 | */ | ||
35 | |||
36 | #define MIPSCPU_INT_BASE 16 | ||
37 | |||
38 | #define MIPS_CPU_IPI_IRQ 1 | ||
39 | |||
40 | #define LOCK_MT_PRA() \ | ||
41 | local_irq_save(flags); \ | ||
42 | mtflags = dmt() | ||
43 | |||
44 | #define UNLOCK_MT_PRA() \ | ||
45 | emt(mtflags); \ | ||
46 | local_irq_restore(flags) | ||
47 | |||
48 | #define LOCK_CORE_PRA() \ | ||
49 | local_irq_save(flags); \ | ||
50 | mtflags = dvpe() | ||
51 | |||
52 | #define UNLOCK_CORE_PRA() \ | ||
53 | evpe(mtflags); \ | ||
54 | local_irq_restore(flags) | ||
55 | |||
56 | /* | ||
57 | * Data structures purely associated with SMTC parallelism | ||
58 | */ | ||
59 | |||
60 | |||
61 | /* | ||
62 | * Table for tracking ASIDs whose lifetime is prolonged. | ||
63 | */ | ||
64 | |||
65 | asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; | ||
66 | |||
67 | /* | ||
68 | * Clock interrupt "latch" buffers, per "CPU" | ||
69 | */ | ||
70 | |||
71 | unsigned int ipi_timer_latch[NR_CPUS]; | ||
72 | |||
73 | /* | ||
74 | * Number of InterProcessor Interupt (IPI) message buffers to allocate | ||
75 | */ | ||
76 | |||
77 | #define IPIBUF_PER_CPU 4 | ||
78 | |||
79 | struct smtc_ipi_q IPIQ[NR_CPUS]; | ||
80 | struct smtc_ipi_q freeIPIq; | ||
81 | |||
82 | |||
83 | /* Forward declarations */ | ||
84 | |||
85 | void ipi_decode(struct pt_regs *, struct smtc_ipi *); | ||
86 | void post_direct_ipi(int cpu, struct smtc_ipi *pipi); | ||
87 | void setup_cross_vpe_interrupts(void); | ||
88 | void init_smtc_stats(void); | ||
89 | |||
90 | /* Global SMTC Status */ | ||
91 | |||
92 | unsigned int smtc_status = 0; | ||
93 | |||
94 | /* Boot command line configuration overrides */ | ||
95 | |||
96 | static int vpelimit = 0; | ||
97 | static int tclimit = 0; | ||
98 | static int ipibuffers = 0; | ||
99 | static int nostlb = 0; | ||
100 | static int asidmask = 0; | ||
101 | unsigned long smtc_asid_mask = 0xff; | ||
102 | |||
103 | static int __init maxvpes(char *str) | ||
104 | { | ||
105 | get_option(&str, &vpelimit); | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | static int __init maxtcs(char *str) | ||
110 | { | ||
111 | get_option(&str, &tclimit); | ||
112 | return 1; | ||
113 | } | ||
114 | |||
115 | static int __init ipibufs(char *str) | ||
116 | { | ||
117 | get_option(&str, &ipibuffers); | ||
118 | return 1; | ||
119 | } | ||
120 | |||
121 | static int __init stlb_disable(char *s) | ||
122 | { | ||
123 | nostlb = 1; | ||
124 | return 1; | ||
125 | } | ||
126 | |||
127 | static int __init asidmask_set(char *str) | ||
128 | { | ||
129 | get_option(&str, &asidmask); | ||
130 | switch(asidmask) { | ||
131 | case 0x1: | ||
132 | case 0x3: | ||
133 | case 0x7: | ||
134 | case 0xf: | ||
135 | case 0x1f: | ||
136 | case 0x3f: | ||
137 | case 0x7f: | ||
138 | case 0xff: | ||
139 | smtc_asid_mask = (unsigned long)asidmask; | ||
140 | break; | ||
141 | default: | ||
142 | printk("ILLEGAL ASID mask 0x%x from command line\n", asidmask); | ||
143 | } | ||
144 | return 1; | ||
145 | } | ||
146 | |||
147 | __setup("maxvpes=", maxvpes); | ||
148 | __setup("maxtcs=", maxtcs); | ||
149 | __setup("ipibufs=", ipibufs); | ||
150 | __setup("nostlb", stlb_disable); | ||
151 | __setup("asidmask=", asidmask_set); | ||
152 | |||
153 | /* Enable additional debug checks before going into CPU idle loop */ | ||
154 | #define SMTC_IDLE_HOOK_DEBUG | ||
155 | |||
156 | #ifdef SMTC_IDLE_HOOK_DEBUG | ||
157 | |||
158 | static int hang_trig = 0; | ||
159 | |||
160 | static int __init hangtrig_enable(char *s) | ||
161 | { | ||
162 | hang_trig = 1; | ||
163 | return 1; | ||
164 | } | ||
165 | |||
166 | |||
167 | __setup("hangtrig", hangtrig_enable); | ||
168 | |||
169 | #define DEFAULT_BLOCKED_IPI_LIMIT 32 | ||
170 | |||
171 | static int timerq_limit = DEFAULT_BLOCKED_IPI_LIMIT; | ||
172 | |||
173 | static int __init tintq(char *str) | ||
174 | { | ||
175 | get_option(&str, &timerq_limit); | ||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | __setup("tintq=", tintq); | ||
180 | |||
181 | int imstuckcount[2][8]; | ||
182 | /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ | ||
183 | int vpemask[2][8] = {{0,1,1,0,0,0,0,1},{0,1,0,0,0,0,0,1}}; | ||
184 | int tcnoprog[NR_CPUS]; | ||
185 | static atomic_t idle_hook_initialized = {0}; | ||
186 | static int clock_hang_reported[NR_CPUS]; | ||
187 | |||
188 | #endif /* SMTC_IDLE_HOOK_DEBUG */ | ||
189 | |||
190 | /* Initialize shared TLB - the should probably migrate to smtc_setup_cpus() */ | ||
191 | |||
192 | void __init sanitize_tlb_entries(void) | ||
193 | { | ||
194 | printk("Deprecated sanitize_tlb_entries() invoked\n"); | ||
195 | } | ||
196 | |||
197 | |||
198 | /* | ||
199 | * Configure shared TLB - VPC configuration bit must be set by caller | ||
200 | */ | ||
201 | |||
202 | void smtc_configure_tlb(void) | ||
203 | { | ||
204 | int i,tlbsiz,vpes; | ||
205 | unsigned long mvpconf0; | ||
206 | unsigned long config1val; | ||
207 | |||
208 | /* Set up ASID preservation table */ | ||
209 | for (vpes=0; vpes<MAX_SMTC_TLBS; vpes++) { | ||
210 | for(i = 0; i < MAX_SMTC_ASIDS; i++) { | ||
211 | smtc_live_asid[vpes][i] = 0; | ||
212 | } | ||
213 | } | ||
214 | mvpconf0 = read_c0_mvpconf0(); | ||
215 | |||
216 | if ((vpes = ((mvpconf0 & MVPCONF0_PVPE) | ||
217 | >> MVPCONF0_PVPE_SHIFT) + 1) > 1) { | ||
218 | /* If we have multiple VPEs, try to share the TLB */ | ||
219 | if ((mvpconf0 & MVPCONF0_TLBS) && !nostlb) { | ||
220 | /* | ||
221 | * If TLB sizing is programmable, shared TLB | ||
222 | * size is the total available complement. | ||
223 | * Otherwise, we have to take the sum of all | ||
224 | * static VPE TLB entries. | ||
225 | */ | ||
226 | if ((tlbsiz = ((mvpconf0 & MVPCONF0_PTLBE) | ||
227 | >> MVPCONF0_PTLBE_SHIFT)) == 0) { | ||
228 | /* | ||
229 | * If there's more than one VPE, there had better | ||
230 | * be more than one TC, because we need one to bind | ||
231 | * to each VPE in turn to be able to read | ||
232 | * its configuration state! | ||
233 | */ | ||
234 | settc(1); | ||
235 | /* Stop the TC from doing anything foolish */ | ||
236 | write_tc_c0_tchalt(TCHALT_H); | ||
237 | mips_ihb(); | ||
238 | /* No need to un-Halt - that happens later anyway */ | ||
239 | for (i=0; i < vpes; i++) { | ||
240 | write_tc_c0_tcbind(i); | ||
241 | /* | ||
242 | * To be 100% sure we're really getting the right | ||
243 | * information, we exit the configuration state | ||
244 | * and do an IHB after each rebinding. | ||
245 | */ | ||
246 | write_c0_mvpcontrol( | ||
247 | read_c0_mvpcontrol() & ~ MVPCONTROL_VPC ); | ||
248 | mips_ihb(); | ||
249 | /* | ||
250 | * Only count if the MMU Type indicated is TLB | ||
251 | */ | ||
252 | if(((read_vpe_c0_config() & MIPS_CONF_MT) >> 7) == 1) { | ||
253 | config1val = read_vpe_c0_config1(); | ||
254 | tlbsiz += ((config1val >> 25) & 0x3f) + 1; | ||
255 | } | ||
256 | |||
257 | /* Put core back in configuration state */ | ||
258 | write_c0_mvpcontrol( | ||
259 | read_c0_mvpcontrol() | MVPCONTROL_VPC ); | ||
260 | mips_ihb(); | ||
261 | } | ||
262 | } | ||
263 | write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB); | ||
264 | |||
265 | /* | ||
266 | * Setup kernel data structures to use software total, | ||
267 | * rather than read the per-VPE Config1 value. The values | ||
268 | * for "CPU 0" gets copied to all the other CPUs as part | ||
269 | * of their initialization in smtc_cpu_setup(). | ||
270 | */ | ||
271 | |||
272 | tlbsiz = tlbsiz & 0x3f; /* MIPS32 limits TLB indices to 64 */ | ||
273 | cpu_data[0].tlbsize = tlbsiz; | ||
274 | smtc_status |= SMTC_TLB_SHARED; | ||
275 | |||
276 | printk("TLB of %d entry pairs shared by %d VPEs\n", | ||
277 | tlbsiz, vpes); | ||
278 | } else { | ||
279 | printk("WARNING: TLB Not Sharable on SMTC Boot!\n"); | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | |||
284 | |||
285 | /* | ||
286 | * Incrementally build the CPU map out of constituent MIPS MT cores, | ||
287 | * using the specified available VPEs and TCs. Plaform code needs | ||
288 | * to ensure that each MIPS MT core invokes this routine on reset, | ||
289 | * one at a time(!). | ||
290 | * | ||
291 | * This version of the build_cpu_map and prepare_cpus routines assumes | ||
292 | * that *all* TCs of a MIPS MT core will be used for Linux, and that | ||
293 | * they will be spread across *all* available VPEs (to minimise the | ||
294 | * loss of efficiency due to exception service serialization). | ||
295 | * An improved version would pick up configuration information and | ||
296 | * possibly leave some TCs/VPEs as "slave" processors. | ||
297 | * | ||
298 | * Use c0_MVPConf0 to find out how many TCs are available, setting up | ||
299 | * phys_cpu_present_map and the logical/physical mappings. | ||
300 | */ | ||
301 | |||
302 | int __init mipsmt_build_cpu_map(int start_cpu_slot) | ||
303 | { | ||
304 | int i, ntcs; | ||
305 | |||
306 | /* | ||
307 | * The CPU map isn't actually used for anything at this point, | ||
308 | * so it's not clear what else we should do apart from set | ||
309 | * everything up so that "logical" = "physical". | ||
310 | */ | ||
311 | ntcs = ((read_c0_mvpconf0() & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; | ||
312 | for (i=start_cpu_slot; i<NR_CPUS && i<ntcs; i++) { | ||
313 | cpu_set(i, phys_cpu_present_map); | ||
314 | __cpu_number_map[i] = i; | ||
315 | __cpu_logical_map[i] = i; | ||
316 | } | ||
317 | /* Initialize map of CPUs with FPUs */ | ||
318 | cpus_clear(mt_fpu_cpumask); | ||
319 | |||
320 | /* One of those TC's is the one booting, and not a secondary... */ | ||
321 | printk("%i available secondary CPU TC(s)\n", i - 1); | ||
322 | |||
323 | return i; | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * Common setup before any secondaries are started | ||
328 | * Make sure all CPU's are in a sensible state before we boot any of the | ||
329 | * secondaries. | ||
330 | * | ||
331 | * For MIPS MT "SMTC" operation, we set up all TCs, spread as evenly | ||
332 | * as possible across the available VPEs. | ||
333 | */ | ||
334 | |||
335 | static void smtc_tc_setup(int vpe, int tc, int cpu) | ||
336 | { | ||
337 | settc(tc); | ||
338 | write_tc_c0_tchalt(TCHALT_H); | ||
339 | mips_ihb(); | ||
340 | write_tc_c0_tcstatus((read_tc_c0_tcstatus() | ||
341 | & ~(TCSTATUS_TKSU | TCSTATUS_DA | TCSTATUS_IXMT)) | ||
342 | | TCSTATUS_A); | ||
343 | write_tc_c0_tccontext(0); | ||
344 | /* Bind tc to vpe */ | ||
345 | write_tc_c0_tcbind(vpe); | ||
346 | /* In general, all TCs should have the same cpu_data indications */ | ||
347 | memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); | ||
348 | /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ | ||
349 | if (cpu_data[0].cputype == CPU_34K) | ||
350 | cpu_data[cpu].options &= ~MIPS_CPU_FPU; | ||
351 | cpu_data[cpu].vpe_id = vpe; | ||
352 | cpu_data[cpu].tc_id = tc; | ||
353 | } | ||
354 | |||
355 | |||
356 | void mipsmt_prepare_cpus(void) | ||
357 | { | ||
358 | int i, vpe, tc, ntc, nvpe, tcpervpe, slop, cpu; | ||
359 | unsigned long flags; | ||
360 | unsigned long val; | ||
361 | int nipi; | ||
362 | struct smtc_ipi *pipi; | ||
363 | |||
364 | /* disable interrupts so we can disable MT */ | ||
365 | local_irq_save(flags); | ||
366 | /* disable MT so we can configure */ | ||
367 | dvpe(); | ||
368 | dmt(); | ||
369 | |||
370 | freeIPIq.lock = SPIN_LOCK_UNLOCKED; | ||
371 | |||
372 | /* | ||
373 | * We probably don't have as many VPEs as we do SMP "CPUs", | ||
374 | * but it's possible - and in any case we'll never use more! | ||
375 | */ | ||
376 | for (i=0; i<NR_CPUS; i++) { | ||
377 | IPIQ[i].head = IPIQ[i].tail = NULL; | ||
378 | IPIQ[i].lock = SPIN_LOCK_UNLOCKED; | ||
379 | IPIQ[i].depth = 0; | ||
380 | ipi_timer_latch[i] = 0; | ||
381 | } | ||
382 | |||
383 | /* cpu_data index starts at zero */ | ||
384 | cpu = 0; | ||
385 | cpu_data[cpu].vpe_id = 0; | ||
386 | cpu_data[cpu].tc_id = 0; | ||
387 | cpu++; | ||
388 | |||
389 | /* Report on boot-time options */ | ||
390 | mips_mt_set_cpuoptions (); | ||
391 | if (vpelimit > 0) | ||
392 | printk("Limit of %d VPEs set\n", vpelimit); | ||
393 | if (tclimit > 0) | ||
394 | printk("Limit of %d TCs set\n", tclimit); | ||
395 | if (nostlb) { | ||
396 | printk("Shared TLB Use Inhibited - UNSAFE for Multi-VPE Operation\n"); | ||
397 | } | ||
398 | if (asidmask) | ||
399 | printk("ASID mask value override to 0x%x\n", asidmask); | ||
400 | |||
401 | /* Temporary */ | ||
402 | #ifdef SMTC_IDLE_HOOK_DEBUG | ||
403 | if (hang_trig) | ||
404 | printk("Logic Analyser Trigger on suspected TC hang\n"); | ||
405 | #endif /* SMTC_IDLE_HOOK_DEBUG */ | ||
406 | |||
407 | /* Put MVPE's into 'configuration state' */ | ||
408 | write_c0_mvpcontrol( read_c0_mvpcontrol() | MVPCONTROL_VPC ); | ||
409 | |||
410 | val = read_c0_mvpconf0(); | ||
411 | nvpe = ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; | ||
412 | if (vpelimit > 0 && nvpe > vpelimit) | ||
413 | nvpe = vpelimit; | ||
414 | ntc = ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; | ||
415 | if (ntc > NR_CPUS) | ||
416 | ntc = NR_CPUS; | ||
417 | if (tclimit > 0 && ntc > tclimit) | ||
418 | ntc = tclimit; | ||
419 | tcpervpe = ntc / nvpe; | ||
420 | slop = ntc % nvpe; /* Residual TCs, < NVPE */ | ||
421 | |||
422 | /* Set up shared TLB */ | ||
423 | smtc_configure_tlb(); | ||
424 | |||
425 | for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { | ||
426 | /* | ||
427 | * Set the MVP bits. | ||
428 | */ | ||
429 | settc(tc); | ||
430 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_MVP); | ||
431 | if (vpe != 0) | ||
432 | printk(", "); | ||
433 | printk("VPE %d: TC", vpe); | ||
434 | for (i = 0; i < tcpervpe; i++) { | ||
435 | /* | ||
436 | * TC 0 is bound to VPE 0 at reset, | ||
437 | * and is presumably executing this | ||
438 | * code. Leave it alone! | ||
439 | */ | ||
440 | if (tc != 0) { | ||
441 | smtc_tc_setup(vpe,tc, cpu); | ||
442 | cpu++; | ||
443 | } | ||
444 | printk(" %d", tc); | ||
445 | tc++; | ||
446 | } | ||
447 | if (slop) { | ||
448 | if (tc != 0) { | ||
449 | smtc_tc_setup(vpe,tc, cpu); | ||
450 | cpu++; | ||
451 | } | ||
452 | printk(" %d", tc); | ||
453 | tc++; | ||
454 | slop--; | ||
455 | } | ||
456 | if (vpe != 0) { | ||
457 | /* | ||
458 | * Clear any stale software interrupts from VPE's Cause | ||
459 | */ | ||
460 | write_vpe_c0_cause(0); | ||
461 | |||
462 | /* | ||
463 | * Clear ERL/EXL of VPEs other than 0 | ||
464 | * and set restricted interrupt enable/mask. | ||
465 | */ | ||
466 | write_vpe_c0_status((read_vpe_c0_status() | ||
467 | & ~(ST0_BEV | ST0_ERL | ST0_EXL | ST0_IM)) | ||
468 | | (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7 | ||
469 | | ST0_IE)); | ||
470 | /* | ||
471 | * set config to be the same as vpe0, | ||
472 | * particularly kseg0 coherency alg | ||
473 | */ | ||
474 | write_vpe_c0_config(read_c0_config()); | ||
475 | /* Clear any pending timer interrupt */ | ||
476 | write_vpe_c0_compare(0); | ||
477 | /* Propagate Config7 */ | ||
478 | write_vpe_c0_config7(read_c0_config7()); | ||
479 | } | ||
480 | /* enable multi-threading within VPE */ | ||
481 | write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE); | ||
482 | /* enable the VPE */ | ||
483 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); | ||
484 | } | ||
485 | |||
486 | /* | ||
487 | * Pull any physically present but unused TCs out of circulation. | ||
488 | */ | ||
489 | while (tc < (((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1)) { | ||
490 | cpu_clear(tc, phys_cpu_present_map); | ||
491 | cpu_clear(tc, cpu_present_map); | ||
492 | tc++; | ||
493 | } | ||
494 | |||
495 | /* release config state */ | ||
496 | write_c0_mvpcontrol( read_c0_mvpcontrol() & ~ MVPCONTROL_VPC ); | ||
497 | |||
498 | printk("\n"); | ||
499 | |||
500 | /* Set up coprocessor affinity CPU mask(s) */ | ||
501 | |||
502 | for (tc = 0; tc < ntc; tc++) { | ||
503 | if(cpu_data[tc].options & MIPS_CPU_FPU) | ||
504 | cpu_set(tc, mt_fpu_cpumask); | ||
505 | } | ||
506 | |||
507 | /* set up ipi interrupts... */ | ||
508 | |||
509 | /* If we have multiple VPEs running, set up the cross-VPE interrupt */ | ||
510 | |||
511 | if (nvpe > 1) | ||
512 | setup_cross_vpe_interrupts(); | ||
513 | |||
514 | /* Set up queue of free IPI "messages". */ | ||
515 | nipi = NR_CPUS * IPIBUF_PER_CPU; | ||
516 | if (ipibuffers > 0) | ||
517 | nipi = ipibuffers; | ||
518 | |||
519 | pipi = kmalloc(nipi *sizeof(struct smtc_ipi), GFP_KERNEL); | ||
520 | if (pipi == NULL) | ||
521 | panic("kmalloc of IPI message buffers failed\n"); | ||
522 | else | ||
523 | printk("IPI buffer pool of %d buffers\n", nipi); | ||
524 | for (i = 0; i < nipi; i++) { | ||
525 | smtc_ipi_nq(&freeIPIq, pipi); | ||
526 | pipi++; | ||
527 | } | ||
528 | |||
529 | /* Arm multithreading and enable other VPEs - but all TCs are Halted */ | ||
530 | emt(EMT_ENABLE); | ||
531 | evpe(EVPE_ENABLE); | ||
532 | local_irq_restore(flags); | ||
533 | /* Initialize SMTC /proc statistics/diagnostics */ | ||
534 | init_smtc_stats(); | ||
535 | } | ||
536 | |||
537 | |||
538 | /* | ||
539 | * Setup the PC, SP, and GP of a secondary processor and start it | ||
540 | * running! | ||
541 | * smp_bootstrap is the place to resume from | ||
542 | * __KSTK_TOS(idle) is apparently the stack pointer | ||
543 | * (unsigned long)idle->thread_info the gp | ||
544 | * | ||
545 | */ | ||
546 | void smtc_boot_secondary(int cpu, struct task_struct *idle) | ||
547 | { | ||
548 | extern u32 kernelsp[NR_CPUS]; | ||
549 | long flags; | ||
550 | int mtflags; | ||
551 | |||
552 | LOCK_MT_PRA(); | ||
553 | if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { | ||
554 | dvpe(); | ||
555 | } | ||
556 | settc(cpu_data[cpu].tc_id); | ||
557 | |||
558 | /* pc */ | ||
559 | write_tc_c0_tcrestart((unsigned long)&smp_bootstrap); | ||
560 | |||
561 | /* stack pointer */ | ||
562 | kernelsp[cpu] = __KSTK_TOS(idle); | ||
563 | write_tc_gpr_sp(__KSTK_TOS(idle)); | ||
564 | |||
565 | /* global pointer */ | ||
566 | write_tc_gpr_gp((unsigned long)idle->thread_info); | ||
567 | |||
568 | smtc_status |= SMTC_MTC_ACTIVE; | ||
569 | write_tc_c0_tchalt(0); | ||
570 | if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { | ||
571 | evpe(EVPE_ENABLE); | ||
572 | } | ||
573 | UNLOCK_MT_PRA(); | ||
574 | } | ||
575 | |||
576 | void smtc_init_secondary(void) | ||
577 | { | ||
578 | /* | ||
579 | * Start timer on secondary VPEs if necessary. | ||
580 | * mips_timer_setup should already have been invoked by init/main | ||
581 | * on "boot" TC. Like per_cpu_trap_init() hack, this assumes that | ||
582 | * SMTC init code assigns TCs consdecutively and in ascending order | ||
583 | * to across available VPEs. | ||
584 | */ | ||
585 | if(((read_c0_tcbind() & TCBIND_CURTC) != 0) | ||
586 | && ((read_c0_tcbind() & TCBIND_CURVPE) | ||
587 | != cpu_data[smp_processor_id() - 1].vpe_id)){ | ||
588 | write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ); | ||
589 | } | ||
590 | |||
591 | local_irq_enable(); | ||
592 | } | ||
593 | |||
594 | void smtc_smp_finish(void) | ||
595 | { | ||
596 | printk("TC %d going on-line as CPU %d\n", | ||
597 | cpu_data[smp_processor_id()].tc_id, smp_processor_id()); | ||
598 | } | ||
599 | |||
600 | void smtc_cpus_done(void) | ||
601 | { | ||
602 | } | ||
603 | |||
604 | /* | ||
605 | * Support for SMTC-optimized driver IRQ registration | ||
606 | */ | ||
607 | |||
608 | /* | ||
609 | * SMTC Kernel needs to manipulate low-level CPU interrupt mask | ||
610 | * in do_IRQ. These are passed in setup_irq_smtc() and stored | ||
611 | * in this table. | ||
612 | */ | ||
613 | |||
614 | int setup_irq_smtc(unsigned int irq, struct irqaction * new, | ||
615 | unsigned long hwmask) | ||
616 | { | ||
617 | irq_hwmask[irq] = hwmask; | ||
618 | |||
619 | return setup_irq(irq, new); | ||
620 | } | ||
621 | |||
622 | /* | ||
623 | * IPI model for SMTC is tricky, because interrupts aren't TC-specific. | ||
624 | * Within a VPE one TC can interrupt another by different approaches. | ||
625 | * The easiest to get right would probably be to make all TCs except | ||
626 | * the target IXMT and set a software interrupt, but an IXMT-based | ||
627 | * scheme requires that a handler must run before a new IPI could | ||
628 | * be sent, which would break the "broadcast" loops in MIPS MT. | ||
629 | * A more gonzo approach within a VPE is to halt the TC, extract | ||
630 | * its Restart, Status, and a couple of GPRs, and program the Restart | ||
631 | * address to emulate an interrupt. | ||
632 | * | ||
633 | * Within a VPE, one can be confident that the target TC isn't in | ||
634 | * a critical EXL state when halted, since the write to the Halt | ||
635 | * register could not have issued on the writing thread if the | ||
636 | * halting thread had EXL set. So k0 and k1 of the target TC | ||
637 | * can be used by the injection code. Across VPEs, one can't | ||
638 | * be certain that the target TC isn't in a critical exception | ||
639 | * state. So we try a two-step process of sending a software | ||
640 | * interrupt to the target VPE, which either handles the event | ||
641 | * itself (if it was the target) or injects the event within | ||
642 | * the VPE. | ||
643 | */ | ||
644 | |||
645 | void smtc_ipi_qdump(void) | ||
646 | { | ||
647 | int i; | ||
648 | |||
649 | for (i = 0; i < NR_CPUS ;i++) { | ||
650 | printk("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n", | ||
651 | i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail, | ||
652 | IPIQ[i].depth); | ||
653 | } | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * The standard atomic.h primitives don't quite do what we want | ||
658 | * here: We need an atomic add-and-return-previous-value (which | ||
659 | * could be done with atomic_add_return and a decrement) and an | ||
660 | * atomic set/zero-and-return-previous-value (which can't really | ||
661 | * be done with the atomic.h primitives). And since this is | ||
662 | * MIPS MT, we can assume that we have LL/SC. | ||
663 | */ | ||
664 | static __inline__ int atomic_postincrement(unsigned int *pv) | ||
665 | { | ||
666 | unsigned long result; | ||
667 | |||
668 | unsigned long temp; | ||
669 | |||
670 | __asm__ __volatile__( | ||
671 | "1: ll %0, %2 \n" | ||
672 | " addu %1, %0, 1 \n" | ||
673 | " sc %1, %2 \n" | ||
674 | " beqz %1, 1b \n" | ||
675 | " sync \n" | ||
676 | : "=&r" (result), "=&r" (temp), "=m" (*pv) | ||
677 | : "m" (*pv) | ||
678 | : "memory"); | ||
679 | |||
680 | return result; | ||
681 | } | ||
682 | |||
683 | /* No longer used in IPI dispatch, but retained for future recycling */ | ||
684 | |||
685 | static __inline__ int atomic_postclear(unsigned int *pv) | ||
686 | { | ||
687 | unsigned long result; | ||
688 | |||
689 | unsigned long temp; | ||
690 | |||
691 | __asm__ __volatile__( | ||
692 | "1: ll %0, %2 \n" | ||
693 | " or %1, $0, $0 \n" | ||
694 | " sc %1, %2 \n" | ||
695 | " beqz %1, 1b \n" | ||
696 | " sync \n" | ||
697 | : "=&r" (result), "=&r" (temp), "=m" (*pv) | ||
698 | : "m" (*pv) | ||
699 | : "memory"); | ||
700 | |||
701 | return result; | ||
702 | } | ||
703 | |||
704 | |||
705 | void smtc_send_ipi(int cpu, int type, unsigned int action) | ||
706 | { | ||
707 | int tcstatus; | ||
708 | struct smtc_ipi *pipi; | ||
709 | long flags; | ||
710 | int mtflags; | ||
711 | |||
712 | if (cpu == smp_processor_id()) { | ||
713 | printk("Cannot Send IPI to self!\n"); | ||
714 | return; | ||
715 | } | ||
716 | /* Set up a descriptor, to be delivered either promptly or queued */ | ||
717 | pipi = smtc_ipi_dq(&freeIPIq); | ||
718 | if (pipi == NULL) { | ||
719 | bust_spinlocks(1); | ||
720 | mips_mt_regdump(dvpe()); | ||
721 | panic("IPI Msg. Buffers Depleted\n"); | ||
722 | } | ||
723 | pipi->type = type; | ||
724 | pipi->arg = (void *)action; | ||
725 | pipi->dest = cpu; | ||
726 | if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { | ||
727 | /* If not on same VPE, enqueue and send cross-VPE interupt */ | ||
728 | smtc_ipi_nq(&IPIQ[cpu], pipi); | ||
729 | LOCK_CORE_PRA(); | ||
730 | settc(cpu_data[cpu].tc_id); | ||
731 | write_vpe_c0_cause(read_vpe_c0_cause() | C_SW1); | ||
732 | UNLOCK_CORE_PRA(); | ||
733 | } else { | ||
734 | /* | ||
735 | * Not sufficient to do a LOCK_MT_PRA (dmt) here, | ||
736 | * since ASID shootdown on the other VPE may | ||
737 | * collide with this operation. | ||
738 | */ | ||
739 | LOCK_CORE_PRA(); | ||
740 | settc(cpu_data[cpu].tc_id); | ||
741 | /* Halt the targeted TC */ | ||
742 | write_tc_c0_tchalt(TCHALT_H); | ||
743 | mips_ihb(); | ||
744 | |||
745 | /* | ||
746 | * Inspect TCStatus - if IXMT is set, we have to queue | ||
747 | * a message. Otherwise, we set up the "interrupt" | ||
748 | * of the other TC | ||
749 | */ | ||
750 | tcstatus = read_tc_c0_tcstatus(); | ||
751 | |||
752 | if ((tcstatus & TCSTATUS_IXMT) != 0) { | ||
753 | /* | ||
754 | * Spin-waiting here can deadlock, | ||
755 | * so we queue the message for the target TC. | ||
756 | */ | ||
757 | write_tc_c0_tchalt(0); | ||
758 | UNLOCK_CORE_PRA(); | ||
759 | /* Try to reduce redundant timer interrupt messages */ | ||
760 | if(type == SMTC_CLOCK_TICK) { | ||
761 | if(atomic_postincrement(&ipi_timer_latch[cpu])!=0) { | ||
762 | smtc_ipi_nq(&freeIPIq, pipi); | ||
763 | return; | ||
764 | } | ||
765 | } | ||
766 | smtc_ipi_nq(&IPIQ[cpu], pipi); | ||
767 | } else { | ||
768 | post_direct_ipi(cpu, pipi); | ||
769 | write_tc_c0_tchalt(0); | ||
770 | UNLOCK_CORE_PRA(); | ||
771 | } | ||
772 | } | ||
773 | } | ||
774 | |||
775 | /* | ||
776 | * Send IPI message to Halted TC, TargTC/TargVPE already having been set | ||
777 | */ | ||
778 | void post_direct_ipi(int cpu, struct smtc_ipi *pipi) | ||
779 | { | ||
780 | struct pt_regs *kstack; | ||
781 | unsigned long tcstatus; | ||
782 | unsigned long tcrestart; | ||
783 | extern u32 kernelsp[NR_CPUS]; | ||
784 | extern void __smtc_ipi_vector(void); | ||
785 | |||
786 | /* Extract Status, EPC from halted TC */ | ||
787 | tcstatus = read_tc_c0_tcstatus(); | ||
788 | tcrestart = read_tc_c0_tcrestart(); | ||
789 | /* If TCRestart indicates a WAIT instruction, advance the PC */ | ||
790 | if ((tcrestart & 0x80000000) | ||
791 | && ((*(unsigned int *)tcrestart & 0xfe00003f) == 0x42000020)) { | ||
792 | tcrestart += 4; | ||
793 | } | ||
794 | /* | ||
795 | * Save on TC's future kernel stack | ||
796 | * | ||
797 | * CU bit of Status is indicator that TC was | ||
798 | * already running on a kernel stack... | ||
799 | */ | ||
800 | if(tcstatus & ST0_CU0) { | ||
801 | /* Note that this "- 1" is pointer arithmetic */ | ||
802 | kstack = ((struct pt_regs *)read_tc_gpr_sp()) - 1; | ||
803 | } else { | ||
804 | kstack = ((struct pt_regs *)kernelsp[cpu]) - 1; | ||
805 | } | ||
806 | |||
807 | kstack->cp0_epc = (long)tcrestart; | ||
808 | /* Save TCStatus */ | ||
809 | kstack->cp0_tcstatus = tcstatus; | ||
810 | /* Pass token of operation to be performed kernel stack pad area */ | ||
811 | kstack->pad0[4] = (unsigned long)pipi; | ||
812 | /* Pass address of function to be called likewise */ | ||
813 | kstack->pad0[5] = (unsigned long)&ipi_decode; | ||
814 | /* Set interrupt exempt and kernel mode */ | ||
815 | tcstatus |= TCSTATUS_IXMT; | ||
816 | tcstatus &= ~TCSTATUS_TKSU; | ||
817 | write_tc_c0_tcstatus(tcstatus); | ||
818 | ehb(); | ||
819 | /* Set TC Restart address to be SMTC IPI vector */ | ||
820 | write_tc_c0_tcrestart(__smtc_ipi_vector); | ||
821 | } | ||
822 | |||
823 | void ipi_resched_interrupt(struct pt_regs *regs) | ||
824 | { | ||
825 | /* Return from interrupt should be enough to cause scheduler check */ | ||
826 | } | ||
827 | |||
828 | |||
829 | void ipi_call_interrupt(struct pt_regs *regs) | ||
830 | { | ||
831 | /* Invoke generic function invocation code in smp.c */ | ||
832 | smp_call_function_interrupt(); | ||
833 | } | ||
834 | |||
835 | void ipi_decode(struct pt_regs *regs, struct smtc_ipi *pipi) | ||
836 | { | ||
837 | void *arg_copy = pipi->arg; | ||
838 | int type_copy = pipi->type; | ||
839 | int dest_copy = pipi->dest; | ||
840 | |||
841 | smtc_ipi_nq(&freeIPIq, pipi); | ||
842 | switch (type_copy) { | ||
843 | case SMTC_CLOCK_TICK: | ||
844 | /* Invoke Clock "Interrupt" */ | ||
845 | ipi_timer_latch[dest_copy] = 0; | ||
846 | #ifdef SMTC_IDLE_HOOK_DEBUG | ||
847 | clock_hang_reported[dest_copy] = 0; | ||
848 | #endif /* SMTC_IDLE_HOOK_DEBUG */ | ||
849 | local_timer_interrupt(0, NULL, regs); | ||
850 | break; | ||
851 | case LINUX_SMP_IPI: | ||
852 | switch ((int)arg_copy) { | ||
853 | case SMP_RESCHEDULE_YOURSELF: | ||
854 | ipi_resched_interrupt(regs); | ||
855 | break; | ||
856 | case SMP_CALL_FUNCTION: | ||
857 | ipi_call_interrupt(regs); | ||
858 | break; | ||
859 | default: | ||
860 | printk("Impossible SMTC IPI Argument 0x%x\n", | ||
861 | (int)arg_copy); | ||
862 | break; | ||
863 | } | ||
864 | break; | ||
865 | default: | ||
866 | printk("Impossible SMTC IPI Type 0x%x\n", type_copy); | ||
867 | break; | ||
868 | } | ||
869 | } | ||
870 | |||
871 | void deferred_smtc_ipi(struct pt_regs *regs) | ||
872 | { | ||
873 | struct smtc_ipi *pipi; | ||
874 | unsigned long flags; | ||
875 | /* DEBUG */ | ||
876 | int q = smp_processor_id(); | ||
877 | |||
878 | /* | ||
879 | * Test is not atomic, but much faster than a dequeue, | ||
880 | * and the vast majority of invocations will have a null queue. | ||
881 | */ | ||
882 | if(IPIQ[q].head != NULL) { | ||
883 | while((pipi = smtc_ipi_dq(&IPIQ[q])) != NULL) { | ||
884 | /* ipi_decode() should be called with interrupts off */ | ||
885 | local_irq_save(flags); | ||
886 | ipi_decode(regs, pipi); | ||
887 | local_irq_restore(flags); | ||
888 | } | ||
889 | } | ||
890 | } | ||
891 | |||
892 | /* | ||
893 | * Send clock tick to all TCs except the one executing the funtion | ||
894 | */ | ||
895 | |||
896 | void smtc_timer_broadcast(int vpe) | ||
897 | { | ||
898 | int cpu; | ||
899 | int myTC = cpu_data[smp_processor_id()].tc_id; | ||
900 | int myVPE = cpu_data[smp_processor_id()].vpe_id; | ||
901 | |||
902 | smtc_cpu_stats[smp_processor_id()].timerints++; | ||
903 | |||
904 | for_each_online_cpu(cpu) { | ||
905 | if (cpu_data[cpu].vpe_id == myVPE && | ||
906 | cpu_data[cpu].tc_id != myTC) | ||
907 | smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0); | ||
908 | } | ||
909 | } | ||
910 | |||
911 | /* | ||
912 | * Cross-VPE interrupts in the SMTC prototype use "software interrupts" | ||
913 | * set via cross-VPE MTTR manipulation of the Cause register. It would be | ||
914 | * in some regards preferable to have external logic for "doorbell" hardware | ||
915 | * interrupts. | ||
916 | */ | ||
917 | |||
918 | static int cpu_ipi_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_IRQ; | ||
919 | |||
920 | static irqreturn_t ipi_interrupt(int irq, void *dev_idm, struct pt_regs *regs) | ||
921 | { | ||
922 | int my_vpe = cpu_data[smp_processor_id()].vpe_id; | ||
923 | int my_tc = cpu_data[smp_processor_id()].tc_id; | ||
924 | int cpu; | ||
925 | struct smtc_ipi *pipi; | ||
926 | unsigned long tcstatus; | ||
927 | int sent; | ||
928 | long flags; | ||
929 | unsigned int mtflags; | ||
930 | unsigned int vpflags; | ||
931 | |||
932 | /* | ||
933 | * So long as cross-VPE interrupts are done via | ||
934 | * MFTR/MTTR read-modify-writes of Cause, we need | ||
935 | * to stop other VPEs whenever the local VPE does | ||
936 | * anything similar. | ||
937 | */ | ||
938 | local_irq_save(flags); | ||
939 | vpflags = dvpe(); | ||
940 | clear_c0_cause(0x100 << MIPS_CPU_IPI_IRQ); | ||
941 | set_c0_status(0x100 << MIPS_CPU_IPI_IRQ); | ||
942 | irq_enable_hazard(); | ||
943 | evpe(vpflags); | ||
944 | local_irq_restore(flags); | ||
945 | |||
946 | /* | ||
947 | * Cross-VPE Interrupt handler: Try to directly deliver IPIs | ||
948 | * queued for TCs on this VPE other than the current one. | ||
949 | * Return-from-interrupt should cause us to drain the queue | ||
950 | * for the current TC, so we ought not to have to do it explicitly here. | ||
951 | */ | ||
952 | |||
953 | for_each_online_cpu(cpu) { | ||
954 | if (cpu_data[cpu].vpe_id != my_vpe) | ||
955 | continue; | ||
956 | |||
957 | pipi = smtc_ipi_dq(&IPIQ[cpu]); | ||
958 | if (pipi != NULL) { | ||
959 | if (cpu_data[cpu].tc_id != my_tc) { | ||
960 | sent = 0; | ||
961 | LOCK_MT_PRA(); | ||
962 | settc(cpu_data[cpu].tc_id); | ||
963 | write_tc_c0_tchalt(TCHALT_H); | ||
964 | mips_ihb(); | ||
965 | tcstatus = read_tc_c0_tcstatus(); | ||
966 | if ((tcstatus & TCSTATUS_IXMT) == 0) { | ||
967 | post_direct_ipi(cpu, pipi); | ||
968 | sent = 1; | ||
969 | } | ||
970 | write_tc_c0_tchalt(0); | ||
971 | UNLOCK_MT_PRA(); | ||
972 | if (!sent) { | ||
973 | smtc_ipi_req(&IPIQ[cpu], pipi); | ||
974 | } | ||
975 | } else { | ||
976 | /* | ||
977 | * ipi_decode() should be called | ||
978 | * with interrupts off | ||
979 | */ | ||
980 | local_irq_save(flags); | ||
981 | ipi_decode(regs, pipi); | ||
982 | local_irq_restore(flags); | ||
983 | } | ||
984 | } | ||
985 | } | ||
986 | |||
987 | return IRQ_HANDLED; | ||
988 | } | ||
989 | |||
990 | static void ipi_irq_dispatch(struct pt_regs *regs) | ||
991 | { | ||
992 | do_IRQ(cpu_ipi_irq, regs); | ||
993 | } | ||
994 | |||
995 | static struct irqaction irq_ipi; | ||
996 | |||
997 | void setup_cross_vpe_interrupts(void) | ||
998 | { | ||
999 | if (!cpu_has_vint) | ||
1000 | panic("SMTC Kernel requires Vectored Interupt support"); | ||
1001 | |||
1002 | set_vi_handler(MIPS_CPU_IPI_IRQ, ipi_irq_dispatch); | ||
1003 | |||
1004 | irq_ipi.handler = ipi_interrupt; | ||
1005 | irq_ipi.flags = SA_INTERRUPT; | ||
1006 | irq_ipi.name = "SMTC_IPI"; | ||
1007 | |||
1008 | setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ)); | ||
1009 | |||
1010 | irq_desc[cpu_ipi_irq].status |= IRQ_PER_CPU; | ||
1011 | } | ||
1012 | |||
1013 | /* | ||
1014 | * SMTC-specific hacks invoked from elsewhere in the kernel. | ||
1015 | */ | ||
1016 | |||
1017 | void smtc_idle_loop_hook(void) | ||
1018 | { | ||
1019 | #ifdef SMTC_IDLE_HOOK_DEBUG | ||
1020 | int im; | ||
1021 | int flags; | ||
1022 | int mtflags; | ||
1023 | int bit; | ||
1024 | int vpe; | ||
1025 | int tc; | ||
1026 | int hook_ntcs; | ||
1027 | /* | ||
1028 | * printk within DMT-protected regions can deadlock, | ||
1029 | * so buffer diagnostic messages for later output. | ||
1030 | */ | ||
1031 | char *pdb_msg; | ||
1032 | char id_ho_db_msg[768]; /* worst-case use should be less than 700 */ | ||
1033 | |||
1034 | if (atomic_read(&idle_hook_initialized) == 0) { /* fast test */ | ||
1035 | if (atomic_add_return(1, &idle_hook_initialized) == 1) { | ||
1036 | int mvpconf0; | ||
1037 | /* Tedious stuff to just do once */ | ||
1038 | mvpconf0 = read_c0_mvpconf0(); | ||
1039 | hook_ntcs = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; | ||
1040 | if (hook_ntcs > NR_CPUS) | ||
1041 | hook_ntcs = NR_CPUS; | ||
1042 | for (tc = 0; tc < hook_ntcs; tc++) { | ||
1043 | tcnoprog[tc] = 0; | ||
1044 | clock_hang_reported[tc] = 0; | ||
1045 | } | ||
1046 | for (vpe = 0; vpe < 2; vpe++) | ||
1047 | for (im = 0; im < 8; im++) | ||
1048 | imstuckcount[vpe][im] = 0; | ||
1049 | printk("Idle loop test hook initialized for %d TCs\n", hook_ntcs); | ||
1050 | atomic_set(&idle_hook_initialized, 1000); | ||
1051 | } else { | ||
1052 | /* Someone else is initializing in parallel - let 'em finish */ | ||
1053 | while (atomic_read(&idle_hook_initialized) < 1000) | ||
1054 | ; | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | /* Have we stupidly left IXMT set somewhere? */ | ||
1059 | if (read_c0_tcstatus() & 0x400) { | ||
1060 | write_c0_tcstatus(read_c0_tcstatus() & ~0x400); | ||
1061 | ehb(); | ||
1062 | printk("Dangling IXMT in cpu_idle()\n"); | ||
1063 | } | ||
1064 | |||
1065 | /* Have we stupidly left an IM bit turned off? */ | ||
1066 | #define IM_LIMIT 2000 | ||
1067 | local_irq_save(flags); | ||
1068 | mtflags = dmt(); | ||
1069 | pdb_msg = &id_ho_db_msg[0]; | ||
1070 | im = read_c0_status(); | ||
1071 | vpe = cpu_data[smp_processor_id()].vpe_id; | ||
1072 | for (bit = 0; bit < 8; bit++) { | ||
1073 | /* | ||
1074 | * In current prototype, I/O interrupts | ||
1075 | * are masked for VPE > 0 | ||
1076 | */ | ||
1077 | if (vpemask[vpe][bit]) { | ||
1078 | if (!(im & (0x100 << bit))) | ||
1079 | imstuckcount[vpe][bit]++; | ||
1080 | else | ||
1081 | imstuckcount[vpe][bit] = 0; | ||
1082 | if (imstuckcount[vpe][bit] > IM_LIMIT) { | ||
1083 | set_c0_status(0x100 << bit); | ||
1084 | ehb(); | ||
1085 | imstuckcount[vpe][bit] = 0; | ||
1086 | pdb_msg += sprintf(pdb_msg, | ||
1087 | "Dangling IM %d fixed for VPE %d\n", bit, | ||
1088 | vpe); | ||
1089 | } | ||
1090 | } | ||
1091 | } | ||
1092 | |||
1093 | /* | ||
1094 | * Now that we limit outstanding timer IPIs, check for hung TC | ||
1095 | */ | ||
1096 | for (tc = 0; tc < NR_CPUS; tc++) { | ||
1097 | /* Don't check ourself - we'll dequeue IPIs just below */ | ||
1098 | if ((tc != smp_processor_id()) && | ||
1099 | ipi_timer_latch[tc] > timerq_limit) { | ||
1100 | if (clock_hang_reported[tc] == 0) { | ||
1101 | pdb_msg += sprintf(pdb_msg, | ||
1102 | "TC %d looks hung with timer latch at %d\n", | ||
1103 | tc, ipi_timer_latch[tc]); | ||
1104 | clock_hang_reported[tc]++; | ||
1105 | } | ||
1106 | } | ||
1107 | } | ||
1108 | emt(mtflags); | ||
1109 | local_irq_restore(flags); | ||
1110 | if (pdb_msg != &id_ho_db_msg[0]) | ||
1111 | printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); | ||
1112 | #endif /* SMTC_IDLE_HOOK_DEBUG */ | ||
1113 | /* | ||
1114 | * To the extent that we've ever turned interrupts off, | ||
1115 | * we may have accumulated deferred IPIs. This is subtle. | ||
1116 | * If we use the smtc_ipi_qdepth() macro, we'll get an | ||
1117 | * exact number - but we'll also disable interrupts | ||
1118 | * and create a window of failure where a new IPI gets | ||
1119 | * queued after we test the depth but before we re-enable | ||
1120 | * interrupts. So long as IXMT never gets set, however, | ||
1121 | * we should be OK: If we pick up something and dispatch | ||
1122 | * it here, that's great. If we see nothing, but concurrent | ||
1123 | * with this operation, another TC sends us an IPI, IXMT | ||
1124 | * is clear, and we'll handle it as a real pseudo-interrupt | ||
1125 | * and not a pseudo-pseudo interrupt. | ||
1126 | */ | ||
1127 | if (IPIQ[smp_processor_id()].depth > 0) { | ||
1128 | struct smtc_ipi *pipi; | ||
1129 | extern void self_ipi(struct smtc_ipi *); | ||
1130 | |||
1131 | if ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()])) != NULL) { | ||
1132 | self_ipi(pipi); | ||
1133 | smtc_cpu_stats[smp_processor_id()].selfipis++; | ||
1134 | } | ||
1135 | } | ||
1136 | } | ||
1137 | |||
1138 | void smtc_soft_dump(void) | ||
1139 | { | ||
1140 | int i; | ||
1141 | |||
1142 | printk("Counter Interrupts taken per CPU (TC)\n"); | ||
1143 | for (i=0; i < NR_CPUS; i++) { | ||
1144 | printk("%d: %ld\n", i, smtc_cpu_stats[i].timerints); | ||
1145 | } | ||
1146 | printk("Self-IPI invocations:\n"); | ||
1147 | for (i=0; i < NR_CPUS; i++) { | ||
1148 | printk("%d: %ld\n", i, smtc_cpu_stats[i].selfipis); | ||
1149 | } | ||
1150 | smtc_ipi_qdump(); | ||
1151 | printk("Timer IPI Backlogs:\n"); | ||
1152 | for (i=0; i < NR_CPUS; i++) { | ||
1153 | printk("%d: %d\n", i, ipi_timer_latch[i]); | ||
1154 | } | ||
1155 | printk("%d Recoveries of \"stolen\" FPU\n", | ||
1156 | atomic_read(&smtc_fpu_recoveries)); | ||
1157 | } | ||
1158 | |||
1159 | |||
1160 | /* | ||
1161 | * TLB management routines special to SMTC | ||
1162 | */ | ||
1163 | |||
1164 | void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | ||
1165 | { | ||
1166 | unsigned long flags, mtflags, tcstat, prevhalt, asid; | ||
1167 | int tlb, i; | ||
1168 | |||
1169 | /* | ||
1170 | * It would be nice to be able to use a spinlock here, | ||
1171 | * but this is invoked from within TLB flush routines | ||
1172 | * that protect themselves with DVPE, so if a lock is | ||
1173 | * held by another TC, it'll never be freed. | ||
1174 | * | ||
1175 | * DVPE/DMT must not be done with interrupts enabled, | ||
1176 | * so even so most callers will already have disabled | ||
1177 | * them, let's be really careful... | ||
1178 | */ | ||
1179 | |||
1180 | local_irq_save(flags); | ||
1181 | if (smtc_status & SMTC_TLB_SHARED) { | ||
1182 | mtflags = dvpe(); | ||
1183 | tlb = 0; | ||
1184 | } else { | ||
1185 | mtflags = dmt(); | ||
1186 | tlb = cpu_data[cpu].vpe_id; | ||
1187 | } | ||
1188 | asid = asid_cache(cpu); | ||
1189 | |||
1190 | do { | ||
1191 | if (!((asid += ASID_INC) & ASID_MASK) ) { | ||
1192 | if (cpu_has_vtag_icache) | ||
1193 | flush_icache_all(); | ||
1194 | /* Traverse all online CPUs (hack requires contigous range) */ | ||
1195 | for (i = 0; i < num_online_cpus(); i++) { | ||
1196 | /* | ||
1197 | * We don't need to worry about our own CPU, nor those of | ||
1198 | * CPUs who don't share our TLB. | ||
1199 | */ | ||
1200 | if ((i != smp_processor_id()) && | ||
1201 | ((smtc_status & SMTC_TLB_SHARED) || | ||
1202 | (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))) { | ||
1203 | settc(cpu_data[i].tc_id); | ||
1204 | prevhalt = read_tc_c0_tchalt() & TCHALT_H; | ||
1205 | if (!prevhalt) { | ||
1206 | write_tc_c0_tchalt(TCHALT_H); | ||
1207 | mips_ihb(); | ||
1208 | } | ||
1209 | tcstat = read_tc_c0_tcstatus(); | ||
1210 | smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i); | ||
1211 | if (!prevhalt) | ||
1212 | write_tc_c0_tchalt(0); | ||
1213 | } | ||
1214 | } | ||
1215 | if (!asid) /* fix version if needed */ | ||
1216 | asid = ASID_FIRST_VERSION; | ||
1217 | local_flush_tlb_all(); /* start new asid cycle */ | ||
1218 | } | ||
1219 | } while (smtc_live_asid[tlb][(asid & ASID_MASK)]); | ||
1220 | |||
1221 | /* | ||
1222 | * SMTC shares the TLB within VPEs and possibly across all VPEs. | ||
1223 | */ | ||
1224 | for (i = 0; i < num_online_cpus(); i++) { | ||
1225 | if ((smtc_status & SMTC_TLB_SHARED) || | ||
1226 | (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id)) | ||
1227 | cpu_context(i, mm) = asid_cache(i) = asid; | ||
1228 | } | ||
1229 | |||
1230 | if (smtc_status & SMTC_TLB_SHARED) | ||
1231 | evpe(mtflags); | ||
1232 | else | ||
1233 | emt(mtflags); | ||
1234 | local_irq_restore(flags); | ||
1235 | } | ||
1236 | |||
1237 | /* | ||
1238 | * Invoked from macros defined in mmu_context.h | ||
1239 | * which must already have disabled interrupts | ||
1240 | * and done a DVPE or DMT as appropriate. | ||
1241 | */ | ||
1242 | |||
1243 | void smtc_flush_tlb_asid(unsigned long asid) | ||
1244 | { | ||
1245 | int entry; | ||
1246 | unsigned long ehi; | ||
1247 | |||
1248 | entry = read_c0_wired(); | ||
1249 | |||
1250 | /* Traverse all non-wired entries */ | ||
1251 | while (entry < current_cpu_data.tlbsize) { | ||
1252 | write_c0_index(entry); | ||
1253 | ehb(); | ||
1254 | tlb_read(); | ||
1255 | ehb(); | ||
1256 | ehi = read_c0_entryhi(); | ||
1257 | if((ehi & ASID_MASK) == asid) { | ||
1258 | /* | ||
1259 | * Invalidate only entries with specified ASID, | ||
1260 | * makiing sure all entries differ. | ||
1261 | */ | ||
1262 | write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1))); | ||
1263 | write_c0_entrylo0(0); | ||
1264 | write_c0_entrylo1(0); | ||
1265 | mtc0_tlbw_hazard(); | ||
1266 | tlb_write_indexed(); | ||
1267 | } | ||
1268 | entry++; | ||
1269 | } | ||
1270 | write_c0_index(PARKED_INDEX); | ||
1271 | tlbw_use_hazard(); | ||
1272 | } | ||
1273 | |||
1274 | /* | ||
1275 | * Support for single-threading cache flush operations. | ||
1276 | */ | ||
1277 | |||
1278 | int halt_state_save[NR_CPUS]; | ||
1279 | |||
1280 | /* | ||
1281 | * To really, really be sure that nothing is being done | ||
1282 | * by other TCs, halt them all. This code assumes that | ||
1283 | * a DVPE has already been done, so while their Halted | ||
1284 | * state is theoretically architecturally unstable, in | ||
1285 | * practice, it's not going to change while we're looking | ||
1286 | * at it. | ||
1287 | */ | ||
1288 | |||
1289 | void smtc_cflush_lockdown(void) | ||
1290 | { | ||
1291 | int cpu; | ||
1292 | |||
1293 | for_each_online_cpu(cpu) { | ||
1294 | if (cpu != smp_processor_id()) { | ||
1295 | settc(cpu_data[cpu].tc_id); | ||
1296 | halt_state_save[cpu] = read_tc_c0_tchalt(); | ||
1297 | write_tc_c0_tchalt(TCHALT_H); | ||
1298 | } | ||
1299 | } | ||
1300 | mips_ihb(); | ||
1301 | } | ||
1302 | |||
1303 | /* It would be cheating to change the cpu_online states during a flush! */ | ||
1304 | |||
1305 | void smtc_cflush_release(void) | ||
1306 | { | ||
1307 | int cpu; | ||
1308 | |||
1309 | /* | ||
1310 | * Start with a hazard barrier to ensure | ||
1311 | * that all CACHE ops have played through. | ||
1312 | */ | ||
1313 | mips_ihb(); | ||
1314 | |||
1315 | for_each_online_cpu(cpu) { | ||
1316 | if (cpu != smp_processor_id()) { | ||
1317 | settc(cpu_data[cpu].tc_id); | ||
1318 | write_tc_c0_tchalt(halt_state_save[cpu]); | ||
1319 | } | ||
1320 | } | ||
1321 | mips_ihb(); | ||
1322 | } | ||
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 5e51a2d8f3f0..13ff4da598cd 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c | |||
@@ -116,8 +116,7 @@ static void c0_timer_ack(void) | |||
116 | write_c0_compare(expirelo); | 116 | write_c0_compare(expirelo); |
117 | 117 | ||
118 | /* Check to see if we have missed any timer interrupts. */ | 118 | /* Check to see if we have missed any timer interrupts. */ |
119 | count = read_c0_count(); | 119 | while (((count = read_c0_count()) - expirelo) < 0x7fffffff) { |
120 | if ((count - expirelo) < 0x7fffffff) { | ||
121 | /* missed_timer_count++; */ | 120 | /* missed_timer_count++; */ |
122 | expirelo = count + cycles_per_jiffy; | 121 | expirelo = count + cycles_per_jiffy; |
123 | write_c0_compare(expirelo); | 122 | write_c0_compare(expirelo); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index bed0eb6cf55d..4901f0a37fca 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <asm/watch.h> | 42 | #include <asm/watch.h> |
43 | #include <asm/types.h> | 43 | #include <asm/types.h> |
44 | 44 | ||
45 | extern asmlinkage void handle_int(void); | ||
45 | extern asmlinkage void handle_tlbm(void); | 46 | extern asmlinkage void handle_tlbm(void); |
46 | extern asmlinkage void handle_tlbl(void); | 47 | extern asmlinkage void handle_tlbl(void); |
47 | extern asmlinkage void handle_tlbs(void); | 48 | extern asmlinkage void handle_tlbs(void); |
@@ -279,9 +280,16 @@ static DEFINE_SPINLOCK(die_lock); | |||
279 | NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs) | 280 | NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs) |
280 | { | 281 | { |
281 | static int die_counter; | 282 | static int die_counter; |
283 | #ifdef CONFIG_MIPS_MT_SMTC | ||
284 | unsigned long dvpret = dvpe(); | ||
285 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
282 | 286 | ||
283 | console_verbose(); | 287 | console_verbose(); |
284 | spin_lock_irq(&die_lock); | 288 | spin_lock_irq(&die_lock); |
289 | bust_spinlocks(1); | ||
290 | #ifdef CONFIG_MIPS_MT_SMTC | ||
291 | mips_mt_regdump(dvpret); | ||
292 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
285 | printk("%s[#%d]:\n", str, ++die_counter); | 293 | printk("%s[#%d]:\n", str, ++die_counter); |
286 | show_registers(regs); | 294 | show_registers(regs); |
287 | spin_unlock_irq(&die_lock); | 295 | spin_unlock_irq(&die_lock); |
@@ -750,12 +758,43 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
750 | ¤t->thread.fpu.soft); | 758 | ¤t->thread.fpu.soft); |
751 | if (sig) | 759 | if (sig) |
752 | force_sig(sig, current); | 760 | force_sig(sig, current); |
761 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
762 | else { | ||
763 | /* | ||
764 | * MIPS MT processors may have fewer FPU contexts | ||
765 | * than CPU threads. If we've emulated more than | ||
766 | * some threshold number of instructions, force | ||
767 | * migration to a "CPU" that has FP support. | ||
768 | */ | ||
769 | if(mt_fpemul_threshold > 0 | ||
770 | && ((current->thread.emulated_fp++ | ||
771 | > mt_fpemul_threshold))) { | ||
772 | /* | ||
773 | * If there's no FPU present, or if the | ||
774 | * application has already restricted | ||
775 | * the allowed set to exclude any CPUs | ||
776 | * with FPUs, we'll skip the procedure. | ||
777 | */ | ||
778 | if (cpus_intersects(current->cpus_allowed, | ||
779 | mt_fpu_cpumask)) { | ||
780 | cpumask_t tmask; | ||
781 | |||
782 | cpus_and(tmask, | ||
783 | current->thread.user_cpus_allowed, | ||
784 | mt_fpu_cpumask); | ||
785 | set_cpus_allowed(current, tmask); | ||
786 | current->thread.mflags |= MF_FPUBOUND; | ||
787 | } | ||
788 | } | ||
789 | } | ||
790 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
753 | } | 791 | } |
754 | 792 | ||
755 | return; | 793 | return; |
756 | 794 | ||
757 | case 2: | 795 | case 2: |
758 | case 3: | 796 | case 3: |
797 | die_if_kernel("do_cpu invoked from kernel context!", regs); | ||
759 | break; | 798 | break; |
760 | } | 799 | } |
761 | 800 | ||
@@ -793,6 +832,36 @@ asmlinkage void do_mcheck(struct pt_regs *regs) | |||
793 | 832 | ||
794 | asmlinkage void do_mt(struct pt_regs *regs) | 833 | asmlinkage void do_mt(struct pt_regs *regs) |
795 | { | 834 | { |
835 | int subcode; | ||
836 | |||
837 | die_if_kernel("MIPS MT Thread exception in kernel", regs); | ||
838 | |||
839 | subcode = (read_vpe_c0_vpecontrol() & VPECONTROL_EXCPT) | ||
840 | >> VPECONTROL_EXCPT_SHIFT; | ||
841 | switch (subcode) { | ||
842 | case 0: | ||
843 | printk(KERN_ERR "Thread Underflow\n"); | ||
844 | break; | ||
845 | case 1: | ||
846 | printk(KERN_ERR "Thread Overflow\n"); | ||
847 | break; | ||
848 | case 2: | ||
849 | printk(KERN_ERR "Invalid YIELD Qualifier\n"); | ||
850 | break; | ||
851 | case 3: | ||
852 | printk(KERN_ERR "Gating Storage Exception\n"); | ||
853 | break; | ||
854 | case 4: | ||
855 | printk(KERN_ERR "YIELD Scheduler Exception\n"); | ||
856 | break; | ||
857 | case 5: | ||
858 | printk(KERN_ERR "Gating Storage Schedulier Exception\n"); | ||
859 | break; | ||
860 | default: | ||
861 | printk(KERN_ERR "*** UNKNOWN THREAD EXCEPTION %d ***\n", | ||
862 | subcode); | ||
863 | break; | ||
864 | } | ||
796 | die_if_kernel("MIPS MT Thread exception in kernel", regs); | 865 | die_if_kernel("MIPS MT Thread exception in kernel", regs); |
797 | 866 | ||
798 | force_sig(SIGILL, current); | 867 | force_sig(SIGILL, current); |
@@ -928,7 +997,15 @@ void ejtag_exception_handler(struct pt_regs *regs) | |||
928 | */ | 997 | */ |
929 | void nmi_exception_handler(struct pt_regs *regs) | 998 | void nmi_exception_handler(struct pt_regs *regs) |
930 | { | 999 | { |
1000 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1001 | unsigned long dvpret = dvpe(); | ||
1002 | bust_spinlocks(1); | ||
1003 | printk("NMI taken!!!!\n"); | ||
1004 | mips_mt_regdump(dvpret); | ||
1005 | #else | ||
1006 | bust_spinlocks(1); | ||
931 | printk("NMI taken!!!!\n"); | 1007 | printk("NMI taken!!!!\n"); |
1008 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
932 | die("NMI", regs); | 1009 | die("NMI", regs); |
933 | while(1) ; | 1010 | while(1) ; |
934 | } | 1011 | } |
@@ -960,27 +1037,29 @@ void *set_except_vector(int n, void *addr) | |||
960 | 1037 | ||
961 | #ifdef CONFIG_CPU_MIPSR2 | 1038 | #ifdef CONFIG_CPU_MIPSR2 |
962 | /* | 1039 | /* |
963 | * Shadow register allocation | 1040 | * MIPSR2 shadow register set allocation |
964 | * FIXME: SMP... | 1041 | * FIXME: SMP... |
965 | */ | 1042 | */ |
966 | 1043 | ||
967 | /* MIPSR2 shadow register sets */ | 1044 | static struct shadow_registers { |
968 | struct shadow_registers { | 1045 | /* |
969 | spinlock_t sr_lock; /* */ | 1046 | * Number of shadow register sets supported |
970 | int sr_supported; /* Number of shadow register sets supported */ | 1047 | */ |
971 | int sr_allocated; /* Bitmap of allocated shadow registers */ | 1048 | unsigned long sr_supported; |
1049 | /* | ||
1050 | * Bitmap of allocated shadow registers | ||
1051 | */ | ||
1052 | unsigned long sr_allocated; | ||
972 | } shadow_registers; | 1053 | } shadow_registers; |
973 | 1054 | ||
974 | void mips_srs_init(void) | 1055 | static void mips_srs_init(void) |
975 | { | 1056 | { |
976 | #ifdef CONFIG_CPU_MIPSR2_SRS | 1057 | #ifdef CONFIG_CPU_MIPSR2_SRS |
977 | shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; | 1058 | shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; |
978 | printk ("%d MIPSR2 register sets available\n", shadow_registers.sr_supported); | 1059 | printk(KERN_INFO "%d MIPSR2 register sets available\n", |
979 | #else | 1060 | shadow_registers.sr_supported); |
980 | shadow_registers.sr_supported = 1; | ||
981 | #endif | 1061 | #endif |
982 | shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ | 1062 | shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ |
983 | spin_lock_init(&shadow_registers.sr_lock); | ||
984 | } | 1063 | } |
985 | 1064 | ||
986 | int mips_srs_max(void) | 1065 | int mips_srs_max(void) |
@@ -988,38 +1067,30 @@ int mips_srs_max(void) | |||
988 | return shadow_registers.sr_supported; | 1067 | return shadow_registers.sr_supported; |
989 | } | 1068 | } |
990 | 1069 | ||
991 | int mips_srs_alloc (void) | 1070 | int mips_srs_alloc(void) |
992 | { | 1071 | { |
993 | struct shadow_registers *sr = &shadow_registers; | 1072 | struct shadow_registers *sr = &shadow_registers; |
994 | unsigned long flags; | ||
995 | int set; | 1073 | int set; |
996 | 1074 | ||
997 | spin_lock_irqsave(&sr->sr_lock, flags); | 1075 | again: |
1076 | set = find_first_zero_bit(&sr->sr_allocated, sr->sr_supported); | ||
1077 | if (set >= sr->sr_supported) | ||
1078 | return -1; | ||
998 | 1079 | ||
999 | for (set = 0; set < sr->sr_supported; set++) { | 1080 | if (test_and_set_bit(set, &sr->sr_allocated)) |
1000 | if ((sr->sr_allocated & (1 << set)) == 0) { | 1081 | goto again; |
1001 | sr->sr_allocated |= 1 << set; | ||
1002 | spin_unlock_irqrestore(&sr->sr_lock, flags); | ||
1003 | return set; | ||
1004 | } | ||
1005 | } | ||
1006 | 1082 | ||
1007 | /* None available */ | 1083 | return set; |
1008 | spin_unlock_irqrestore(&sr->sr_lock, flags); | ||
1009 | return -1; | ||
1010 | } | 1084 | } |
1011 | 1085 | ||
1012 | void mips_srs_free (int set) | 1086 | void mips_srs_free(int set) |
1013 | { | 1087 | { |
1014 | struct shadow_registers *sr = &shadow_registers; | 1088 | struct shadow_registers *sr = &shadow_registers; |
1015 | unsigned long flags; | ||
1016 | 1089 | ||
1017 | spin_lock_irqsave(&sr->sr_lock, flags); | 1090 | clear_bit(set, &sr->sr_allocated); |
1018 | sr->sr_allocated &= ~(1 << set); | ||
1019 | spin_unlock_irqrestore(&sr->sr_lock, flags); | ||
1020 | } | 1091 | } |
1021 | 1092 | ||
1022 | void *set_vi_srs_handler (int n, void *addr, int srs) | 1093 | static void *set_vi_srs_handler(int n, void *addr, int srs) |
1023 | { | 1094 | { |
1024 | unsigned long handler; | 1095 | unsigned long handler; |
1025 | unsigned long old_handler = vi_handlers[n]; | 1096 | unsigned long old_handler = vi_handlers[n]; |
@@ -1032,8 +1103,7 @@ void *set_vi_srs_handler (int n, void *addr, int srs) | |||
1032 | if (addr == NULL) { | 1103 | if (addr == NULL) { |
1033 | handler = (unsigned long) do_default_vi; | 1104 | handler = (unsigned long) do_default_vi; |
1034 | srs = 0; | 1105 | srs = 0; |
1035 | } | 1106 | } else |
1036 | else | ||
1037 | handler = (unsigned long) addr; | 1107 | handler = (unsigned long) addr; |
1038 | vi_handlers[n] = (unsigned long) addr; | 1108 | vi_handlers[n] = (unsigned long) addr; |
1039 | 1109 | ||
@@ -1045,8 +1115,7 @@ void *set_vi_srs_handler (int n, void *addr, int srs) | |||
1045 | if (cpu_has_veic) { | 1115 | if (cpu_has_veic) { |
1046 | if (board_bind_eic_interrupt) | 1116 | if (board_bind_eic_interrupt) |
1047 | board_bind_eic_interrupt (n, srs); | 1117 | board_bind_eic_interrupt (n, srs); |
1048 | } | 1118 | } else if (cpu_has_vint) { |
1049 | else if (cpu_has_vint) { | ||
1050 | /* SRSMap is only defined if shadow sets are implemented */ | 1119 | /* SRSMap is only defined if shadow sets are implemented */ |
1051 | if (mips_srs_max() > 1) | 1120 | if (mips_srs_max() > 1) |
1052 | change_c0_srsmap (0xf << n*4, srs << n*4); | 1121 | change_c0_srsmap (0xf << n*4, srs << n*4); |
@@ -1060,6 +1129,15 @@ void *set_vi_srs_handler (int n, void *addr, int srs) | |||
1060 | 1129 | ||
1061 | extern char except_vec_vi, except_vec_vi_lui; | 1130 | extern char except_vec_vi, except_vec_vi_lui; |
1062 | extern char except_vec_vi_ori, except_vec_vi_end; | 1131 | extern char except_vec_vi_ori, except_vec_vi_end; |
1132 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1133 | /* | ||
1134 | * We need to provide the SMTC vectored interrupt handler | ||
1135 | * not only with the address of the handler, but with the | ||
1136 | * Status.IM bit to be masked before going there. | ||
1137 | */ | ||
1138 | extern char except_vec_vi_mori; | ||
1139 | const int mori_offset = &except_vec_vi_mori - &except_vec_vi; | ||
1140 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1063 | const int handler_len = &except_vec_vi_end - &except_vec_vi; | 1141 | const int handler_len = &except_vec_vi_end - &except_vec_vi; |
1064 | const int lui_offset = &except_vec_vi_lui - &except_vec_vi; | 1142 | const int lui_offset = &except_vec_vi_lui - &except_vec_vi; |
1065 | const int ori_offset = &except_vec_vi_ori - &except_vec_vi; | 1143 | const int ori_offset = &except_vec_vi_ori - &except_vec_vi; |
@@ -1073,6 +1151,12 @@ void *set_vi_srs_handler (int n, void *addr, int srs) | |||
1073 | } | 1151 | } |
1074 | 1152 | ||
1075 | memcpy (b, &except_vec_vi, handler_len); | 1153 | memcpy (b, &except_vec_vi, handler_len); |
1154 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1155 | if (n > 7) | ||
1156 | printk("Vector index %d exceeds SMTC maximum\n", n); | ||
1157 | w = (u32 *)(b + mori_offset); | ||
1158 | *w = (*w & 0xffff0000) | (0x100 << n); | ||
1159 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1076 | w = (u32 *)(b + lui_offset); | 1160 | w = (u32 *)(b + lui_offset); |
1077 | *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff); | 1161 | *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff); |
1078 | w = (u32 *)(b + ori_offset); | 1162 | w = (u32 *)(b + ori_offset); |
@@ -1095,9 +1179,9 @@ void *set_vi_srs_handler (int n, void *addr, int srs) | |||
1095 | return (void *)old_handler; | 1179 | return (void *)old_handler; |
1096 | } | 1180 | } |
1097 | 1181 | ||
1098 | void *set_vi_handler (int n, void *addr) | 1182 | void *set_vi_handler(int n, void *addr) |
1099 | { | 1183 | { |
1100 | return set_vi_srs_handler (n, addr, 0); | 1184 | return set_vi_srs_handler(n, addr, 0); |
1101 | } | 1185 | } |
1102 | #endif | 1186 | #endif |
1103 | 1187 | ||
@@ -1113,8 +1197,29 @@ extern asmlinkage int _restore_fp_context(struct sigcontext *sc); | |||
1113 | extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); | 1197 | extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); |
1114 | extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); | 1198 | extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); |
1115 | 1199 | ||
1200 | #ifdef CONFIG_SMP | ||
1201 | static int smp_save_fp_context(struct sigcontext *sc) | ||
1202 | { | ||
1203 | return cpu_has_fpu | ||
1204 | ? _save_fp_context(sc) | ||
1205 | : fpu_emulator_save_context(sc); | ||
1206 | } | ||
1207 | |||
1208 | static int smp_restore_fp_context(struct sigcontext *sc) | ||
1209 | { | ||
1210 | return cpu_has_fpu | ||
1211 | ? _restore_fp_context(sc) | ||
1212 | : fpu_emulator_restore_context(sc); | ||
1213 | } | ||
1214 | #endif | ||
1215 | |||
1116 | static inline void signal_init(void) | 1216 | static inline void signal_init(void) |
1117 | { | 1217 | { |
1218 | #ifdef CONFIG_SMP | ||
1219 | /* For now just do the cpu_has_fpu check when the functions are invoked */ | ||
1220 | save_fp_context = smp_save_fp_context; | ||
1221 | restore_fp_context = smp_restore_fp_context; | ||
1222 | #else | ||
1118 | if (cpu_has_fpu) { | 1223 | if (cpu_has_fpu) { |
1119 | save_fp_context = _save_fp_context; | 1224 | save_fp_context = _save_fp_context; |
1120 | restore_fp_context = _restore_fp_context; | 1225 | restore_fp_context = _restore_fp_context; |
@@ -1122,6 +1227,7 @@ static inline void signal_init(void) | |||
1122 | save_fp_context = fpu_emulator_save_context; | 1227 | save_fp_context = fpu_emulator_save_context; |
1123 | restore_fp_context = fpu_emulator_restore_context; | 1228 | restore_fp_context = fpu_emulator_restore_context; |
1124 | } | 1229 | } |
1230 | #endif | ||
1125 | } | 1231 | } |
1126 | 1232 | ||
1127 | #ifdef CONFIG_MIPS32_COMPAT | 1233 | #ifdef CONFIG_MIPS32_COMPAT |
@@ -1158,6 +1264,20 @@ void __init per_cpu_trap_init(void) | |||
1158 | { | 1264 | { |
1159 | unsigned int cpu = smp_processor_id(); | 1265 | unsigned int cpu = smp_processor_id(); |
1160 | unsigned int status_set = ST0_CU0; | 1266 | unsigned int status_set = ST0_CU0; |
1267 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1268 | int secondaryTC = 0; | ||
1269 | int bootTC = (cpu == 0); | ||
1270 | |||
1271 | /* | ||
1272 | * Only do per_cpu_trap_init() for first TC of Each VPE. | ||
1273 | * Note that this hack assumes that the SMTC init code | ||
1274 | * assigns TCs consecutively and in ascending order. | ||
1275 | */ | ||
1276 | |||
1277 | if (((read_c0_tcbind() & TCBIND_CURTC) != 0) && | ||
1278 | ((read_c0_tcbind() & TCBIND_CURVPE) == cpu_data[cpu - 1].vpe_id)) | ||
1279 | secondaryTC = 1; | ||
1280 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1161 | 1281 | ||
1162 | /* | 1282 | /* |
1163 | * Disable coprocessors and select 32-bit or 64-bit addressing | 1283 | * Disable coprocessors and select 32-bit or 64-bit addressing |
@@ -1180,6 +1300,10 @@ void __init per_cpu_trap_init(void) | |||
1180 | write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */ | 1300 | write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */ |
1181 | #endif | 1301 | #endif |
1182 | 1302 | ||
1303 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1304 | if (!secondaryTC) { | ||
1305 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1306 | |||
1183 | /* | 1307 | /* |
1184 | * Interrupt handling. | 1308 | * Interrupt handling. |
1185 | */ | 1309 | */ |
@@ -1196,6 +1320,9 @@ void __init per_cpu_trap_init(void) | |||
1196 | } else | 1320 | } else |
1197 | set_c0_cause(CAUSEF_IV); | 1321 | set_c0_cause(CAUSEF_IV); |
1198 | } | 1322 | } |
1323 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1324 | } | ||
1325 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1199 | 1326 | ||
1200 | cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; | 1327 | cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; |
1201 | TLBMISS_HANDLER_SETUP(); | 1328 | TLBMISS_HANDLER_SETUP(); |
@@ -1205,8 +1332,14 @@ void __init per_cpu_trap_init(void) | |||
1205 | BUG_ON(current->mm); | 1332 | BUG_ON(current->mm); |
1206 | enter_lazy_tlb(&init_mm, current); | 1333 | enter_lazy_tlb(&init_mm, current); |
1207 | 1334 | ||
1208 | cpu_cache_init(); | 1335 | #ifdef CONFIG_MIPS_MT_SMTC |
1209 | tlb_init(); | 1336 | if (bootTC) { |
1337 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1338 | cpu_cache_init(); | ||
1339 | tlb_init(); | ||
1340 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1341 | } | ||
1342 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1210 | } | 1343 | } |
1211 | 1344 | ||
1212 | /* Install CPU exception handler */ | 1345 | /* Install CPU exception handler */ |
@@ -1278,7 +1411,7 @@ void __init trap_init(void) | |||
1278 | if (cpu_has_veic || cpu_has_vint) { | 1411 | if (cpu_has_veic || cpu_has_vint) { |
1279 | int nvec = cpu_has_veic ? 64 : 8; | 1412 | int nvec = cpu_has_veic ? 64 : 8; |
1280 | for (i = 0; i < nvec; i++) | 1413 | for (i = 0; i < nvec; i++) |
1281 | set_vi_handler (i, NULL); | 1414 | set_vi_handler(i, NULL); |
1282 | } | 1415 | } |
1283 | else if (cpu_has_divec) | 1416 | else if (cpu_has_divec) |
1284 | set_handler(0x200, &except_vec4, 0x8); | 1417 | set_handler(0x200, &except_vec4, 0x8); |
@@ -1297,6 +1430,7 @@ void __init trap_init(void) | |||
1297 | if (board_be_init) | 1430 | if (board_be_init) |
1298 | board_be_init(); | 1431 | board_be_init(); |
1299 | 1432 | ||
1433 | set_except_vector(0, handle_int); | ||
1300 | set_except_vector(1, handle_tlbm); | 1434 | set_except_vector(1, handle_tlbm); |
1301 | set_except_vector(2, handle_tlbl); | 1435 | set_except_vector(2, handle_tlbl); |
1302 | set_except_vector(3, handle_tlbs); | 1436 | set_except_vector(3, handle_tlbs); |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 2ad0cedf29fe..14fa00e3cdfa 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
@@ -2,7 +2,7 @@ | |||
2 | #include <asm/asm-offsets.h> | 2 | #include <asm/asm-offsets.h> |
3 | #include <asm-generic/vmlinux.lds.h> | 3 | #include <asm-generic/vmlinux.lds.h> |
4 | 4 | ||
5 | #undef mips /* CPP really sucks for this job */ | 5 | #undef mips |
6 | #define mips mips | 6 | #define mips mips |
7 | OUTPUT_ARCH(mips) | 7 | OUTPUT_ARCH(mips) |
8 | ENTRY(kernel_entry) | 8 | ENTRY(kernel_entry) |
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index ae83b755cf4a..80ffaa6d50ad 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -13,7 +13,6 @@ | |||
13 | * You should have received a copy of the GNU General Public License along | 13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., | 14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
16 | * | ||
17 | */ | 16 | */ |
18 | 17 | ||
19 | /* | 18 | /* |
@@ -27,11 +26,8 @@ | |||
27 | * | 26 | * |
28 | * To load and run, simply cat a SP 'program file' to /dev/vpe1. | 27 | * To load and run, simply cat a SP 'program file' to /dev/vpe1. |
29 | * i.e cat spapp >/dev/vpe1. | 28 | * i.e cat spapp >/dev/vpe1. |
30 | * | ||
31 | * You'll need to have the following device files. | ||
32 | * mknod /dev/vpe0 c 63 0 | ||
33 | * mknod /dev/vpe1 c 63 1 | ||
34 | */ | 29 | */ |
30 | |||
35 | #include <linux/config.h> | 31 | #include <linux/config.h> |
36 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 33 | #include <linux/module.h> |
@@ -55,6 +51,8 @@ | |||
55 | #include <asm/cpu.h> | 51 | #include <asm/cpu.h> |
56 | #include <asm/processor.h> | 52 | #include <asm/processor.h> |
57 | #include <asm/system.h> | 53 | #include <asm/system.h> |
54 | #include <asm/vpe.h> | ||
55 | #include <asm/kspd.h> | ||
58 | 56 | ||
59 | typedef void *vpe_handle; | 57 | typedef void *vpe_handle; |
60 | 58 | ||
@@ -68,6 +66,11 @@ typedef void *vpe_handle; | |||
68 | static char module_name[] = "vpe"; | 66 | static char module_name[] = "vpe"; |
69 | static int major; | 67 | static int major; |
70 | 68 | ||
69 | #ifdef CONFIG_MIPS_APSP_KSPD | ||
70 | static struct kspd_notifications kspd_events; | ||
71 | static int kspd_events_reqd = 0; | ||
72 | #endif | ||
73 | |||
71 | /* grab the likely amount of memory we will need. */ | 74 | /* grab the likely amount of memory we will need. */ |
72 | #ifdef CONFIG_MIPS_VPE_LOADER_TOM | 75 | #ifdef CONFIG_MIPS_VPE_LOADER_TOM |
73 | #define P_SIZE (2 * 1024 * 1024) | 76 | #define P_SIZE (2 * 1024 * 1024) |
@@ -76,7 +79,10 @@ static int major; | |||
76 | #define P_SIZE (256 * 1024) | 79 | #define P_SIZE (256 * 1024) |
77 | #endif | 80 | #endif |
78 | 81 | ||
82 | extern unsigned long physical_memsize; | ||
83 | |||
79 | #define MAX_VPES 16 | 84 | #define MAX_VPES 16 |
85 | #define VPE_PATH_MAX 256 | ||
80 | 86 | ||
81 | enum vpe_state { | 87 | enum vpe_state { |
82 | VPE_STATE_UNUSED = 0, | 88 | VPE_STATE_UNUSED = 0, |
@@ -102,6 +108,8 @@ struct vpe { | |||
102 | unsigned long len; | 108 | unsigned long len; |
103 | char *pbuffer; | 109 | char *pbuffer; |
104 | unsigned long plen; | 110 | unsigned long plen; |
111 | unsigned int uid, gid; | ||
112 | char cwd[VPE_PATH_MAX]; | ||
105 | 113 | ||
106 | unsigned long __start; | 114 | unsigned long __start; |
107 | 115 | ||
@@ -113,6 +121,9 @@ struct vpe { | |||
113 | 121 | ||
114 | /* shared symbol address */ | 122 | /* shared symbol address */ |
115 | void *shared_ptr; | 123 | void *shared_ptr; |
124 | |||
125 | /* the list of who wants to know when something major happens */ | ||
126 | struct list_head notify; | ||
116 | }; | 127 | }; |
117 | 128 | ||
118 | struct tc { | 129 | struct tc { |
@@ -138,7 +149,7 @@ struct vpecontrol_ { | |||
138 | } vpecontrol; | 149 | } vpecontrol; |
139 | 150 | ||
140 | static void release_progmem(void *ptr); | 151 | static void release_progmem(void *ptr); |
141 | static void dump_vpe(struct vpe * v); | 152 | /* static __attribute_used__ void dump_vpe(struct vpe * v); */ |
142 | extern void save_gp_address(unsigned int secbase, unsigned int rel); | 153 | extern void save_gp_address(unsigned int secbase, unsigned int rel); |
143 | 154 | ||
144 | /* get the vpe associated with this minor */ | 155 | /* get the vpe associated with this minor */ |
@@ -146,12 +157,14 @@ struct vpe *get_vpe(int minor) | |||
146 | { | 157 | { |
147 | struct vpe *v; | 158 | struct vpe *v; |
148 | 159 | ||
160 | if (!cpu_has_mipsmt) | ||
161 | return NULL; | ||
162 | |||
149 | list_for_each_entry(v, &vpecontrol.vpe_list, list) { | 163 | list_for_each_entry(v, &vpecontrol.vpe_list, list) { |
150 | if (v->minor == minor) | 164 | if (v->minor == minor) |
151 | return v; | 165 | return v; |
152 | } | 166 | } |
153 | 167 | ||
154 | printk(KERN_DEBUG "VPE: get_vpe minor %d not found\n", minor); | ||
155 | return NULL; | 168 | return NULL; |
156 | } | 169 | } |
157 | 170 | ||
@@ -165,8 +178,6 @@ struct tc *get_tc(int index) | |||
165 | return t; | 178 | return t; |
166 | } | 179 | } |
167 | 180 | ||
168 | printk(KERN_DEBUG "VPE: get_tc index %d not found\n", index); | ||
169 | |||
170 | return NULL; | 181 | return NULL; |
171 | } | 182 | } |
172 | 183 | ||
@@ -179,8 +190,6 @@ struct tc *get_tc_unused(void) | |||
179 | return t; | 190 | return t; |
180 | } | 191 | } |
181 | 192 | ||
182 | printk(KERN_DEBUG "VPE: All TC's are in use\n"); | ||
183 | |||
184 | return NULL; | 193 | return NULL; |
185 | } | 194 | } |
186 | 195 | ||
@@ -190,13 +199,13 @@ struct vpe *alloc_vpe(int minor) | |||
190 | struct vpe *v; | 199 | struct vpe *v; |
191 | 200 | ||
192 | if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { | 201 | if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { |
193 | printk(KERN_WARNING "VPE: alloc_vpe no mem\n"); | ||
194 | return NULL; | 202 | return NULL; |
195 | } | 203 | } |
196 | 204 | ||
197 | INIT_LIST_HEAD(&v->tc); | 205 | INIT_LIST_HEAD(&v->tc); |
198 | list_add_tail(&v->list, &vpecontrol.vpe_list); | 206 | list_add_tail(&v->list, &vpecontrol.vpe_list); |
199 | 207 | ||
208 | INIT_LIST_HEAD(&v->notify); | ||
200 | v->minor = minor; | 209 | v->minor = minor; |
201 | return v; | 210 | return v; |
202 | } | 211 | } |
@@ -207,7 +216,6 @@ struct tc *alloc_tc(int index) | |||
207 | struct tc *t; | 216 | struct tc *t; |
208 | 217 | ||
209 | if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) { | 218 | if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) { |
210 | printk(KERN_WARNING "VPE: alloc_tc no mem\n"); | ||
211 | return NULL; | 219 | return NULL; |
212 | } | 220 | } |
213 | 221 | ||
@@ -236,20 +244,16 @@ void dump_mtregs(void) | |||
236 | printk("config3 0x%lx MT %ld\n", val, | 244 | printk("config3 0x%lx MT %ld\n", val, |
237 | (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT); | 245 | (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT); |
238 | 246 | ||
239 | val = read_c0_mvpconf0(); | ||
240 | printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val, | ||
241 | (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT, | ||
242 | val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT); | ||
243 | |||
244 | val = read_c0_mvpcontrol(); | 247 | val = read_c0_mvpcontrol(); |
245 | printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val, | 248 | printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val, |
246 | (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT, | 249 | (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT, |
247 | (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT, | 250 | (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT, |
248 | (val & MVPCONTROL_EVP)); | 251 | (val & MVPCONTROL_EVP)); |
249 | 252 | ||
250 | val = read_c0_vpeconf0(); | 253 | val = read_c0_mvpconf0(); |
251 | printk("VPEConf0 0x%lx MVP %ld\n", val, | 254 | printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val, |
252 | (val & VPECONF0_MVP) >> VPECONF0_MVP_SHIFT); | 255 | (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT, |
256 | val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT); | ||
253 | } | 257 | } |
254 | 258 | ||
255 | /* Find some VPE program space */ | 259 | /* Find some VPE program space */ |
@@ -354,9 +358,9 @@ static int apply_r_mips_gprel16(struct module *me, uint32_t *location, | |||
354 | } | 358 | } |
355 | 359 | ||
356 | if( (rel > 32768) || (rel < -32768) ) { | 360 | if( (rel > 32768) || (rel < -32768) ) { |
357 | printk(KERN_ERR | 361 | printk(KERN_DEBUG "VPE loader: apply_r_mips_gprel16: " |
358 | "apply_r_mips_gprel16: relative address out of range 0x%x %d\n", | 362 | "relative address 0x%x out of range of gp register\n", |
359 | rel, rel); | 363 | rel); |
360 | return -ENOEXEC; | 364 | return -ENOEXEC; |
361 | } | 365 | } |
362 | 366 | ||
@@ -374,8 +378,8 @@ static int apply_r_mips_pc16(struct module *me, uint32_t *location, | |||
374 | rel -= 1; // and one instruction less due to the branch delay slot. | 378 | rel -= 1; // and one instruction less due to the branch delay slot. |
375 | 379 | ||
376 | if( (rel > 32768) || (rel < -32768) ) { | 380 | if( (rel > 32768) || (rel < -32768) ) { |
377 | printk(KERN_ERR | 381 | printk(KERN_DEBUG "VPE loader: " |
378 | "apply_r_mips_pc16: relative address out of range 0x%x\n", rel); | 382 | "apply_r_mips_pc16: relative address out of range 0x%x\n", rel); |
379 | return -ENOEXEC; | 383 | return -ENOEXEC; |
380 | } | 384 | } |
381 | 385 | ||
@@ -396,7 +400,8 @@ static int apply_r_mips_26(struct module *me, uint32_t *location, | |||
396 | Elf32_Addr v) | 400 | Elf32_Addr v) |
397 | { | 401 | { |
398 | if (v % 4) { | 402 | if (v % 4) { |
399 | printk(KERN_ERR "module %s: dangerous relocation mod4\n", me->name); | 403 | printk(KERN_DEBUG "VPE loader: apply_r_mips_26 " |
404 | " unaligned relocation\n"); | ||
400 | return -ENOEXEC; | 405 | return -ENOEXEC; |
401 | } | 406 | } |
402 | 407 | ||
@@ -459,12 +464,13 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, | |||
459 | /* | 464 | /* |
460 | * The value for the HI16 had best be the same. | 465 | * The value for the HI16 had best be the same. |
461 | */ | 466 | */ |
462 | if (v != l->value) { | 467 | if (v != l->value) { |
463 | printk("%d != %d\n", v, l->value); | 468 | printk(KERN_DEBUG "VPE loader: " |
464 | goto out_danger; | 469 | "apply_r_mips_lo16/hi16: " |
470 | "inconsistent value information\n"); | ||
471 | return -ENOEXEC; | ||
465 | } | 472 | } |
466 | 473 | ||
467 | |||
468 | /* | 474 | /* |
469 | * Do the HI16 relocation. Note that we actually don't | 475 | * Do the HI16 relocation. Note that we actually don't |
470 | * need to know anything about the LO16 itself, except | 476 | * need to know anything about the LO16 itself, except |
@@ -500,11 +506,6 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, | |||
500 | *location = insnlo; | 506 | *location = insnlo; |
501 | 507 | ||
502 | return 0; | 508 | return 0; |
503 | |||
504 | out_danger: | ||
505 | printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name); | ||
506 | |||
507 | return -ENOEXEC; | ||
508 | } | 509 | } |
509 | 510 | ||
510 | static int (*reloc_handlers[]) (struct module *me, uint32_t *location, | 511 | static int (*reloc_handlers[]) (struct module *me, uint32_t *location, |
@@ -518,6 +519,15 @@ static int (*reloc_handlers[]) (struct module *me, uint32_t *location, | |||
518 | [R_MIPS_PC16] = apply_r_mips_pc16 | 519 | [R_MIPS_PC16] = apply_r_mips_pc16 |
519 | }; | 520 | }; |
520 | 521 | ||
522 | static char *rstrs[] = { | ||
523 | [R_MIPS_NONE] = "MIPS_NONE", | ||
524 | [R_MIPS_32] = "MIPS_32", | ||
525 | [R_MIPS_26] = "MIPS_26", | ||
526 | [R_MIPS_HI16] = "MIPS_HI16", | ||
527 | [R_MIPS_LO16] = "MIPS_LO16", | ||
528 | [R_MIPS_GPREL16] = "MIPS_GPREL16", | ||
529 | [R_MIPS_PC16] = "MIPS_PC16" | ||
530 | }; | ||
521 | 531 | ||
522 | int apply_relocations(Elf32_Shdr *sechdrs, | 532 | int apply_relocations(Elf32_Shdr *sechdrs, |
523 | const char *strtab, | 533 | const char *strtab, |
@@ -552,15 +562,13 @@ int apply_relocations(Elf32_Shdr *sechdrs, | |||
552 | 562 | ||
553 | res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v); | 563 | res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v); |
554 | if( res ) { | 564 | if( res ) { |
555 | printk(KERN_DEBUG | 565 | char *r = rstrs[ELF32_R_TYPE(r_info)]; |
556 | "relocation error 0x%x sym refer <%s> value 0x%x " | 566 | printk(KERN_WARNING "VPE loader: .text+0x%x " |
557 | "type 0x%x r_info 0x%x\n", | 567 | "relocation type %s for symbol \"%s\" failed\n", |
558 | (unsigned int)location, strtab + sym->st_name, v, | 568 | rel[i].r_offset, r ? r : "UNKNOWN", |
559 | r_info, ELF32_R_TYPE(r_info)); | 569 | strtab + sym->st_name); |
560 | } | ||
561 | |||
562 | if (res) | ||
563 | return res; | 570 | return res; |
571 | } | ||
564 | } | 572 | } |
565 | 573 | ||
566 | return 0; | 574 | return 0; |
@@ -576,7 +584,7 @@ void save_gp_address(unsigned int secbase, unsigned int rel) | |||
576 | 584 | ||
577 | 585 | ||
578 | /* Change all symbols so that sh_value encodes the pointer directly. */ | 586 | /* Change all symbols so that sh_value encodes the pointer directly. */ |
579 | static int simplify_symbols(Elf_Shdr * sechdrs, | 587 | static void simplify_symbols(Elf_Shdr * sechdrs, |
580 | unsigned int symindex, | 588 | unsigned int symindex, |
581 | const char *strtab, | 589 | const char *strtab, |
582 | const char *secstrings, | 590 | const char *secstrings, |
@@ -585,18 +593,21 @@ static int simplify_symbols(Elf_Shdr * sechdrs, | |||
585 | Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; | 593 | Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; |
586 | unsigned long secbase, bssbase = 0; | 594 | unsigned long secbase, bssbase = 0; |
587 | unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym); | 595 | unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym); |
588 | int ret = 0, size; | 596 | int size; |
589 | 597 | ||
590 | /* find the .bss section for COMMON symbols */ | 598 | /* find the .bss section for COMMON symbols */ |
591 | for (i = 0; i < nsecs; i++) { | 599 | for (i = 0; i < nsecs; i++) { |
592 | if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0) | 600 | if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0) { |
593 | bssbase = sechdrs[i].sh_addr; | 601 | bssbase = sechdrs[i].sh_addr; |
602 | break; | ||
603 | } | ||
594 | } | 604 | } |
595 | 605 | ||
596 | for (i = 1; i < n; i++) { | 606 | for (i = 1; i < n; i++) { |
597 | switch (sym[i].st_shndx) { | 607 | switch (sym[i].st_shndx) { |
598 | case SHN_COMMON: | 608 | case SHN_COMMON: |
599 | /* Allocate space for the symbol in the .bss section. st_value is currently size. | 609 | /* Allocate space for the symbol in the .bss section. |
610 | st_value is currently size. | ||
600 | We want it to have the address of the symbol. */ | 611 | We want it to have the address of the symbol. */ |
601 | 612 | ||
602 | size = sym[i].st_value; | 613 | size = sym[i].st_value; |
@@ -614,11 +625,9 @@ static int simplify_symbols(Elf_Shdr * sechdrs, | |||
614 | break; | 625 | break; |
615 | 626 | ||
616 | case SHN_MIPS_SCOMMON: | 627 | case SHN_MIPS_SCOMMON: |
617 | 628 | printk(KERN_DEBUG "simplify_symbols: ignoring SHN_MIPS_SCOMMON" | |
618 | printk(KERN_DEBUG | 629 | "symbol <%s> st_shndx %d\n", strtab + sym[i].st_name, |
619 | "simplify_symbols: ignoring SHN_MIPS_SCOMMON symbol <%s> st_shndx %d\n", | 630 | sym[i].st_shndx); |
620 | strtab + sym[i].st_name, sym[i].st_shndx); | ||
621 | |||
622 | // .sbss section | 631 | // .sbss section |
623 | break; | 632 | break; |
624 | 633 | ||
@@ -632,10 +641,7 @@ static int simplify_symbols(Elf_Shdr * sechdrs, | |||
632 | sym[i].st_value += secbase; | 641 | sym[i].st_value += secbase; |
633 | break; | 642 | break; |
634 | } | 643 | } |
635 | |||
636 | } | 644 | } |
637 | |||
638 | return ret; | ||
639 | } | 645 | } |
640 | 646 | ||
641 | #ifdef DEBUG_ELFLOADER | 647 | #ifdef DEBUG_ELFLOADER |
@@ -655,9 +661,26 @@ static void dump_elfsymbols(Elf_Shdr * sechdrs, unsigned int symindex, | |||
655 | 661 | ||
656 | static void dump_tc(struct tc *t) | 662 | static void dump_tc(struct tc *t) |
657 | { | 663 | { |
658 | printk(KERN_WARNING "VPE: TC index %d TCStatus 0x%lx halt 0x%lx\n", | 664 | unsigned long val; |
659 | t->index, read_tc_c0_tcstatus(), read_tc_c0_tchalt()); | 665 | |
660 | printk(KERN_WARNING "VPE: tcrestart 0x%lx\n", read_tc_c0_tcrestart()); | 666 | settc(t->index); |
667 | printk(KERN_DEBUG "VPE loader: TC index %d targtc %ld " | ||
668 | "TCStatus 0x%lx halt 0x%lx\n", | ||
669 | t->index, read_c0_vpecontrol() & VPECONTROL_TARGTC, | ||
670 | read_tc_c0_tcstatus(), read_tc_c0_tchalt()); | ||
671 | |||
672 | printk(KERN_DEBUG " tcrestart 0x%lx\n", read_tc_c0_tcrestart()); | ||
673 | printk(KERN_DEBUG " tcbind 0x%lx\n", read_tc_c0_tcbind()); | ||
674 | |||
675 | val = read_c0_vpeconf0(); | ||
676 | printk(KERN_DEBUG " VPEConf0 0x%lx MVP %ld\n", val, | ||
677 | (val & VPECONF0_MVP) >> VPECONF0_MVP_SHIFT); | ||
678 | |||
679 | printk(KERN_DEBUG " c0 status 0x%lx\n", read_vpe_c0_status()); | ||
680 | printk(KERN_DEBUG " c0 cause 0x%lx\n", read_vpe_c0_cause()); | ||
681 | |||
682 | printk(KERN_DEBUG " c0 badvaddr 0x%lx\n", read_vpe_c0_badvaddr()); | ||
683 | printk(KERN_DEBUG " c0 epc 0x%lx\n", read_vpe_c0_epc()); | ||
661 | } | 684 | } |
662 | 685 | ||
663 | static void dump_tclist(void) | 686 | static void dump_tclist(void) |
@@ -672,96 +695,108 @@ static void dump_tclist(void) | |||
672 | /* We are prepared so configure and start the VPE... */ | 695 | /* We are prepared so configure and start the VPE... */ |
673 | int vpe_run(struct vpe * v) | 696 | int vpe_run(struct vpe * v) |
674 | { | 697 | { |
675 | unsigned long val; | 698 | struct vpe_notifications *n; |
699 | unsigned long val, dmt_flag; | ||
676 | struct tc *t; | 700 | struct tc *t; |
677 | 701 | ||
678 | /* check we are the Master VPE */ | 702 | /* check we are the Master VPE */ |
679 | val = read_c0_vpeconf0(); | 703 | val = read_c0_vpeconf0(); |
680 | if (!(val & VPECONF0_MVP)) { | 704 | if (!(val & VPECONF0_MVP)) { |
681 | printk(KERN_WARNING | 705 | printk(KERN_WARNING |
682 | "VPE: only Master VPE's are allowed to configure MT\n"); | 706 | "VPE loader: only Master VPE's are allowed to configure MT\n"); |
683 | return -1; | 707 | return -1; |
684 | } | 708 | } |
685 | 709 | ||
686 | /* disable MT (using dvpe) */ | 710 | /* disable MT (using dvpe) */ |
687 | dvpe(); | 711 | dvpe(); |
688 | 712 | ||
713 | if (!list_empty(&v->tc)) { | ||
714 | if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) { | ||
715 | printk(KERN_WARNING "VPE loader: TC %d is already in use.\n", | ||
716 | t->index); | ||
717 | return -ENOEXEC; | ||
718 | } | ||
719 | } else { | ||
720 | printk(KERN_WARNING "VPE loader: No TC's associated with VPE %d\n", | ||
721 | v->minor); | ||
722 | return -ENOEXEC; | ||
723 | } | ||
724 | |||
689 | /* Put MVPE's into 'configuration state' */ | 725 | /* Put MVPE's into 'configuration state' */ |
690 | set_c0_mvpcontrol(MVPCONTROL_VPC); | 726 | set_c0_mvpcontrol(MVPCONTROL_VPC); |
691 | 727 | ||
692 | if (!list_empty(&v->tc)) { | ||
693 | if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) { | ||
694 | printk(KERN_WARNING "VPE: TC %d is already in use.\n", | ||
695 | t->index); | ||
696 | return -ENOEXEC; | ||
697 | } | ||
698 | } else { | ||
699 | printk(KERN_WARNING "VPE: No TC's associated with VPE %d\n", | ||
700 | v->minor); | ||
701 | return -ENOEXEC; | ||
702 | } | ||
703 | |||
704 | settc(t->index); | 728 | settc(t->index); |
705 | 729 | ||
706 | val = read_vpe_c0_vpeconf0(); | ||
707 | |||
708 | /* should check it is halted, and not activated */ | 730 | /* should check it is halted, and not activated */ |
709 | if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) { | 731 | if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) { |
710 | printk(KERN_WARNING "VPE: TC %d is already doing something!\n", | 732 | printk(KERN_WARNING "VPE loader: TC %d is already doing something!\n", |
711 | t->index); | 733 | t->index); |
712 | |||
713 | dump_tclist(); | 734 | dump_tclist(); |
714 | return -ENOEXEC; | 735 | return -ENOEXEC; |
715 | } | 736 | } |
716 | 737 | ||
738 | /* | ||
739 | * Disable multi-threaded execution whilst we activate, clear the | ||
740 | * halt bit and bound the tc to the other VPE... | ||
741 | */ | ||
742 | dmt_flag = dmt(); | ||
743 | |||
717 | /* Write the address we want it to start running from in the TCPC register. */ | 744 | /* Write the address we want it to start running from in the TCPC register. */ |
718 | write_tc_c0_tcrestart((unsigned long)v->__start); | 745 | write_tc_c0_tcrestart((unsigned long)v->__start); |
719 | |||
720 | /* write the sivc_info address to tccontext */ | ||
721 | write_tc_c0_tccontext((unsigned long)0); | 746 | write_tc_c0_tccontext((unsigned long)0); |
722 | 747 | /* | |
723 | /* Set up the XTC bit in vpeconf0 to point at our tc */ | 748 | * Mark the TC as activated, not interrupt exempt and not dynamically |
724 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (t->index << VPECONF0_XTC_SHIFT)); | 749 | * allocatable |
725 | 750 | */ | |
726 | /* mark the TC as activated, not interrupt exempt and not dynamically allocatable */ | ||
727 | val = read_tc_c0_tcstatus(); | 751 | val = read_tc_c0_tcstatus(); |
728 | val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A; | 752 | val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A; |
729 | write_tc_c0_tcstatus(val); | 753 | write_tc_c0_tcstatus(val); |
730 | 754 | ||
731 | write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H); | 755 | write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H); |
732 | 756 | ||
733 | /* set up VPE1 */ | ||
734 | write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); // no multiple TC's | ||
735 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); // enable this VPE | ||
736 | |||
737 | /* | 757 | /* |
738 | * The sde-kit passes 'memsize' to __start in $a3, so set something | 758 | * The sde-kit passes 'memsize' to __start in $a3, so set something |
739 | * here... | 759 | * here... Or set $a3 to zero and define DFLT_STACK_SIZE and |
740 | * Or set $a3 (register 7) to zero and define DFLT_STACK_SIZE and | ||
741 | * DFLT_HEAP_SIZE when you compile your program | 760 | * DFLT_HEAP_SIZE when you compile your program |
742 | */ | 761 | */ |
762 | mttgpr(7, physical_memsize); | ||
763 | |||
764 | |||
765 | /* set up VPE1 */ | ||
766 | /* | ||
767 | * bind the TC to VPE 1 as late as possible so we only have the final | ||
768 | * VPE registers to set up, and so an EJTAG probe can trigger on it | ||
769 | */ | ||
770 | write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | v->minor); | ||
743 | 771 | ||
744 | mttgpr(7, 0); | 772 | /* Set up the XTC bit in vpeconf0 to point at our tc */ |
773 | write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC)) | ||
774 | | (t->index << VPECONF0_XTC_SHIFT)); | ||
745 | 775 | ||
746 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ | 776 | /* enable this VPE */ |
747 | write_vpe_c0_config(read_c0_config()); | 777 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); |
748 | 778 | ||
749 | /* clear out any left overs from a previous program */ | 779 | /* clear out any left overs from a previous program */ |
780 | write_vpe_c0_status(0); | ||
750 | write_vpe_c0_cause(0); | 781 | write_vpe_c0_cause(0); |
751 | 782 | ||
752 | /* take system out of configuration state */ | 783 | /* take system out of configuration state */ |
753 | clear_c0_mvpcontrol(MVPCONTROL_VPC); | 784 | clear_c0_mvpcontrol(MVPCONTROL_VPC); |
754 | 785 | ||
755 | /* clear interrupts enabled IE, ERL, EXL, and KSU from c0 status */ | 786 | /* now safe to re-enable multi-threading */ |
756 | write_vpe_c0_status(read_vpe_c0_status() & ~(ST0_ERL | ST0_KSU | ST0_IE | ST0_EXL)); | 787 | emt(dmt_flag); |
757 | 788 | ||
758 | /* set it running */ | 789 | /* set it running */ |
759 | evpe(EVPE_ENABLE); | 790 | evpe(EVPE_ENABLE); |
760 | 791 | ||
792 | list_for_each_entry(n, &v->notify, list) { | ||
793 | n->start(v->minor); | ||
794 | } | ||
795 | |||
761 | return 0; | 796 | return 0; |
762 | } | 797 | } |
763 | 798 | ||
764 | static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs, | 799 | static int find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs, |
765 | unsigned int symindex, const char *strtab, | 800 | unsigned int symindex, const char *strtab, |
766 | struct module *mod) | 801 | struct module *mod) |
767 | { | 802 | { |
@@ -778,26 +813,28 @@ static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs, | |||
778 | } | 813 | } |
779 | } | 814 | } |
780 | 815 | ||
816 | if ( (v->__start == 0) || (v->shared_ptr == NULL)) | ||
817 | return -1; | ||
818 | |||
781 | return 0; | 819 | return 0; |
782 | } | 820 | } |
783 | 821 | ||
784 | /* | 822 | /* |
785 | * Allocates a VPE with some program code space(the load address), copies | 823 | * Allocates a VPE with some program code space(the load address), copies the |
786 | * the contents of the program (p)buffer performing relocatations/etc, | 824 | * contents of the program (p)buffer performing relocatations/etc, free's it |
787 | * free's it when finished. | 825 | * when finished. |
788 | */ | 826 | */ |
789 | int vpe_elfload(struct vpe * v) | 827 | int vpe_elfload(struct vpe * v) |
790 | { | 828 | { |
791 | Elf_Ehdr *hdr; | 829 | Elf_Ehdr *hdr; |
792 | Elf_Shdr *sechdrs; | 830 | Elf_Shdr *sechdrs; |
793 | long err = 0; | 831 | long err = 0; |
794 | char *secstrings, *strtab = NULL; | 832 | char *secstrings, *strtab = NULL; |
795 | unsigned int len, i, symindex = 0, strindex = 0; | 833 | unsigned int len, i, symindex = 0, strindex = 0, relocate = 0; |
796 | |||
797 | struct module mod; // so we can re-use the relocations code | 834 | struct module mod; // so we can re-use the relocations code |
798 | 835 | ||
799 | memset(&mod, 0, sizeof(struct module)); | 836 | memset(&mod, 0, sizeof(struct module)); |
800 | strcpy(mod.name, "VPE dummy prog module"); | 837 | strcpy(mod.name, "VPE loader"); |
801 | 838 | ||
802 | hdr = (Elf_Ehdr *) v->pbuffer; | 839 | hdr = (Elf_Ehdr *) v->pbuffer; |
803 | len = v->plen; | 840 | len = v->plen; |
@@ -805,16 +842,22 @@ int vpe_elfload(struct vpe * v) | |||
805 | /* Sanity checks against insmoding binaries or wrong arch, | 842 | /* Sanity checks against insmoding binaries or wrong arch, |
806 | weird elf version */ | 843 | weird elf version */ |
807 | if (memcmp(hdr->e_ident, ELFMAG, 4) != 0 | 844 | if (memcmp(hdr->e_ident, ELFMAG, 4) != 0 |
808 | || hdr->e_type != ET_REL || !elf_check_arch(hdr) | 845 | || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC) |
846 | || !elf_check_arch(hdr) | ||
809 | || hdr->e_shentsize != sizeof(*sechdrs)) { | 847 | || hdr->e_shentsize != sizeof(*sechdrs)) { |
810 | printk(KERN_WARNING | 848 | printk(KERN_WARNING |
811 | "VPE program, wrong arch or weird elf version\n"); | 849 | "VPE loader: program wrong arch or weird elf version\n"); |
812 | 850 | ||
813 | return -ENOEXEC; | 851 | return -ENOEXEC; |
814 | } | 852 | } |
815 | 853 | ||
854 | if (hdr->e_type == ET_REL) | ||
855 | relocate = 1; | ||
856 | |||
816 | if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) { | 857 | if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) { |
817 | printk(KERN_ERR "VPE program length %u truncated\n", len); | 858 | printk(KERN_ERR "VPE loader: program length %u truncated\n", |
859 | len); | ||
860 | |||
818 | return -ENOEXEC; | 861 | return -ENOEXEC; |
819 | } | 862 | } |
820 | 863 | ||
@@ -826,82 +869,126 @@ int vpe_elfload(struct vpe * v) | |||
826 | /* And these should exist, but gcc whinges if we don't init them */ | 869 | /* And these should exist, but gcc whinges if we don't init them */ |
827 | symindex = strindex = 0; | 870 | symindex = strindex = 0; |
828 | 871 | ||
829 | for (i = 1; i < hdr->e_shnum; i++) { | 872 | if (relocate) { |
830 | 873 | for (i = 1; i < hdr->e_shnum; i++) { | |
831 | if (sechdrs[i].sh_type != SHT_NOBITS | 874 | if (sechdrs[i].sh_type != SHT_NOBITS |
832 | && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) { | 875 | && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) { |
833 | printk(KERN_ERR "VPE program length %u truncated\n", | 876 | printk(KERN_ERR "VPE program length %u truncated\n", |
834 | len); | 877 | len); |
835 | return -ENOEXEC; | 878 | return -ENOEXEC; |
836 | } | 879 | } |
837 | 880 | ||
838 | /* Mark all sections sh_addr with their address in the | 881 | /* Mark all sections sh_addr with their address in the |
839 | temporary image. */ | 882 | temporary image. */ |
840 | sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset; | 883 | sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset; |
841 | 884 | ||
842 | /* Internal symbols and strings. */ | 885 | /* Internal symbols and strings. */ |
843 | if (sechdrs[i].sh_type == SHT_SYMTAB) { | 886 | if (sechdrs[i].sh_type == SHT_SYMTAB) { |
844 | symindex = i; | 887 | symindex = i; |
845 | strindex = sechdrs[i].sh_link; | 888 | strindex = sechdrs[i].sh_link; |
846 | strtab = (char *)hdr + sechdrs[strindex].sh_offset; | 889 | strtab = (char *)hdr + sechdrs[strindex].sh_offset; |
890 | } | ||
847 | } | 891 | } |
892 | layout_sections(&mod, hdr, sechdrs, secstrings); | ||
848 | } | 893 | } |
849 | 894 | ||
850 | layout_sections(&mod, hdr, sechdrs, secstrings); | ||
851 | |||
852 | v->load_addr = alloc_progmem(mod.core_size); | 895 | v->load_addr = alloc_progmem(mod.core_size); |
853 | memset(v->load_addr, 0, mod.core_size); | 896 | memset(v->load_addr, 0, mod.core_size); |
854 | 897 | ||
855 | printk("VPE elf_loader: loading to %p\n", v->load_addr); | 898 | printk("VPE loader: loading to %p\n", v->load_addr); |
856 | 899 | ||
857 | for (i = 0; i < hdr->e_shnum; i++) { | 900 | if (relocate) { |
858 | void *dest; | 901 | for (i = 0; i < hdr->e_shnum; i++) { |
902 | void *dest; | ||
859 | 903 | ||
860 | if (!(sechdrs[i].sh_flags & SHF_ALLOC)) | 904 | if (!(sechdrs[i].sh_flags & SHF_ALLOC)) |
861 | continue; | 905 | continue; |
862 | 906 | ||
863 | dest = v->load_addr + sechdrs[i].sh_entsize; | 907 | dest = v->load_addr + sechdrs[i].sh_entsize; |
864 | 908 | ||
865 | if (sechdrs[i].sh_type != SHT_NOBITS) | 909 | if (sechdrs[i].sh_type != SHT_NOBITS) |
866 | memcpy(dest, (void *)sechdrs[i].sh_addr, | 910 | memcpy(dest, (void *)sechdrs[i].sh_addr, |
867 | sechdrs[i].sh_size); | 911 | sechdrs[i].sh_size); |
868 | /* Update sh_addr to point to copy in image. */ | 912 | /* Update sh_addr to point to copy in image. */ |
869 | sechdrs[i].sh_addr = (unsigned long)dest; | 913 | sechdrs[i].sh_addr = (unsigned long)dest; |
870 | } | ||
871 | 914 | ||
872 | /* Fix up syms, so that st_value is a pointer to location. */ | 915 | printk(KERN_DEBUG " section sh_name %s sh_addr 0x%x\n", |
873 | err = | 916 | secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr); |
874 | simplify_symbols(sechdrs, symindex, strtab, secstrings, | 917 | } |
875 | hdr->e_shnum, &mod); | ||
876 | if (err < 0) { | ||
877 | printk(KERN_WARNING "VPE: unable to simplify symbols\n"); | ||
878 | goto cleanup; | ||
879 | } | ||
880 | 918 | ||
881 | /* Now do relocations. */ | 919 | /* Fix up syms, so that st_value is a pointer to location. */ |
882 | for (i = 1; i < hdr->e_shnum; i++) { | 920 | simplify_symbols(sechdrs, symindex, strtab, secstrings, |
883 | const char *strtab = (char *)sechdrs[strindex].sh_addr; | 921 | hdr->e_shnum, &mod); |
884 | unsigned int info = sechdrs[i].sh_info; | 922 | |
885 | 923 | /* Now do relocations. */ | |
886 | /* Not a valid relocation section? */ | 924 | for (i = 1; i < hdr->e_shnum; i++) { |
887 | if (info >= hdr->e_shnum) | 925 | const char *strtab = (char *)sechdrs[strindex].sh_addr; |
888 | continue; | 926 | unsigned int info = sechdrs[i].sh_info; |
889 | 927 | ||
890 | /* Don't bother with non-allocated sections */ | 928 | /* Not a valid relocation section? */ |
891 | if (!(sechdrs[info].sh_flags & SHF_ALLOC)) | 929 | if (info >= hdr->e_shnum) |
892 | continue; | 930 | continue; |
893 | 931 | ||
894 | if (sechdrs[i].sh_type == SHT_REL) | 932 | /* Don't bother with non-allocated sections */ |
895 | err = | 933 | if (!(sechdrs[info].sh_flags & SHF_ALLOC)) |
896 | apply_relocations(sechdrs, strtab, symindex, i, &mod); | 934 | continue; |
897 | else if (sechdrs[i].sh_type == SHT_RELA) | 935 | |
898 | err = apply_relocate_add(sechdrs, strtab, symindex, i, | 936 | if (sechdrs[i].sh_type == SHT_REL) |
899 | &mod); | 937 | err = apply_relocations(sechdrs, strtab, symindex, i, |
900 | if (err < 0) { | 938 | &mod); |
901 | printk(KERN_WARNING | 939 | else if (sechdrs[i].sh_type == SHT_RELA) |
902 | "vpe_elfload: error in relocations err %ld\n", | 940 | err = apply_relocate_add(sechdrs, strtab, symindex, i, |
903 | err); | 941 | &mod); |
904 | goto cleanup; | 942 | if (err < 0) |
943 | return err; | ||
944 | |||
945 | } | ||
946 | } else { | ||
947 | for (i = 0; i < hdr->e_shnum; i++) { | ||
948 | |||
949 | /* Internal symbols and strings. */ | ||
950 | if (sechdrs[i].sh_type == SHT_SYMTAB) { | ||
951 | symindex = i; | ||
952 | strindex = sechdrs[i].sh_link; | ||
953 | strtab = (char *)hdr + sechdrs[strindex].sh_offset; | ||
954 | |||
955 | /* mark the symtab's address for when we try to find the | ||
956 | magic symbols */ | ||
957 | sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset; | ||
958 | } | ||
959 | |||
960 | /* filter sections we dont want in the final image */ | ||
961 | if (!(sechdrs[i].sh_flags & SHF_ALLOC) || | ||
962 | (sechdrs[i].sh_type == SHT_MIPS_REGINFO)) { | ||
963 | printk( KERN_DEBUG " ignoring section, " | ||
964 | "name %s type %x address 0x%x \n", | ||
965 | secstrings + sechdrs[i].sh_name, | ||
966 | sechdrs[i].sh_type, sechdrs[i].sh_addr); | ||
967 | continue; | ||
968 | } | ||
969 | |||
970 | if (sechdrs[i].sh_addr < (unsigned int)v->load_addr) { | ||
971 | printk( KERN_WARNING "VPE loader: " | ||
972 | "fully linked image has invalid section, " | ||
973 | "name %s type %x address 0x%x, before load " | ||
974 | "address of 0x%x\n", | ||
975 | secstrings + sechdrs[i].sh_name, | ||
976 | sechdrs[i].sh_type, sechdrs[i].sh_addr, | ||
977 | (unsigned int)v->load_addr); | ||
978 | return -ENOEXEC; | ||
979 | } | ||
980 | |||
981 | printk(KERN_DEBUG " copying section sh_name %s, sh_addr 0x%x " | ||
982 | "size 0x%x0 from x%p\n", | ||
983 | secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr, | ||
984 | sechdrs[i].sh_size, hdr + sechdrs[i].sh_offset); | ||
985 | |||
986 | if (sechdrs[i].sh_type != SHT_NOBITS) | ||
987 | memcpy((void *)sechdrs[i].sh_addr, | ||
988 | (char *)hdr + sechdrs[i].sh_offset, | ||
989 | sechdrs[i].sh_size); | ||
990 | else | ||
991 | memset((void *)sechdrs[i].sh_addr, 0, sechdrs[i].sh_size); | ||
905 | } | 992 | } |
906 | } | 993 | } |
907 | 994 | ||
@@ -910,71 +997,104 @@ int vpe_elfload(struct vpe * v) | |||
910 | (unsigned long)v->load_addr + v->len); | 997 | (unsigned long)v->load_addr + v->len); |
911 | 998 | ||
912 | if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) { | 999 | if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) { |
1000 | if (v->__start == 0) { | ||
1001 | printk(KERN_WARNING "VPE loader: program does not contain " | ||
1002 | "a __start symbol\n"); | ||
1003 | return -ENOEXEC; | ||
1004 | } | ||
913 | 1005 | ||
914 | printk(KERN_WARNING | 1006 | if (v->shared_ptr == NULL) |
915 | "VPE: program doesn't contain __start or vpe_shared symbols\n"); | 1007 | printk(KERN_WARNING "VPE loader: " |
916 | err = -ENOEXEC; | 1008 | "program does not contain vpe_shared symbol.\n" |
1009 | " Unable to use AMVP (AP/SP) facilities.\n"); | ||
917 | } | 1010 | } |
918 | 1011 | ||
919 | printk(" elf loaded\n"); | 1012 | printk(" elf loaded\n"); |
920 | 1013 | return 0; | |
921 | cleanup: | ||
922 | return err; | ||
923 | } | 1014 | } |
924 | 1015 | ||
925 | static void dump_vpe(struct vpe * v) | 1016 | __attribute_used__ void dump_vpe(struct vpe * v) |
926 | { | 1017 | { |
927 | struct tc *t; | 1018 | struct tc *t; |
928 | 1019 | ||
1020 | settc(v->minor); | ||
1021 | |||
929 | printk(KERN_DEBUG "VPEControl 0x%lx\n", read_vpe_c0_vpecontrol()); | 1022 | printk(KERN_DEBUG "VPEControl 0x%lx\n", read_vpe_c0_vpecontrol()); |
930 | printk(KERN_DEBUG "VPEConf0 0x%lx\n", read_vpe_c0_vpeconf0()); | 1023 | printk(KERN_DEBUG "VPEConf0 0x%lx\n", read_vpe_c0_vpeconf0()); |
931 | 1024 | ||
932 | list_for_each_entry(t, &vpecontrol.tc_list, list) { | 1025 | list_for_each_entry(t, &vpecontrol.tc_list, list) |
933 | dump_tc(t); | 1026 | dump_tc(t); |
934 | } | ||
935 | } | 1027 | } |
936 | 1028 | ||
937 | /* checks for VPE is unused and gets ready to load program */ | 1029 | static void cleanup_tc(struct tc *tc) |
1030 | { | ||
1031 | int tmp; | ||
1032 | |||
1033 | /* Put MVPE's into 'configuration state' */ | ||
1034 | set_c0_mvpcontrol(MVPCONTROL_VPC); | ||
1035 | |||
1036 | settc(tc->index); | ||
1037 | tmp = read_tc_c0_tcstatus(); | ||
1038 | |||
1039 | /* mark not allocated and not dynamically allocatable */ | ||
1040 | tmp &= ~(TCSTATUS_A | TCSTATUS_DA); | ||
1041 | tmp |= TCSTATUS_IXMT; /* interrupt exempt */ | ||
1042 | write_tc_c0_tcstatus(tmp); | ||
1043 | |||
1044 | write_tc_c0_tchalt(TCHALT_H); | ||
1045 | |||
1046 | /* bind it to anything other than VPE1 */ | ||
1047 | write_tc_c0_tcbind(read_tc_c0_tcbind() & ~TCBIND_CURVPE); // | TCBIND_CURVPE | ||
1048 | |||
1049 | clear_c0_mvpcontrol(MVPCONTROL_VPC); | ||
1050 | } | ||
1051 | |||
1052 | static int getcwd(char *buff, int size) | ||
1053 | { | ||
1054 | mm_segment_t old_fs; | ||
1055 | int ret; | ||
1056 | |||
1057 | old_fs = get_fs(); | ||
1058 | set_fs(KERNEL_DS); | ||
1059 | |||
1060 | ret = sys_getcwd(buff,size); | ||
1061 | |||
1062 | set_fs(old_fs); | ||
1063 | |||
1064 | return ret; | ||
1065 | } | ||
1066 | |||
1067 | /* checks VPE is unused and gets ready to load program */ | ||
938 | static int vpe_open(struct inode *inode, struct file *filp) | 1068 | static int vpe_open(struct inode *inode, struct file *filp) |
939 | { | 1069 | { |
940 | int minor; | 1070 | int minor, ret; |
941 | struct vpe *v; | 1071 | struct vpe *v; |
1072 | struct vpe_notifications *not; | ||
942 | 1073 | ||
943 | /* assume only 1 device at the mo. */ | 1074 | /* assume only 1 device at the mo. */ |
944 | if ((minor = MINOR(inode->i_rdev)) != 1) { | 1075 | if ((minor = MINOR(inode->i_rdev)) != 1) { |
945 | printk(KERN_WARNING "VPE: only vpe1 is supported\n"); | 1076 | printk(KERN_WARNING "VPE loader: only vpe1 is supported\n"); |
946 | return -ENODEV; | 1077 | return -ENODEV; |
947 | } | 1078 | } |
948 | 1079 | ||
949 | if ((v = get_vpe(minor)) == NULL) { | 1080 | if ((v = get_vpe(minor)) == NULL) { |
950 | printk(KERN_WARNING "VPE: unable to get vpe\n"); | 1081 | printk(KERN_WARNING "VPE loader: unable to get vpe\n"); |
951 | return -ENODEV; | 1082 | return -ENODEV; |
952 | } | 1083 | } |
953 | 1084 | ||
954 | if (v->state != VPE_STATE_UNUSED) { | 1085 | if (v->state != VPE_STATE_UNUSED) { |
955 | unsigned long tmp; | ||
956 | struct tc *t; | ||
957 | |||
958 | printk(KERN_WARNING "VPE: device %d already in use\n", minor); | ||
959 | |||
960 | dvpe(); | 1086 | dvpe(); |
961 | dump_vpe(v); | ||
962 | |||
963 | printk(KERN_WARNING "VPE: re-initialising %d\n", minor); | ||
964 | |||
965 | release_progmem(v->load_addr); | ||
966 | 1087 | ||
967 | t = get_tc(minor); | 1088 | printk(KERN_DEBUG "VPE loader: tc in use dumping regs\n"); |
968 | settc(minor); | ||
969 | tmp = read_tc_c0_tcstatus(); | ||
970 | 1089 | ||
971 | /* mark not allocated and not dynamically allocatable */ | 1090 | dump_tc(get_tc(minor)); |
972 | tmp &= ~(TCSTATUS_A | TCSTATUS_DA); | ||
973 | tmp |= TCSTATUS_IXMT; /* interrupt exempt */ | ||
974 | write_tc_c0_tcstatus(tmp); | ||
975 | 1091 | ||
976 | write_tc_c0_tchalt(TCHALT_H); | 1092 | list_for_each_entry(not, &v->notify, list) { |
1093 | not->stop(minor); | ||
1094 | } | ||
977 | 1095 | ||
1096 | release_progmem(v->load_addr); | ||
1097 | cleanup_tc(get_tc(minor)); | ||
978 | } | 1098 | } |
979 | 1099 | ||
980 | // allocate it so when we get write ops we know it's expected. | 1100 | // allocate it so when we get write ops we know it's expected. |
@@ -986,6 +1106,24 @@ static int vpe_open(struct inode *inode, struct file *filp) | |||
986 | v->load_addr = NULL; | 1106 | v->load_addr = NULL; |
987 | v->len = 0; | 1107 | v->len = 0; |
988 | 1108 | ||
1109 | v->uid = filp->f_uid; | ||
1110 | v->gid = filp->f_gid; | ||
1111 | |||
1112 | #ifdef CONFIG_MIPS_APSP_KSPD | ||
1113 | /* get kspd to tell us when a syscall_exit happens */ | ||
1114 | if (!kspd_events_reqd) { | ||
1115 | kspd_notify(&kspd_events); | ||
1116 | kspd_events_reqd++; | ||
1117 | } | ||
1118 | #endif | ||
1119 | |||
1120 | v->cwd[0] = 0; | ||
1121 | ret = getcwd(v->cwd, VPE_PATH_MAX); | ||
1122 | if (ret < 0) | ||
1123 | printk(KERN_WARNING "VPE loader: open, getcwd returned %d\n", ret); | ||
1124 | |||
1125 | v->shared_ptr = NULL; | ||
1126 | v->__start = 0; | ||
989 | return 0; | 1127 | return 0; |
990 | } | 1128 | } |
991 | 1129 | ||
@@ -1006,14 +1144,22 @@ static int vpe_release(struct inode *inode, struct file *filp) | |||
1006 | if (vpe_elfload(v) >= 0) | 1144 | if (vpe_elfload(v) >= 0) |
1007 | vpe_run(v); | 1145 | vpe_run(v); |
1008 | else { | 1146 | else { |
1009 | printk(KERN_WARNING "VPE: ELF load failed.\n"); | 1147 | printk(KERN_WARNING "VPE loader: ELF load failed.\n"); |
1010 | ret = -ENOEXEC; | 1148 | ret = -ENOEXEC; |
1011 | } | 1149 | } |
1012 | } else { | 1150 | } else { |
1013 | printk(KERN_WARNING "VPE: only elf files are supported\n"); | 1151 | printk(KERN_WARNING "VPE loader: only elf files are supported\n"); |
1014 | ret = -ENOEXEC; | 1152 | ret = -ENOEXEC; |
1015 | } | 1153 | } |
1016 | 1154 | ||
1155 | /* It's good to be able to run the SP and if it chokes have a look at | ||
1156 | the /dev/rt?. But if we reset the pointer to the shared struct we | ||
1157 | loose what has happened. So perhaps if garbage is sent to the vpe | ||
1158 | device, use it as a trigger for the reset. Hopefully a nice | ||
1159 | executable will be along shortly. */ | ||
1160 | if (ret < 0) | ||
1161 | v->shared_ptr = NULL; | ||
1162 | |||
1017 | // cleanup any temp buffers | 1163 | // cleanup any temp buffers |
1018 | if (v->pbuffer) | 1164 | if (v->pbuffer) |
1019 | vfree(v->pbuffer); | 1165 | vfree(v->pbuffer); |
@@ -1033,21 +1179,19 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer, | |||
1033 | return -ENODEV; | 1179 | return -ENODEV; |
1034 | 1180 | ||
1035 | if (v->pbuffer == NULL) { | 1181 | if (v->pbuffer == NULL) { |
1036 | printk(KERN_ERR "vpe_write: no pbuffer\n"); | 1182 | printk(KERN_ERR "VPE loader: no buffer for program\n"); |
1037 | return -ENOMEM; | 1183 | return -ENOMEM; |
1038 | } | 1184 | } |
1039 | 1185 | ||
1040 | if ((count + v->len) > v->plen) { | 1186 | if ((count + v->len) > v->plen) { |
1041 | printk(KERN_WARNING | 1187 | printk(KERN_WARNING |
1042 | "VPE Loader: elf size too big. Perhaps strip uneeded symbols\n"); | 1188 | "VPE loader: elf size too big. Perhaps strip uneeded symbols\n"); |
1043 | return -ENOMEM; | 1189 | return -ENOMEM; |
1044 | } | 1190 | } |
1045 | 1191 | ||
1046 | count -= copy_from_user(v->pbuffer + v->len, buffer, count); | 1192 | count -= copy_from_user(v->pbuffer + v->len, buffer, count); |
1047 | if (!count) { | 1193 | if (!count) |
1048 | printk("vpe_write: copy_to_user failed\n"); | ||
1049 | return -EFAULT; | 1194 | return -EFAULT; |
1050 | } | ||
1051 | 1195 | ||
1052 | v->len += count; | 1196 | v->len += count; |
1053 | return ret; | 1197 | return ret; |
@@ -1149,16 +1293,70 @@ void *vpe_get_shared(int index) | |||
1149 | { | 1293 | { |
1150 | struct vpe *v; | 1294 | struct vpe *v; |
1151 | 1295 | ||
1152 | if ((v = get_vpe(index)) == NULL) { | 1296 | if ((v = get_vpe(index)) == NULL) |
1153 | printk(KERN_WARNING "vpe: invalid vpe index %d\n", index); | ||
1154 | return NULL; | 1297 | return NULL; |
1155 | } | ||
1156 | 1298 | ||
1157 | return v->shared_ptr; | 1299 | return v->shared_ptr; |
1158 | } | 1300 | } |
1159 | 1301 | ||
1160 | EXPORT_SYMBOL(vpe_get_shared); | 1302 | EXPORT_SYMBOL(vpe_get_shared); |
1161 | 1303 | ||
1304 | int vpe_getuid(int index) | ||
1305 | { | ||
1306 | struct vpe *v; | ||
1307 | |||
1308 | if ((v = get_vpe(index)) == NULL) | ||
1309 | return -1; | ||
1310 | |||
1311 | return v->uid; | ||
1312 | } | ||
1313 | |||
1314 | EXPORT_SYMBOL(vpe_getuid); | ||
1315 | |||
1316 | int vpe_getgid(int index) | ||
1317 | { | ||
1318 | struct vpe *v; | ||
1319 | |||
1320 | if ((v = get_vpe(index)) == NULL) | ||
1321 | return -1; | ||
1322 | |||
1323 | return v->gid; | ||
1324 | } | ||
1325 | |||
1326 | EXPORT_SYMBOL(vpe_getgid); | ||
1327 | |||
1328 | int vpe_notify(int index, struct vpe_notifications *notify) | ||
1329 | { | ||
1330 | struct vpe *v; | ||
1331 | |||
1332 | if ((v = get_vpe(index)) == NULL) | ||
1333 | return -1; | ||
1334 | |||
1335 | list_add(¬ify->list, &v->notify); | ||
1336 | return 0; | ||
1337 | } | ||
1338 | |||
1339 | EXPORT_SYMBOL(vpe_notify); | ||
1340 | |||
1341 | char *vpe_getcwd(int index) | ||
1342 | { | ||
1343 | struct vpe *v; | ||
1344 | |||
1345 | if ((v = get_vpe(index)) == NULL) | ||
1346 | return NULL; | ||
1347 | |||
1348 | return v->cwd; | ||
1349 | } | ||
1350 | |||
1351 | EXPORT_SYMBOL(vpe_getcwd); | ||
1352 | |||
1353 | #ifdef CONFIG_MIPS_APSP_KSPD | ||
1354 | static void kspd_sp_exit( int sp_id) | ||
1355 | { | ||
1356 | cleanup_tc(get_tc(sp_id)); | ||
1357 | } | ||
1358 | #endif | ||
1359 | |||
1162 | static int __init vpe_module_init(void) | 1360 | static int __init vpe_module_init(void) |
1163 | { | 1361 | { |
1164 | struct vpe *v = NULL; | 1362 | struct vpe *v = NULL; |
@@ -1201,7 +1399,8 @@ static int __init vpe_module_init(void) | |||
1201 | return -ENODEV; | 1399 | return -ENODEV; |
1202 | } | 1400 | } |
1203 | 1401 | ||
1204 | list_add(&t->tc, &v->tc); /* add the tc to the list of this vpe's tc's. */ | 1402 | /* add the tc to the list of this vpe's tc's. */ |
1403 | list_add(&t->tc, &v->tc); | ||
1205 | 1404 | ||
1206 | /* deactivate all but vpe0 */ | 1405 | /* deactivate all but vpe0 */ |
1207 | if (i != 0) { | 1406 | if (i != 0) { |
@@ -1222,10 +1421,12 @@ static int __init vpe_module_init(void) | |||
1222 | ~(ST0_IM | ST0_IE | ST0_KSU)) | 1421 | ~(ST0_IM | ST0_IE | ST0_KSU)) |
1223 | | ST0_CU0); | 1422 | | ST0_CU0); |
1224 | 1423 | ||
1225 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ | 1424 | /* |
1425 | * Set config to be the same as vpe0, | ||
1426 | * particularly kseg0 coherency alg | ||
1427 | */ | ||
1226 | write_vpe_c0_config(read_c0_config()); | 1428 | write_vpe_c0_config(read_c0_config()); |
1227 | } | 1429 | } |
1228 | |||
1229 | } | 1430 | } |
1230 | 1431 | ||
1231 | /* TC's */ | 1432 | /* TC's */ |
@@ -1234,23 +1435,28 @@ static int __init vpe_module_init(void) | |||
1234 | if (i != 0) { | 1435 | if (i != 0) { |
1235 | unsigned long tmp; | 1436 | unsigned long tmp; |
1236 | 1437 | ||
1237 | /* tc 0 will of course be running.... */ | ||
1238 | if (i == 0) | ||
1239 | t->state = TC_STATE_RUNNING; | ||
1240 | |||
1241 | settc(i); | 1438 | settc(i); |
1242 | 1439 | ||
1243 | /* bind a TC to each VPE, May as well put all excess TC's | 1440 | /* Any TC that is bound to VPE0 gets left as is - in case |
1244 | on the last VPE */ | 1441 | we are running SMTC on VPE0. A TC that is bound to any |
1245 | if (i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1)) | 1442 | other VPE gets bound to VPE0, ideally I'd like to make |
1246 | write_tc_c0_tcbind(read_tc_c0_tcbind() | | 1443 | it homeless but it doesn't appear to let me bind a TC |
1247 | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)); | 1444 | to a non-existent VPE. Which is perfectly reasonable. |
1248 | else | 1445 | |
1249 | write_tc_c0_tcbind(read_tc_c0_tcbind() | i); | 1446 | The (un)bound state is visible to an EJTAG probe so may |
1447 | notify GDB... | ||
1448 | */ | ||
1449 | |||
1450 | if (((tmp = read_tc_c0_tcbind()) & TCBIND_CURVPE)) { | ||
1451 | /* tc is bound >vpe0 */ | ||
1452 | write_tc_c0_tcbind(tmp & ~TCBIND_CURVPE); | ||
1453 | |||
1454 | t->pvpe = get_vpe(0); /* set the parent vpe */ | ||
1455 | } | ||
1250 | 1456 | ||
1251 | tmp = read_tc_c0_tcstatus(); | 1457 | tmp = read_tc_c0_tcstatus(); |
1252 | 1458 | ||
1253 | /* mark not allocated and not dynamically allocatable */ | 1459 | /* mark not activated and not dynamically allocatable */ |
1254 | tmp &= ~(TCSTATUS_A | TCSTATUS_DA); | 1460 | tmp &= ~(TCSTATUS_A | TCSTATUS_DA); |
1255 | tmp |= TCSTATUS_IXMT; /* interrupt exempt */ | 1461 | tmp |= TCSTATUS_IXMT; /* interrupt exempt */ |
1256 | write_tc_c0_tcstatus(tmp); | 1462 | write_tc_c0_tcstatus(tmp); |
@@ -1262,6 +1468,9 @@ static int __init vpe_module_init(void) | |||
1262 | /* release config state */ | 1468 | /* release config state */ |
1263 | clear_c0_mvpcontrol(MVPCONTROL_VPC); | 1469 | clear_c0_mvpcontrol(MVPCONTROL_VPC); |
1264 | 1470 | ||
1471 | #ifdef CONFIG_MIPS_APSP_KSPD | ||
1472 | kspd_events.kspd_sp_exit = kspd_sp_exit; | ||
1473 | #endif | ||
1265 | return 0; | 1474 | return 0; |
1266 | } | 1475 | } |
1267 | 1476 | ||
@@ -1281,5 +1490,5 @@ static void __exit vpe_module_exit(void) | |||
1281 | module_init(vpe_module_init); | 1490 | module_init(vpe_module_init); |
1282 | module_exit(vpe_module_exit); | 1491 | module_exit(vpe_module_exit); |
1283 | MODULE_DESCRIPTION("MIPS VPE Loader"); | 1492 | MODULE_DESCRIPTION("MIPS VPE Loader"); |
1284 | MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc"); | 1493 | MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc."); |
1285 | MODULE_LICENSE("GPL"); | 1494 | MODULE_LICENSE("GPL"); |
diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile index 0d5aec436725..99f5046fdf49 100644 --- a/arch/mips/lasat/Makefile +++ b/arch/mips/lasat/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += reset.o setup.o prom.o lasat_board.o \ | 5 | obj-y += reset.o setup.o prom.o lasat_board.o \ |
6 | at93c.o interrupt.o lasatIRQ.o | 6 | at93c.o interrupt.o |
7 | 7 | ||
8 | obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o | 8 | obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o |
9 | obj-$(CONFIG_DS1603) += ds1603.o | 9 | obj-$(CONFIG_DS1603) += ds1603.o |
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index 852a41901a5e..2d3472b21ebb 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c | |||
@@ -27,14 +27,13 @@ | |||
27 | #include <asm/bootinfo.h> | 27 | #include <asm/bootinfo.h> |
28 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
29 | #include <asm/lasat/lasatint.h> | 29 | #include <asm/lasat/lasatint.h> |
30 | #include <asm/time.h> | ||
30 | #include <asm/gdb-stub.h> | 31 | #include <asm/gdb-stub.h> |
31 | 32 | ||
32 | static volatile int *lasat_int_status = NULL; | 33 | static volatile int *lasat_int_status = NULL; |
33 | static volatile int *lasat_int_mask = NULL; | 34 | static volatile int *lasat_int_mask = NULL; |
34 | static volatile int lasat_int_mask_shift; | 35 | static volatile int lasat_int_mask_shift; |
35 | 36 | ||
36 | extern asmlinkage void lasatIRQ(void); | ||
37 | |||
38 | void disable_lasat_irq(unsigned int irq_nr) | 37 | void disable_lasat_irq(unsigned int irq_nr) |
39 | { | 38 | { |
40 | unsigned long flags; | 39 | unsigned long flags; |
@@ -109,11 +108,17 @@ static unsigned long get_int_status_200(void) | |||
109 | return int_status; | 108 | return int_status; |
110 | } | 109 | } |
111 | 110 | ||
112 | void lasat_hw0_irqdispatch(struct pt_regs *regs) | 111 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
113 | { | 112 | { |
114 | unsigned long int_status; | 113 | unsigned long int_status; |
114 | unsigned int cause = read_c0_cause(); | ||
115 | int irq; | 115 | int irq; |
116 | 116 | ||
117 | if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */ | ||
118 | ll_timer_interrupt(7, regs); | ||
119 | return; | ||
120 | } | ||
121 | |||
117 | int_status = get_int_status(); | 122 | int_status = get_int_status(); |
118 | 123 | ||
119 | /* if int_status == 0, then the interrupt has already been cleared */ | 124 | /* if int_status == 0, then the interrupt has already been cleared */ |
@@ -147,9 +152,6 @@ void __init arch_init_irq(void) | |||
147 | panic("arch_init_irq: mips_machtype incorrect"); | 152 | panic("arch_init_irq: mips_machtype incorrect"); |
148 | } | 153 | } |
149 | 154 | ||
150 | /* Now safe to set the exception vector. */ | ||
151 | set_except_vector(0, lasatIRQ); | ||
152 | |||
153 | for (i = 0; i <= LASATINT_END; i++) { | 155 | for (i = 0; i <= LASATINT_END; i++) { |
154 | irq_desc[i].status = IRQ_DISABLED; | 156 | irq_desc[i].status = IRQ_DISABLED; |
155 | irq_desc[i].action = 0; | 157 | irq_desc[i].action = 0; |
diff --git a/arch/mips/lasat/lasatIRQ.S b/arch/mips/lasat/lasatIRQ.S deleted file mode 100644 index 2a2b0d056561..000000000000 --- a/arch/mips/lasat/lasatIRQ.S +++ /dev/null | |||
@@ -1,69 +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 | * Interrupt exception dispatch code. | ||
19 | */ | ||
20 | #include <asm/asm.h> | ||
21 | #include <asm/mipsregs.h> | ||
22 | #include <asm/regdef.h> | ||
23 | #include <asm/stackframe.h> | ||
24 | |||
25 | .text | ||
26 | .set noreorder | ||
27 | .align 5 | ||
28 | NESTED(lasatIRQ, PT_SIZE, sp) | ||
29 | .set noat | ||
30 | SAVE_ALL | ||
31 | CLI | ||
32 | .set at | ||
33 | .set noreorder | ||
34 | |||
35 | mfc0 s0, CP0_CAUSE # get irq mask | ||
36 | |||
37 | /* First we check for r4k counter/timer IRQ. */ | ||
38 | andi a0, s0, CAUSEF_IP7 | ||
39 | beq a0, zero, 1f | ||
40 | andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt | ||
41 | |||
42 | /* Wheee, a timer interrupt. */ | ||
43 | li a0, 7 | ||
44 | jal ll_timer_interrupt | ||
45 | move a1, sp | ||
46 | |||
47 | j ret_from_irq | ||
48 | nop | ||
49 | |||
50 | 1: | ||
51 | /* Wheee, combined hardware level zero interrupt. */ | ||
52 | jal lasat_hw0_irqdispatch | ||
53 | move a0, sp # delay slot | ||
54 | |||
55 | j ret_from_irq | ||
56 | nop # delay slot | ||
57 | |||
58 | 1: | ||
59 | /* | ||
60 | * Here by mistake? This is possible, what can happen is that by the | ||
61 | * time we take the exception the IRQ pin goes low, so just leave if | ||
62 | * this is the case. | ||
63 | */ | ||
64 | move a1,s0 | ||
65 | mfc0 a1, CP0_EPC | ||
66 | |||
67 | j ret_from_irq | ||
68 | nop | ||
69 | END(lasatIRQ) | ||
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c index bc0ebc69bfb3..db53950b7cfb 100644 --- a/arch/mips/mips-boards/atlas/atlas_int.c +++ b/arch/mips/mips-boards/atlas/atlas_int.c | |||
@@ -39,8 +39,6 @@ | |||
39 | 39 | ||
40 | static struct atlas_ictrl_regs *atlas_hw0_icregs; | 40 | static struct atlas_ictrl_regs *atlas_hw0_icregs; |
41 | 41 | ||
42 | extern asmlinkage void mipsIRQ(void); | ||
43 | |||
44 | #if 0 | 42 | #if 0 |
45 | #define DEBUG_INT(x...) printk(x) | 43 | #define DEBUG_INT(x...) printk(x) |
46 | #else | 44 | #else |
@@ -98,7 +96,7 @@ static inline int ls1bit32(unsigned int x) | |||
98 | return b; | 96 | return b; |
99 | } | 97 | } |
100 | 98 | ||
101 | void atlas_hw0_irqdispatch(struct pt_regs *regs) | 99 | static inline void atlas_hw0_irqdispatch(struct pt_regs *regs) |
102 | { | 100 | { |
103 | unsigned long int_status; | 101 | unsigned long int_status; |
104 | int irq; | 102 | int irq; |
@@ -116,6 +114,91 @@ void atlas_hw0_irqdispatch(struct pt_regs *regs) | |||
116 | do_IRQ(irq, regs); | 114 | do_IRQ(irq, regs); |
117 | } | 115 | } |
118 | 116 | ||
117 | static inline int clz(unsigned long x) | ||
118 | { | ||
119 | __asm__ ( | ||
120 | " .set push \n" | ||
121 | " .set mips32 \n" | ||
122 | " clz %0, %1 \n" | ||
123 | " .set pop \n" | ||
124 | : "=r" (x) | ||
125 | : "r" (x)); | ||
126 | |||
127 | return x; | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * Version of ffs that only looks at bits 12..15. | ||
132 | */ | ||
133 | static inline unsigned int irq_ffs(unsigned int pending) | ||
134 | { | ||
135 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
136 | return -clz(pending) + 31 - CAUSEB_IP; | ||
137 | #else | ||
138 | unsigned int a0 = 7; | ||
139 | unsigned int t0; | ||
140 | |||
141 | t0 = s0 & 0xf000; | ||
142 | t0 = t0 < 1; | ||
143 | t0 = t0 << 2; | ||
144 | a0 = a0 - t0; | ||
145 | s0 = s0 << t0; | ||
146 | |||
147 | t0 = s0 & 0xc000; | ||
148 | t0 = t0 < 1; | ||
149 | t0 = t0 << 1; | ||
150 | a0 = a0 - t0; | ||
151 | s0 = s0 << t0; | ||
152 | |||
153 | t0 = s0 & 0x8000; | ||
154 | t0 = t0 < 1; | ||
155 | //t0 = t0 << 2; | ||
156 | a0 = a0 - t0; | ||
157 | //s0 = s0 << t0; | ||
158 | |||
159 | return a0; | ||
160 | #endif | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * IRQs on the Atlas board look basically (barring software IRQs which we | ||
165 | * don't use at all and all external interrupt sources are combined together | ||
166 | * on hardware interrupt 0 (MIPS IRQ 2)) like: | ||
167 | * | ||
168 | * MIPS IRQ Source | ||
169 | * -------- ------ | ||
170 | * 0 Software (ignored) | ||
171 | * 1 Software (ignored) | ||
172 | * 2 Combined hardware interrupt (hw0) | ||
173 | * 3 Hardware (ignored) | ||
174 | * 4 Hardware (ignored) | ||
175 | * 5 Hardware (ignored) | ||
176 | * 6 Hardware (ignored) | ||
177 | * 7 R4k timer (what we use) | ||
178 | * | ||
179 | * We handle the IRQ according to _our_ priority which is: | ||
180 | * | ||
181 | * Highest ---- R4k Timer | ||
182 | * Lowest ---- Combined hardware interrupt | ||
183 | * | ||
184 | * then we just return, if multiple IRQs are pending then we will just take | ||
185 | * another exception, big deal. | ||
186 | */ | ||
187 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
188 | { | ||
189 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
190 | int irq; | ||
191 | |||
192 | irq = irq_ffs(pending); | ||
193 | |||
194 | if (irq == MIPSCPU_INT_ATLAS) | ||
195 | atlas_hw0_irqdispatch(regs); | ||
196 | else if (irq > 0) | ||
197 | do_IRQ(MIPSCPU_INT_BASE + irq, regs); | ||
198 | else | ||
199 | spurious_interrupt(regs); | ||
200 | } | ||
201 | |||
119 | void __init arch_init_irq(void) | 202 | void __init arch_init_irq(void) |
120 | { | 203 | { |
121 | int i; | 204 | int i; |
@@ -128,9 +211,6 @@ void __init arch_init_irq(void) | |||
128 | */ | 211 | */ |
129 | atlas_hw0_icregs->intrsten = 0xffffffff; | 212 | atlas_hw0_icregs->intrsten = 0xffffffff; |
130 | 213 | ||
131 | /* Now safe to set the exception vector. */ | ||
132 | set_except_vector(0, mipsIRQ); | ||
133 | |||
134 | for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { | 214 | for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { |
135 | irq_desc[i].status = IRQ_DISABLED; | 215 | irq_desc[i].status = IRQ_DISABLED; |
136 | irq_desc[i].action = 0; | 216 | irq_desc[i].action = 0; |
diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile index b21bc6887fa8..be47c1c2bc80 100644 --- a/arch/mips/mips-boards/generic/Makefile +++ b/arch/mips/mips-boards/generic/Makefile | |||
@@ -18,8 +18,8 @@ | |||
18 | # Makefile for the MIPS boards generic routines under Linux. | 18 | # Makefile for the MIPS boards generic routines under Linux. |
19 | # | 19 | # |
20 | 20 | ||
21 | obj-y := mipsIRQ.o reset.o display.o init.o memory.o \ | 21 | obj-y := reset.o display.o init.o memory.o printf.o \ |
22 | printf.o cmdline.o time.o | 22 | cmdline.o time.o |
23 | obj-$(CONFIG_PCI) += pci.o | 23 | obj-$(CONFIG_PCI) += pci.o |
24 | obj-$(CONFIG_KGDB) += gdb_hook.o | 24 | obj-$(CONFIG_KGDB) += gdb_hook.o |
25 | 25 | ||
diff --git a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c index 91a2ccbe3730..6a1854de4579 100644 --- a/arch/mips/mips-boards/generic/gdb_hook.c +++ b/arch/mips/mips-boards/generic/gdb_hook.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <asm/serial.h> | 25 | #include <asm/serial.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | 27 | ||
28 | static struct serial_state rs_table[RS_TABLE_SIZE] = { | 28 | static struct serial_state rs_table[] = { |
29 | SERIAL_PORT_DFNS /* Defined in serial.h */ | 29 | SERIAL_PORT_DFNS /* Defined in serial.h */ |
30 | }; | 30 | }; |
31 | 31 | ||
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c index eab5a705e989..17dfe6a8cab9 100644 --- a/arch/mips/mips-boards/generic/init.c +++ b/arch/mips/mips-boards/generic/init.c | |||
@@ -220,7 +220,6 @@ void __init kgdb_config (void) | |||
220 | generic_putDebugChar (*s++); | 220 | generic_putDebugChar (*s++); |
221 | } | 221 | } |
222 | 222 | ||
223 | kgdb_enabled = 1; | ||
224 | /* Breakpoint is invoked after interrupts are initialised */ | 223 | /* Breakpoint is invoked after interrupts are initialised */ |
225 | } | 224 | } |
226 | } | 225 | } |
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c index 32c9210373ac..bc4d093685bb 100644 --- a/arch/mips/mips-boards/generic/memory.c +++ b/arch/mips/mips-boards/generic/memory.c | |||
@@ -22,10 +22,12 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/bootmem.h> | 24 | #include <linux/bootmem.h> |
25 | #include <linux/pfn.h> | ||
25 | #include <linux/string.h> | 26 | #include <linux/string.h> |
26 | 27 | ||
27 | #include <asm/bootinfo.h> | 28 | #include <asm/bootinfo.h> |
28 | #include <asm/page.h> | 29 | #include <asm/page.h> |
30 | #include <asm/sections.h> | ||
29 | 31 | ||
30 | #include <asm/mips-boards/prom.h> | 32 | #include <asm/mips-boards/prom.h> |
31 | 33 | ||
@@ -46,9 +48,6 @@ static char *mtypes[3] = { | |||
46 | }; | 48 | }; |
47 | #endif | 49 | #endif |
48 | 50 | ||
49 | /* References to section boundaries */ | ||
50 | extern char _end; | ||
51 | |||
52 | struct prom_pmemblock * __init prom_getmdesc(void) | 51 | struct prom_pmemblock * __init prom_getmdesc(void) |
53 | { | 52 | { |
54 | char *memsize_str; | 53 | char *memsize_str; |
@@ -106,10 +105,10 @@ struct prom_pmemblock * __init prom_getmdesc(void) | |||
106 | 105 | ||
107 | mdesc[3].type = yamon_dontuse; | 106 | mdesc[3].type = yamon_dontuse; |
108 | mdesc[3].base = 0x00100000; | 107 | mdesc[3].base = 0x00100000; |
109 | mdesc[3].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[3].base; | 108 | mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base; |
110 | 109 | ||
111 | mdesc[4].type = yamon_free; | 110 | mdesc[4].type = yamon_free; |
112 | mdesc[4].base = CPHYSADDR(PAGE_ALIGN(&_end)); | 111 | mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); |
113 | mdesc[4].size = memsize - mdesc[4].base; | 112 | mdesc[4].size = memsize - mdesc[4].base; |
114 | 113 | ||
115 | return &mdesc[0]; | 114 | return &mdesc[0]; |
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S deleted file mode 100644 index ddd5c73a2971..000000000000 --- a/arch/mips/mips-boards/generic/mipsIRQ.S +++ /dev/null | |||
@@ -1,155 +0,0 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999, 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 | * Interrupt exception dispatch code. | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/config.h> | ||
26 | |||
27 | #include <asm/asm.h> | ||
28 | #include <asm/mipsregs.h> | ||
29 | #include <asm/regdef.h> | ||
30 | #include <asm/stackframe.h> | ||
31 | |||
32 | #ifdef CONFIG_MIPS_ATLAS | ||
33 | #include <asm/mips-boards/atlasint.h> | ||
34 | #define CASCADE_IRQ MIPSCPU_INT_ATLAS | ||
35 | #define CASCADE_DISPATCH atlas_hw0_irqdispatch | ||
36 | #endif | ||
37 | #ifdef CONFIG_MIPS_MALTA | ||
38 | #include <asm/mips-boards/maltaint.h> | ||
39 | #define CASCADE_IRQ MIPSCPU_INT_I8259A | ||
40 | #define CASCADE_DISPATCH malta_hw0_irqdispatch | ||
41 | #endif | ||
42 | #ifdef CONFIG_MIPS_SEAD | ||
43 | #include <asm/mips-boards/seadint.h> | ||
44 | #endif | ||
45 | |||
46 | /* A lot of complication here is taken away because: | ||
47 | * | ||
48 | * 1) We handle one interrupt and return, sitting in a loop and moving across | ||
49 | * all the pending IRQ bits in the cause register is _NOT_ the answer, the | ||
50 | * common case is one pending IRQ so optimize in that direction. | ||
51 | * | ||
52 | * 2) We need not check against bits in the status register IRQ mask, that | ||
53 | * would make this routine slow as hell. | ||
54 | * | ||
55 | * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in | ||
56 | * between like BSD spl() brain-damage. | ||
57 | * | ||
58 | * Furthermore, the IRQs on the MIPS board look basically (barring software | ||
59 | * IRQs which we don't use at all and all external interrupt sources are | ||
60 | * combined together on hardware interrupt 0 (MIPS IRQ 2)) like: | ||
61 | * | ||
62 | * MIPS IRQ Source | ||
63 | * -------- ------ | ||
64 | * 0 Software (ignored) | ||
65 | * 1 Software (ignored) | ||
66 | * 2 Combined hardware interrupt (hw0) | ||
67 | * 3 Hardware (ignored) | ||
68 | * 4 Hardware (ignored) | ||
69 | * 5 Hardware (ignored) | ||
70 | * 6 Hardware (ignored) | ||
71 | * 7 R4k timer (what we use) | ||
72 | * | ||
73 | * Note: On the SEAD board thing are a little bit different. | ||
74 | * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired | ||
75 | * wired to UART1. | ||
76 | * | ||
77 | * We handle the IRQ according to _our_ priority which is: | ||
78 | * | ||
79 | * Highest ---- R4k Timer | ||
80 | * Lowest ---- Combined hardware interrupt | ||
81 | * | ||
82 | * then we just return, if multiple IRQs are pending then we will just take | ||
83 | * another exception, big deal. | ||
84 | */ | ||
85 | |||
86 | .text | ||
87 | .set noreorder | ||
88 | .set noat | ||
89 | .align 5 | ||
90 | NESTED(mipsIRQ, PT_SIZE, sp) | ||
91 | SAVE_ALL | ||
92 | CLI | ||
93 | .set at | ||
94 | |||
95 | mfc0 s0, CP0_CAUSE # get irq bits | ||
96 | mfc0 s1, CP0_STATUS # get irq mask | ||
97 | andi s0, ST0_IM # CAUSE.CE may be non-zero! | ||
98 | and s0, s1 | ||
99 | |||
100 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
101 | .set mips32 | ||
102 | clz a0, s0 | ||
103 | .set mips0 | ||
104 | negu a0 | ||
105 | addu a0, 31-CAUSEB_IP | ||
106 | bltz a0, spurious | ||
107 | #else | ||
108 | beqz s0, spurious | ||
109 | li a0, 7 | ||
110 | |||
111 | and t0, s0, 0xf000 | ||
112 | sltiu t0, t0, 1 | ||
113 | sll t0, 2 | ||
114 | subu a0, t0 | ||
115 | sll s0, t0 | ||
116 | |||
117 | and t0, s0, 0xc000 | ||
118 | sltiu t0, t0, 1 | ||
119 | sll t0, 1 | ||
120 | subu a0, t0 | ||
121 | sll s0, t0 | ||
122 | |||
123 | and t0, s0, 0x8000 | ||
124 | sltiu t0, t0, 1 | ||
125 | # sll t0, 0 | ||
126 | subu a0, t0 | ||
127 | # sll s0, t0 | ||
128 | #endif | ||
129 | |||
130 | #ifdef CASCADE_IRQ | ||
131 | li a1, CASCADE_IRQ | ||
132 | bne a0, a1, 1f | ||
133 | addu a0, MIPSCPU_INT_BASE | ||
134 | |||
135 | jal CASCADE_DISPATCH | ||
136 | move a0, sp | ||
137 | |||
138 | j ret_from_irq | ||
139 | nop | ||
140 | 1: | ||
141 | #else | ||
142 | addu a0, MIPSCPU_INT_BASE | ||
143 | #endif | ||
144 | |||
145 | jal do_IRQ | ||
146 | move a1, sp | ||
147 | |||
148 | j ret_from_irq | ||
149 | nop | ||
150 | |||
151 | |||
152 | spurious: | ||
153 | j spurious_interrupt | ||
154 | nop | ||
155 | END(mipsIRQ) | ||
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 93f3bf2c2b22..a9f6124b3a22 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/mc146818rtc.h> | 30 | #include <linux/mc146818rtc.h> |
31 | 31 | ||
32 | #include <asm/mipsregs.h> | 32 | #include <asm/mipsregs.h> |
33 | #include <asm/mipsmtregs.h> | ||
33 | #include <asm/ptrace.h> | 34 | #include <asm/ptrace.h> |
34 | #include <asm/hardirq.h> | 35 | #include <asm/hardirq.h> |
35 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
@@ -50,16 +51,23 @@ unsigned long cpu_khz; | |||
50 | static char display_string[] = " LINUX ON ATLAS "; | 51 | static char display_string[] = " LINUX ON ATLAS "; |
51 | #endif | 52 | #endif |
52 | #if defined(CONFIG_MIPS_MALTA) | 53 | #if defined(CONFIG_MIPS_MALTA) |
54 | #if defined(CONFIG_MIPS_MT_SMTC) | ||
55 | static char display_string[] = " SMTC LINUX ON MALTA "; | ||
56 | #else | ||
53 | static char display_string[] = " LINUX ON MALTA "; | 57 | static char display_string[] = " LINUX ON MALTA "; |
58 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
54 | #endif | 59 | #endif |
55 | #if defined(CONFIG_MIPS_SEAD) | 60 | #if defined(CONFIG_MIPS_SEAD) |
56 | static char display_string[] = " LINUX ON SEAD "; | 61 | static char display_string[] = " LINUX ON SEAD "; |
57 | #endif | 62 | #endif |
58 | static unsigned int display_count = 0; | 63 | static unsigned int display_count; |
59 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) | 64 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) |
60 | 65 | ||
61 | static unsigned int timer_tick_count=0; | 66 | #define CPUCTR_IMASKBIT (0x100 << MIPSCPU_INT_CPUCTR) |
67 | |||
68 | static unsigned int timer_tick_count; | ||
62 | static int mips_cpu_timer_irq; | 69 | static int mips_cpu_timer_irq; |
70 | extern void smtc_timer_broadcast(int); | ||
63 | 71 | ||
64 | static inline void scroll_display_message(void) | 72 | static inline void scroll_display_message(void) |
65 | { | 73 | { |
@@ -75,15 +83,55 @@ static void mips_timer_dispatch (struct pt_regs *regs) | |||
75 | do_IRQ (mips_cpu_timer_irq, regs); | 83 | do_IRQ (mips_cpu_timer_irq, regs); |
76 | } | 84 | } |
77 | 85 | ||
86 | /* | ||
87 | * Redeclare until I get around mopping the timer code insanity on MIPS. | ||
88 | */ | ||
78 | extern int null_perf_irq(struct pt_regs *regs); | 89 | extern int null_perf_irq(struct pt_regs *regs); |
79 | 90 | ||
80 | extern int (*perf_irq)(struct pt_regs *regs); | 91 | extern int (*perf_irq)(struct pt_regs *regs); |
81 | 92 | ||
82 | irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 93 | irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
83 | { | 94 | { |
84 | int r2 = cpu_has_mips_r2; | ||
85 | int cpu = smp_processor_id(); | 95 | int cpu = smp_processor_id(); |
96 | int r2 = cpu_has_mips_r2; | ||
97 | |||
98 | #ifdef CONFIG_MIPS_MT_SMTC | ||
99 | /* | ||
100 | * In an SMTC system, one Count/Compare set exists per VPE. | ||
101 | * Which TC within a VPE gets the interrupt is essentially | ||
102 | * random - we only know that it shouldn't be one with | ||
103 | * IXMT set. Whichever TC gets the interrupt needs to | ||
104 | * send special interprocessor interrupts to the other | ||
105 | * TCs to make sure that they schedule, etc. | ||
106 | * | ||
107 | * That code is specific to the SMTC kernel, not to | ||
108 | * the a particular platform, so it's invoked from | ||
109 | * the general MIPS timer_interrupt routine. | ||
110 | */ | ||
111 | |||
112 | /* | ||
113 | * DVPE is necessary so long as cross-VPE interrupts | ||
114 | * are done via read-modify-write of Cause register. | ||
115 | */ | ||
116 | int vpflags = dvpe(); | ||
117 | write_c0_compare (read_c0_count() - 1); | ||
118 | clear_c0_cause(CPUCTR_IMASKBIT); | ||
119 | evpe(vpflags); | ||
120 | |||
121 | if (cpu_data[cpu].vpe_id == 0) { | ||
122 | timer_interrupt(irq, dev_id, regs); | ||
123 | scroll_display_message(); | ||
124 | } else | ||
125 | write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ)); | ||
126 | smtc_timer_broadcast(cpu_data[cpu].vpe_id); | ||
86 | 127 | ||
128 | if (cpu != 0) | ||
129 | /* | ||
130 | * Other CPUs should do profiling and process accounting | ||
131 | */ | ||
132 | local_timer_interrupt(irq, dev_id, regs); | ||
133 | |||
134 | #else /* CONFIG_MIPS_MT_SMTC */ | ||
87 | if (cpu == 0) { | 135 | if (cpu == 0) { |
88 | /* | 136 | /* |
89 | * CPU 0 handles the global timer interrupt job and process | 137 | * CPU 0 handles the global timer interrupt job and process |
@@ -107,12 +155,14 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
107 | * More support needs to be added to kernel/time for | 155 | * More support needs to be added to kernel/time for |
108 | * counter/timer interrupts on multiple CPU's | 156 | * counter/timer interrupts on multiple CPU's |
109 | */ | 157 | */ |
110 | write_c0_compare (read_c0_count() + (mips_hpt_frequency/HZ)); | 158 | write_c0_compare(read_c0_count() + (mips_hpt_frequency/HZ)); |
159 | |||
111 | /* | 160 | /* |
112 | * other CPUs should do profiling and process accounting | 161 | * Other CPUs should do profiling and process accounting |
113 | */ | 162 | */ |
114 | local_timer_interrupt (irq, dev_id, regs); | 163 | local_timer_interrupt(irq, dev_id, regs); |
115 | } | 164 | } |
165 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
116 | 166 | ||
117 | out: | 167 | out: |
118 | return IRQ_HANDLED; | 168 | return IRQ_HANDLED; |
@@ -126,7 +176,7 @@ static unsigned int __init estimate_cpu_frequency(void) | |||
126 | unsigned int prid = read_c0_prid() & 0xffff00; | 176 | unsigned int prid = read_c0_prid() & 0xffff00; |
127 | unsigned int count; | 177 | unsigned int count; |
128 | 178 | ||
129 | #ifdef CONFIG_MIPS_SEAD | 179 | #if defined(CONFIG_MIPS_SEAD) || defined(CONFIG_MIPS_SIM) |
130 | /* | 180 | /* |
131 | * The SEAD board doesn't have a real time clock, so we can't | 181 | * The SEAD board doesn't have a real time clock, so we can't |
132 | * really calculate the timer frequency | 182 | * really calculate the timer frequency |
@@ -211,7 +261,11 @@ void __init mips_timer_setup(struct irqaction *irq) | |||
211 | 261 | ||
212 | /* we are using the cpu counter for timer interrupts */ | 262 | /* we are using the cpu counter for timer interrupts */ |
213 | irq->handler = mips_timer_interrupt; /* we use our own handler */ | 263 | irq->handler = mips_timer_interrupt; /* we use our own handler */ |
264 | #ifdef CONFIG_MIPS_MT_SMTC | ||
265 | setup_irq_smtc(mips_cpu_timer_irq, irq, CPUCTR_IMASKBIT); | ||
266 | #else | ||
214 | setup_irq(mips_cpu_timer_irq, irq); | 267 | setup_irq(mips_cpu_timer_irq, irq); |
268 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
215 | 269 | ||
216 | #ifdef CONFIG_SMP | 270 | #ifdef CONFIG_SMP |
217 | /* irq_desc(riptor) is a global resource, when the interrupt overlaps | 271 | /* irq_desc(riptor) is a global resource, when the interrupt overlaps |
diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile index fd4c143c0e2f..77ee5c6d33c1 100644 --- a/arch/mips/mips-boards/malta/Makefile +++ b/arch/mips/mips-boards/malta/Makefile | |||
@@ -20,3 +20,4 @@ | |||
20 | # | 20 | # |
21 | 21 | ||
22 | obj-y := malta_int.o malta_setup.o | 22 | obj-y := malta_int.o malta_setup.o |
23 | obj-$(CONFIG_SMP) += malta_smp.o | ||
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index d06dc5ad6c9e..64db07d4dbe5 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <asm/mips-boards/msc01_pci.h> | 40 | #include <asm/mips-boards/msc01_pci.h> |
41 | #include <asm/msc01_ic.h> | 41 | #include <asm/msc01_ic.h> |
42 | 42 | ||
43 | extern asmlinkage void mipsIRQ(void); | ||
44 | extern void mips_timer_interrupt(void); | 43 | extern void mips_timer_interrupt(void); |
45 | 44 | ||
46 | static DEFINE_SPINLOCK(mips_irq_lock); | 45 | static DEFINE_SPINLOCK(mips_irq_lock); |
@@ -114,13 +113,14 @@ static inline int get_int(void) | |||
114 | return irq; | 113 | return irq; |
115 | } | 114 | } |
116 | 115 | ||
117 | void malta_hw0_irqdispatch(struct pt_regs *regs) | 116 | static void malta_hw0_irqdispatch(struct pt_regs *regs) |
118 | { | 117 | { |
119 | int irq; | 118 | int irq; |
120 | 119 | ||
121 | irq = get_int(); | 120 | irq = get_int(); |
122 | if (irq < 0) | 121 | if (irq < 0) { |
123 | return; /* interrupt has already been cleared */ | 122 | return; /* interrupt has already been cleared */ |
123 | } | ||
124 | 124 | ||
125 | do_IRQ(MALTA_INT_BASE+irq, regs); | 125 | do_IRQ(MALTA_INT_BASE+irq, regs); |
126 | } | 126 | } |
@@ -182,6 +182,92 @@ void corehi_irqdispatch(struct pt_regs *regs) | |||
182 | die("CoreHi interrupt", regs); | 182 | die("CoreHi interrupt", regs); |
183 | } | 183 | } |
184 | 184 | ||
185 | static inline int clz(unsigned long x) | ||
186 | { | ||
187 | __asm__ ( | ||
188 | " .set push \n" | ||
189 | " .set mips32 \n" | ||
190 | " clz %0, %1 \n" | ||
191 | " .set pop \n" | ||
192 | : "=r" (x) | ||
193 | : "r" (x)); | ||
194 | |||
195 | return x; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Version of ffs that only looks at bits 12..15. | ||
200 | */ | ||
201 | static inline unsigned int irq_ffs(unsigned int pending) | ||
202 | { | ||
203 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
204 | return -clz(pending) + 31 - CAUSEB_IP; | ||
205 | #else | ||
206 | unsigned int a0 = 7; | ||
207 | unsigned int t0; | ||
208 | |||
209 | t0 = s0 & 0xf000; | ||
210 | t0 = t0 < 1; | ||
211 | t0 = t0 << 2; | ||
212 | a0 = a0 - t0; | ||
213 | s0 = s0 << t0; | ||
214 | |||
215 | t0 = s0 & 0xc000; | ||
216 | t0 = t0 < 1; | ||
217 | t0 = t0 << 1; | ||
218 | a0 = a0 - t0; | ||
219 | s0 = s0 << t0; | ||
220 | |||
221 | t0 = s0 & 0x8000; | ||
222 | t0 = t0 < 1; | ||
223 | //t0 = t0 << 2; | ||
224 | a0 = a0 - t0; | ||
225 | //s0 = s0 << t0; | ||
226 | |||
227 | return a0; | ||
228 | #endif | ||
229 | } | ||
230 | |||
231 | /* | ||
232 | * IRQs on the Malta board look basically (barring software IRQs which we | ||
233 | * don't use at all and all external interrupt sources are combined together | ||
234 | * on hardware interrupt 0 (MIPS IRQ 2)) like: | ||
235 | * | ||
236 | * MIPS IRQ Source | ||
237 | * -------- ------ | ||
238 | * 0 Software (ignored) | ||
239 | * 1 Software (ignored) | ||
240 | * 2 Combined hardware interrupt (hw0) | ||
241 | * 3 Hardware (ignored) | ||
242 | * 4 Hardware (ignored) | ||
243 | * 5 Hardware (ignored) | ||
244 | * 6 Hardware (ignored) | ||
245 | * 7 R4k timer (what we use) | ||
246 | * | ||
247 | * We handle the IRQ according to _our_ priority which is: | ||
248 | * | ||
249 | * Highest ---- R4k Timer | ||
250 | * Lowest ---- Combined hardware interrupt | ||
251 | * | ||
252 | * then we just return, if multiple IRQs are pending then we will just take | ||
253 | * another exception, big deal. | ||
254 | */ | ||
255 | |||
256 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
257 | { | ||
258 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
259 | int irq; | ||
260 | |||
261 | irq = irq_ffs(pending); | ||
262 | |||
263 | if (irq == MIPSCPU_INT_I8259A) | ||
264 | malta_hw0_irqdispatch(regs); | ||
265 | else if (irq > 0) | ||
266 | do_IRQ(MIPSCPU_INT_BASE + irq, regs); | ||
267 | else | ||
268 | spurious_interrupt(regs); | ||
269 | } | ||
270 | |||
185 | static struct irqaction i8259irq = { | 271 | static struct irqaction i8259irq = { |
186 | .handler = no_action, | 272 | .handler = no_action, |
187 | .name = "XT-PIC cascade" | 273 | .name = "XT-PIC cascade" |
@@ -214,7 +300,6 @@ int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap)/sizeof(msc_irqmap_t); | |||
214 | 300 | ||
215 | void __init arch_init_irq(void) | 301 | void __init arch_init_irq(void) |
216 | { | 302 | { |
217 | set_except_vector(0, mipsIRQ); | ||
218 | init_i8259_irqs(); | 303 | init_i8259_irqs(); |
219 | 304 | ||
220 | if (!cpu_has_veic) | 305 | if (!cpu_has_veic) |
@@ -240,12 +325,17 @@ void __init arch_init_irq(void) | |||
240 | else if (cpu_has_vint) { | 325 | else if (cpu_has_vint) { |
241 | set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); | 326 | set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); |
242 | set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch); | 327 | set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch); |
243 | 328 | #ifdef CONFIG_MIPS_MT_SMTC | |
329 | setup_irq_smtc (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq, | ||
330 | (0x100 << MIPSCPU_INT_I8259A)); | ||
331 | setup_irq_smtc (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, | ||
332 | &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI)); | ||
333 | #else /* Not SMTC */ | ||
244 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); | 334 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); |
245 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); | 335 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); |
336 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
246 | } | 337 | } |
247 | else { | 338 | else { |
248 | set_except_vector(0, mipsIRQ); | ||
249 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); | 339 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); |
250 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); | 340 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); |
251 | } | 341 | } |
diff --git a/arch/mips/mips-boards/malta/malta_smp.c b/arch/mips/mips-boards/malta/malta_smp.c new file mode 100644 index 000000000000..6c6c8eeedbce --- /dev/null +++ b/arch/mips/mips-boards/malta/malta_smp.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * Malta Platform-specific hooks for SMP operation | ||
3 | */ | ||
4 | |||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/sched.h> | ||
7 | #include <linux/cpumask.h> | ||
8 | #include <linux/interrupt.h> | ||
9 | |||
10 | #include <asm/atomic.h> | ||
11 | #include <asm/cpu.h> | ||
12 | #include <asm/processor.h> | ||
13 | #include <asm/system.h> | ||
14 | #include <asm/hardirq.h> | ||
15 | #include <asm/mmu_context.h> | ||
16 | #include <asm/smp.h> | ||
17 | #ifdef CONFIG_MIPS_MT_SMTC | ||
18 | #include <asm/smtc_ipi.h> | ||
19 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
20 | |||
21 | /* VPE/SMP Prototype implements platform interfaces directly */ | ||
22 | #if !defined(CONFIG_MIPS_MT_SMP) | ||
23 | |||
24 | /* | ||
25 | * Cause the specified action to be performed on a targeted "CPU" | ||
26 | */ | ||
27 | |||
28 | void core_send_ipi(int cpu, unsigned int action) | ||
29 | { | ||
30 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ | ||
31 | #ifdef CONFIG_MIPS_MT_SMTC | ||
32 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); | ||
33 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * Detect available CPUs/VPEs/TCs and populate phys_cpu_present_map | ||
38 | */ | ||
39 | |||
40 | void __init prom_build_cpu_map(void) | ||
41 | { | ||
42 | int nextslot; | ||
43 | |||
44 | /* | ||
45 | * As of November, 2004, MIPSsim only simulates one core | ||
46 | * at a time. However, that core may be a MIPS MT core | ||
47 | * with multiple virtual processors and thread contexts. | ||
48 | */ | ||
49 | |||
50 | if (read_c0_config3() & (1<<2)) { | ||
51 | nextslot = mipsmt_build_cpu_map(1); | ||
52 | } | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * Platform "CPU" startup hook | ||
57 | */ | ||
58 | |||
59 | void prom_boot_secondary(int cpu, struct task_struct *idle) | ||
60 | { | ||
61 | #ifdef CONFIG_MIPS_MT_SMTC | ||
62 | smtc_boot_secondary(cpu, idle); | ||
63 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
64 | } | ||
65 | |||
66 | /* | ||
67 | * Post-config but pre-boot cleanup entry point | ||
68 | */ | ||
69 | |||
70 | void prom_init_secondary(void) | ||
71 | { | ||
72 | #ifdef CONFIG_MIPS_MT_SMTC | ||
73 | void smtc_init_secondary(void); | ||
74 | int myvpe; | ||
75 | |||
76 | /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ | ||
77 | myvpe = read_c0_tcbind() & TCBIND_CURVPE; | ||
78 | if (myvpe != 0) { | ||
79 | /* Ideally, this should be done only once per VPE, but... */ | ||
80 | clear_c0_status(STATUSF_IP2); | ||
81 | set_c0_status(STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP3 | ||
82 | | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 | ||
83 | | STATUSF_IP7); | ||
84 | } | ||
85 | |||
86 | smtc_init_secondary(); | ||
87 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Platform SMP pre-initialization | ||
92 | * | ||
93 | * As noted above, we can assume a single CPU for now | ||
94 | * but it may be multithreaded. | ||
95 | */ | ||
96 | |||
97 | void plat_smp_setup(void) | ||
98 | { | ||
99 | if (read_c0_config3() & (1<<2)) | ||
100 | mipsmt_build_cpu_map(0); | ||
101 | } | ||
102 | |||
103 | void __init plat_prepare_cpus(unsigned int max_cpus) | ||
104 | { | ||
105 | if (read_c0_config3() & (1<<2)) | ||
106 | mipsmt_prepare_cpus(); | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * SMP initialization finalization entry point | ||
111 | */ | ||
112 | |||
113 | void prom_smp_finish(void) | ||
114 | { | ||
115 | #ifdef CONFIG_MIPS_MT_SMTC | ||
116 | smtc_smp_finish(); | ||
117 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Hook for after all CPUs are online | ||
122 | */ | ||
123 | |||
124 | void prom_cpus_done(void) | ||
125 | { | ||
126 | } | ||
127 | |||
128 | #endif /* CONFIG_MIPS32R2_MT_SMP */ | ||
diff --git a/arch/mips/mips-boards/sead/sead_int.c b/arch/mips/mips-boards/sead/sead_int.c index 90fda0d9915f..9168d934c661 100644 --- a/arch/mips/mips-boards/sead/sead_int.c +++ b/arch/mips/mips-boards/sead/sead_int.c | |||
@@ -24,16 +24,94 @@ | |||
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | 25 | ||
26 | #include <asm/irq_cpu.h> | 26 | #include <asm/irq_cpu.h> |
27 | #include <asm/mipsregs.h> | ||
27 | #include <asm/system.h> | 28 | #include <asm/system.h> |
28 | 29 | ||
29 | #include <asm/mips-boards/seadint.h> | 30 | #include <asm/mips-boards/seadint.h> |
30 | 31 | ||
31 | extern asmlinkage void mipsIRQ(void); | 32 | static inline int clz(unsigned long x) |
33 | { | ||
34 | __asm__ ( | ||
35 | " .set push \n" | ||
36 | " .set mips32 \n" | ||
37 | " clz %0, %1 \n" | ||
38 | " .set pop \n" | ||
39 | : "=r" (x) | ||
40 | : "r" (x)); | ||
41 | |||
42 | return x; | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | * Version of ffs that only looks at bits 12..15. | ||
47 | */ | ||
48 | static inline unsigned int irq_ffs(unsigned int pending) | ||
49 | { | ||
50 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
51 | return -clz(pending) + 31 - CAUSEB_IP; | ||
52 | #else | ||
53 | unsigned int a0 = 7; | ||
54 | unsigned int t0; | ||
55 | |||
56 | t0 = s0 & 0xf000; | ||
57 | t0 = t0 < 1; | ||
58 | t0 = t0 << 2; | ||
59 | a0 = a0 - t0; | ||
60 | s0 = s0 << t0; | ||
61 | |||
62 | t0 = s0 & 0xc000; | ||
63 | t0 = t0 < 1; | ||
64 | t0 = t0 << 1; | ||
65 | a0 = a0 - t0; | ||
66 | s0 = s0 << t0; | ||
67 | |||
68 | t0 = s0 & 0x8000; | ||
69 | t0 = t0 < 1; | ||
70 | //t0 = t0 << 2; | ||
71 | a0 = a0 - t0; | ||
72 | //s0 = s0 << t0; | ||
73 | |||
74 | return a0; | ||
75 | #endif | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * IRQs on the SEAD board look basically are combined together on hardware | ||
80 | * interrupt 0 (MIPS IRQ 2)) like: | ||
81 | * | ||
82 | * MIPS IRQ Source | ||
83 | * -------- ------ | ||
84 | * 0 Software (ignored) | ||
85 | * 1 Software (ignored) | ||
86 | * 2 UART0 (hw0) | ||
87 | * 3 UART1 (hw1) | ||
88 | * 4 Hardware (ignored) | ||
89 | * 5 Hardware (ignored) | ||
90 | * 6 Hardware (ignored) | ||
91 | * 7 R4k timer (what we use) | ||
92 | * | ||
93 | * We handle the IRQ according to _our_ priority which is: | ||
94 | * | ||
95 | * Highest ---- R4k Timer | ||
96 | * Lowest ---- Combined hardware interrupt | ||
97 | * | ||
98 | * then we just return, if multiple IRQs are pending then we will just take | ||
99 | * another exception, big deal. | ||
100 | */ | ||
101 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
102 | { | ||
103 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
104 | int irq; | ||
105 | |||
106 | irq = irq_ffs(pending); | ||
107 | |||
108 | if (irq >= 0) | ||
109 | do_IRQ(MIPSCPU_INT_BASE + irq, regs); | ||
110 | else | ||
111 | spurious_interrupt(regs); | ||
112 | } | ||
32 | 113 | ||
33 | void __init arch_init_irq(void) | 114 | void __init arch_init_irq(void) |
34 | { | 115 | { |
35 | mips_cpu_irq_init(MIPSCPU_INT_BASE); | 116 | mips_cpu_irq_init(MIPSCPU_INT_BASE); |
36 | |||
37 | /* Now safe to set the exception vector. */ | ||
38 | set_except_vector(0, mipsIRQ); | ||
39 | } | 117 | } |
diff --git a/arch/mips/mips-boards/sim/cmdline.c b/arch/mips/mips-boards/sim/cmdline.c deleted file mode 100644 index fef9fbd8e710..000000000000 --- a/arch/mips/mips-boards/sim/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 *)(((int *)(int)_prom_argv)[(index)])) | ||
33 | |||
34 | char arcs_cmdline[CL_SIZE]; | ||
35 | |||
36 | char * __init prom_getcmdline(void) | ||
37 | { | ||
38 | return &(arcs_cmdline[0]); | ||
39 | } | ||
40 | |||
41 | |||
42 | void __init prom_init_cmdline(void) | ||
43 | { | ||
44 | char *cp; | ||
45 | int actr; | ||
46 | |||
47 | actr = 1; /* Always ignore argv[0] */ | ||
48 | |||
49 | cp = &(arcs_cmdline[0]); | ||
50 | while(actr < prom_argc) { | ||
51 | strcpy(cp, prom_argv(actr)); | ||
52 | cp += strlen(prom_argv(actr)); | ||
53 | *cp++ = ' '; | ||
54 | actr++; | ||
55 | } | ||
56 | if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ | ||
57 | --cp; | ||
58 | *cp = '\0'; | ||
59 | } | ||
diff --git a/arch/mips/mips-boards/sim/sim_cmdline.c b/arch/mips/mips-boards/sim/sim_cmdline.c index 9df37c6fca36..c63021a5dc6c 100644 --- a/arch/mips/mips-boards/sim/sim_cmdline.c +++ b/arch/mips/mips-boards/sim/sim_cmdline.c | |||
@@ -26,8 +26,10 @@ char * __init prom_getcmdline(void) | |||
26 | return arcs_cmdline; | 26 | return arcs_cmdline; |
27 | } | 27 | } |
28 | 28 | ||
29 | |||
30 | void __init prom_init_cmdline(void) | 29 | void __init prom_init_cmdline(void) |
31 | { | 30 | { |
32 | /* nothing to do */ | 31 | char *cp; |
32 | cp = arcs_cmdline; | ||
33 | /* Get boot line from environment? */ | ||
34 | *cp = '\0'; | ||
33 | } | 35 | } |
diff --git a/arch/mips/mips-boards/sim/sim_int.c b/arch/mips/mips-boards/sim/sim_int.c index a4d0a2c05031..2c15c8efec4e 100644 --- a/arch/mips/mips-boards/sim/sim_int.c +++ b/arch/mips/mips-boards/sim/sim_int.c | |||
@@ -25,17 +25,71 @@ | |||
25 | 25 | ||
26 | extern void mips_cpu_irq_init(int); | 26 | extern void mips_cpu_irq_init(int); |
27 | 27 | ||
28 | extern asmlinkage void simIRQ(void); | 28 | static inline int clz(unsigned long x) |
29 | { | ||
30 | __asm__ ( | ||
31 | " .set push \n" | ||
32 | " .set mips32 \n" | ||
33 | " clz %0, %1 \n" | ||
34 | " .set pop \n" | ||
35 | : "=r" (x) | ||
36 | : "r" (x)); | ||
37 | |||
38 | return x; | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * Version of ffs that only looks at bits 12..15. | ||
43 | */ | ||
44 | static inline unsigned int irq_ffs(unsigned int pending) | ||
45 | { | ||
46 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
47 | return -clz(pending) + 31 - CAUSEB_IP; | ||
48 | #else | ||
49 | unsigned int a0 = 7; | ||
50 | unsigned int t0; | ||
51 | |||
52 | t0 = s0 & 0xf000; | ||
53 | t0 = t0 < 1; | ||
54 | t0 = t0 << 2; | ||
55 | a0 = a0 - t0; | ||
56 | s0 = s0 << t0; | ||
57 | |||
58 | t0 = s0 & 0xc000; | ||
59 | t0 = t0 < 1; | ||
60 | t0 = t0 << 1; | ||
61 | a0 = a0 - t0; | ||
62 | s0 = s0 << t0; | ||
29 | 63 | ||
30 | asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs) | 64 | t0 = s0 & 0x8000; |
65 | t0 = t0 < 1; | ||
66 | //t0 = t0 << 2; | ||
67 | a0 = a0 - t0; | ||
68 | //s0 = s0 << t0; | ||
69 | |||
70 | return a0; | ||
71 | #endif | ||
72 | } | ||
73 | |||
74 | static inline void sim_hw0_irqdispatch(struct pt_regs *regs) | ||
31 | { | 75 | { |
32 | do_IRQ(2, regs); | 76 | do_IRQ(2, regs); |
33 | } | 77 | } |
34 | 78 | ||
35 | void __init arch_init_irq(void) | 79 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
36 | { | 80 | { |
37 | /* Now safe to set the exception vector. */ | 81 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; |
38 | set_except_vector(0, simIRQ); | 82 | int irq; |
83 | |||
84 | irq = irq_ffs(pending); | ||
39 | 85 | ||
86 | if (irq > 0) | ||
87 | do_IRQ(MIPSCPU_INT_BASE + irq, regs); | ||
88 | else | ||
89 | spurious_interrupt(regs); | ||
90 | } | ||
91 | |||
92 | void __init arch_init_irq(void) | ||
93 | { | ||
40 | mips_cpu_irq_init(MIPSCPU_INT_BASE); | 94 | mips_cpu_irq_init(MIPSCPU_INT_BASE); |
41 | } | 95 | } |
diff --git a/arch/mips/mips-boards/sim/sim_irq.S b/arch/mips/mips-boards/sim/sim_irq.S index da52297a2216..d16cf3822076 100644 --- a/arch/mips/mips-boards/sim/sim_irq.S +++ b/arch/mips/mips-boards/sim/sim_irq.S | |||
@@ -94,6 +94,8 @@ | |||
94 | 94 | ||
95 | 95 | ||
96 | spurious: | 96 | spurious: |
97 | j spurious_interrupt | 97 | jal spurious_interrupt |
98 | nop | ||
99 | j ret_from_irq | ||
98 | nop | 100 | nop |
99 | END(simIRQ) | 101 | END(simIRQ) |
diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mips-boards/sim/sim_mem.c index e57f737bab10..f7ce76983328 100644 --- a/arch/mips/mips-boards/sim/sim_mem.c +++ b/arch/mips/mips-boards/sim/sim_mem.c | |||
@@ -18,9 +18,11 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/bootmem.h> | 20 | #include <linux/bootmem.h> |
21 | #include <linux/pfn.h> | ||
21 | 22 | ||
22 | #include <asm/bootinfo.h> | 23 | #include <asm/bootinfo.h> |
23 | #include <asm/page.h> | 24 | #include <asm/page.h> |
25 | #include <asm/sections.h> | ||
24 | 26 | ||
25 | #include <asm/mips-boards/prom.h> | 27 | #include <asm/mips-boards/prom.h> |
26 | 28 | ||
@@ -39,9 +41,6 @@ static char *mtypes[3] = { | |||
39 | }; | 41 | }; |
40 | #endif | 42 | #endif |
41 | 43 | ||
42 | /* References to section boundaries */ | ||
43 | extern char _end; | ||
44 | |||
45 | struct prom_pmemblock * __init prom_getmdesc(void) | 44 | struct prom_pmemblock * __init prom_getmdesc(void) |
46 | { | 45 | { |
47 | unsigned int memsize; | 46 | unsigned int memsize; |
@@ -61,10 +60,10 @@ struct prom_pmemblock * __init prom_getmdesc(void) | |||
61 | 60 | ||
62 | mdesc[2].type = simmem_reserved; | 61 | mdesc[2].type = simmem_reserved; |
63 | mdesc[2].base = 0x00100000; | 62 | mdesc[2].base = 0x00100000; |
64 | mdesc[2].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[2].base; | 63 | mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base; |
65 | 64 | ||
66 | mdesc[3].type = simmem_free; | 65 | mdesc[3].type = simmem_free; |
67 | mdesc[3].base = CPHYSADDR(PAGE_ALIGN(&_end)); | 66 | mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end)); |
68 | mdesc[3].size = memsize - mdesc[3].base; | 67 | mdesc[3].size = memsize - mdesc[3].base; |
69 | 68 | ||
70 | return &mdesc[0]; | 69 | return &mdesc[0]; |
diff --git a/arch/mips/mips-boards/sim/sim_smp.c b/arch/mips/mips-boards/sim/sim_smp.c index a9f0c2bfe4ad..b7084e7c4bf9 100644 --- a/arch/mips/mips-boards/sim/sim_smp.c +++ b/arch/mips/mips-boards/sim/sim_smp.c | |||
@@ -44,8 +44,6 @@ | |||
44 | void core_send_ipi(int cpu, unsigned int action) | 44 | void core_send_ipi(int cpu, unsigned int action) |
45 | { | 45 | { |
46 | #ifdef CONFIG_MIPS_MT_SMTC | 46 | #ifdef CONFIG_MIPS_MT_SMTC |
47 | void smtc_send_ipi(int, int, unsigned int); | ||
48 | |||
49 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); | 47 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); |
50 | #endif /* CONFIG_MIPS_MT_SMTC */ | 48 | #endif /* CONFIG_MIPS_MT_SMTC */ |
51 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ | 49 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ |
@@ -59,15 +57,8 @@ void core_send_ipi(int cpu, unsigned int action) | |||
59 | void __init prom_build_cpu_map(void) | 57 | void __init prom_build_cpu_map(void) |
60 | { | 58 | { |
61 | #ifdef CONFIG_MIPS_MT_SMTC | 59 | #ifdef CONFIG_MIPS_MT_SMTC |
62 | extern int mipsmt_build_cpu_map(int startslot); | ||
63 | int nextslot; | 60 | int nextslot; |
64 | 61 | ||
65 | cpus_clear(phys_cpu_present_map); | ||
66 | |||
67 | /* Register the boot CPU */ | ||
68 | |||
69 | smp_prepare_boot_cpu(); | ||
70 | |||
71 | /* | 62 | /* |
72 | * As of November, 2004, MIPSsim only simulates one core | 63 | * As of November, 2004, MIPSsim only simulates one core |
73 | * at a time. However, that core may be a MIPS MT core | 64 | * at a time. However, that core may be a MIPS MT core |
@@ -87,8 +78,6 @@ void __init prom_build_cpu_map(void) | |||
87 | void prom_boot_secondary(int cpu, struct task_struct *idle) | 78 | void prom_boot_secondary(int cpu, struct task_struct *idle) |
88 | { | 79 | { |
89 | #ifdef CONFIG_MIPS_MT_SMTC | 80 | #ifdef CONFIG_MIPS_MT_SMTC |
90 | extern void smtc_boot_secondary(int cpu, struct task_struct *t); | ||
91 | |||
92 | smtc_boot_secondary(cpu, idle); | 81 | smtc_boot_secondary(cpu, idle); |
93 | #endif /* CONFIG_MIPS_MT_SMTC */ | 82 | #endif /* CONFIG_MIPS_MT_SMTC */ |
94 | } | 83 | } |
@@ -113,7 +102,6 @@ void prom_init_secondary(void) | |||
113 | void prom_prepare_cpus(unsigned int max_cpus) | 102 | void prom_prepare_cpus(unsigned int max_cpus) |
114 | { | 103 | { |
115 | #ifdef CONFIG_MIPS_MT_SMTC | 104 | #ifdef CONFIG_MIPS_MT_SMTC |
116 | void mipsmt_prepare_cpus(int c); | ||
117 | /* | 105 | /* |
118 | * As noted above, we can assume a single CPU for now | 106 | * As noted above, we can assume a single CPU for now |
119 | * but it may be multithreaded. | 107 | * but it may be multithreaded. |
@@ -132,8 +120,6 @@ void prom_prepare_cpus(unsigned int max_cpus) | |||
132 | void prom_smp_finish(void) | 120 | void prom_smp_finish(void) |
133 | { | 121 | { |
134 | #ifdef CONFIG_MIPS_MT_SMTC | 122 | #ifdef CONFIG_MIPS_MT_SMTC |
135 | void smtc_smp_finish(void); | ||
136 | |||
137 | smtc_smp_finish(); | 123 | smtc_smp_finish(); |
138 | #endif /* CONFIG_MIPS_MT_SMTC */ | 124 | #endif /* CONFIG_MIPS_MT_SMTC */ |
139 | } | 125 | } |
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 9dd1352d5748..bb041a22f20a 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c | |||
@@ -260,6 +260,10 @@ static void r3k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, | |||
260 | { | 260 | { |
261 | } | 261 | } |
262 | 262 | ||
263 | static void local_r3k_flush_data_cache_page(unsigned long addr) | ||
264 | { | ||
265 | } | ||
266 | |||
263 | static void r3k_flush_data_cache_page(unsigned long addr) | 267 | static void r3k_flush_data_cache_page(unsigned long addr) |
264 | { | 268 | { |
265 | } | 269 | } |
@@ -335,6 +339,7 @@ void __init r3k_cache_init(void) | |||
335 | flush_icache_range = r3k_flush_icache_range; | 339 | flush_icache_range = r3k_flush_icache_range; |
336 | 340 | ||
337 | flush_cache_sigtramp = r3k_flush_cache_sigtramp; | 341 | flush_cache_sigtramp = r3k_flush_cache_sigtramp; |
342 | local_flush_data_cache_page = local_r3k_flush_data_cache_page; | ||
338 | flush_data_cache_page = r3k_flush_data_cache_page; | 343 | flush_data_cache_page = r3k_flush_data_cache_page; |
339 | 344 | ||
340 | _dma_cache_wback_inv = r3k_dma_cache_wback_inv; | 345 | _dma_cache_wback_inv = r3k_dma_cache_wback_inv; |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 32b7f6aeb983..4182e1176fae 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -154,7 +154,8 @@ static inline void blast_icache32_r4600_v1_page_indexed(unsigned long page) | |||
154 | 154 | ||
155 | static inline void tx49_blast_icache32_page_indexed(unsigned long page) | 155 | static inline void tx49_blast_icache32_page_indexed(unsigned long page) |
156 | { | 156 | { |
157 | unsigned long start = page; | 157 | unsigned long indexmask = current_cpu_data.icache.waysize - 1; |
158 | unsigned long start = INDEX_BASE + (page & indexmask); | ||
158 | unsigned long end = start + PAGE_SIZE; | 159 | unsigned long end = start + PAGE_SIZE; |
159 | unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; | 160 | unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; |
160 | unsigned long ws_end = current_cpu_data.icache.ways << | 161 | unsigned long ws_end = current_cpu_data.icache.ways << |
@@ -749,12 +750,12 @@ static void __init probe_pcache(void) | |||
749 | icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); | 750 | icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); |
750 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); | 751 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); |
751 | c->icache.ways = 2; | 752 | c->icache.ways = 2; |
752 | c->icache.waybit = ffs(icache_size/2) - 1; | 753 | c->icache.waybit = __ffs(icache_size/2); |
753 | 754 | ||
754 | dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); | 755 | dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); |
755 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); | 756 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); |
756 | c->dcache.ways = 2; | 757 | c->dcache.ways = 2; |
757 | c->dcache.waybit= ffs(dcache_size/2) - 1; | 758 | c->dcache.waybit= __ffs(dcache_size/2); |
758 | 759 | ||
759 | c->options |= MIPS_CPU_CACHE_CDEX_P; | 760 | c->options |= MIPS_CPU_CACHE_CDEX_P; |
760 | break; | 761 | break; |
@@ -837,12 +838,12 @@ static void __init probe_pcache(void) | |||
837 | icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); | 838 | icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); |
838 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); | 839 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); |
839 | c->icache.ways = 2; | 840 | c->icache.ways = 2; |
840 | c->icache.waybit = ffs(icache_size/2) - 1; | 841 | c->icache.waybit = __ffs(icache_size/2); |
841 | 842 | ||
842 | dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); | 843 | dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); |
843 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); | 844 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); |
844 | c->dcache.ways = 2; | 845 | c->dcache.ways = 2; |
845 | c->dcache.waybit = ffs(dcache_size/2) - 1; | 846 | c->dcache.waybit = __ffs(dcache_size/2); |
846 | 847 | ||
847 | c->options |= MIPS_CPU_CACHE_CDEX_P; | 848 | c->options |= MIPS_CPU_CACHE_CDEX_P; |
848 | break; | 849 | break; |
@@ -873,12 +874,12 @@ static void __init probe_pcache(void) | |||
873 | icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); | 874 | icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); |
874 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); | 875 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); |
875 | c->icache.ways = 4; | 876 | c->icache.ways = 4; |
876 | c->icache.waybit = ffs(icache_size / c->icache.ways) - 1; | 877 | c->icache.waybit = __ffs(icache_size / c->icache.ways); |
877 | 878 | ||
878 | dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); | 879 | dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); |
879 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); | 880 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); |
880 | c->dcache.ways = 4; | 881 | c->dcache.ways = 4; |
881 | c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; | 882 | c->dcache.waybit = __ffs(dcache_size / c->dcache.ways); |
882 | 883 | ||
883 | #if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR) | 884 | #if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR) |
884 | c->options |= MIPS_CPU_CACHE_CDEX_P; | 885 | c->options |= MIPS_CPU_CACHE_CDEX_P; |
@@ -906,7 +907,7 @@ static void __init probe_pcache(void) | |||
906 | icache_size = c->icache.sets * | 907 | icache_size = c->icache.sets * |
907 | c->icache.ways * | 908 | c->icache.ways * |
908 | c->icache.linesz; | 909 | c->icache.linesz; |
909 | c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; | 910 | c->icache.waybit = __ffs(icache_size/c->icache.ways); |
910 | 911 | ||
911 | if (config & 0x8) /* VI bit */ | 912 | if (config & 0x8) /* VI bit */ |
912 | c->icache.flags |= MIPS_CACHE_VTAG; | 913 | c->icache.flags |= MIPS_CACHE_VTAG; |
@@ -926,7 +927,7 @@ static void __init probe_pcache(void) | |||
926 | dcache_size = c->dcache.sets * | 927 | dcache_size = c->dcache.sets * |
927 | c->dcache.ways * | 928 | c->dcache.ways * |
928 | c->dcache.linesz; | 929 | c->dcache.linesz; |
929 | c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; | 930 | c->dcache.waybit = __ffs(dcache_size/c->dcache.ways); |
930 | 931 | ||
931 | c->options |= MIPS_CPU_PREFETCH; | 932 | c->options |= MIPS_CPU_PREFETCH; |
932 | break; | 933 | break; |
@@ -1198,6 +1199,7 @@ void __init r4k_cache_init(void) | |||
1198 | 1199 | ||
1199 | flush_cache_sigtramp = r4k_flush_cache_sigtramp; | 1200 | flush_cache_sigtramp = r4k_flush_cache_sigtramp; |
1200 | flush_icache_all = r4k_flush_icache_all; | 1201 | flush_icache_all = r4k_flush_icache_all; |
1202 | local_flush_data_cache_page = local_r4k_flush_data_cache_page; | ||
1201 | flush_data_cache_page = r4k_flush_data_cache_page; | 1203 | flush_data_cache_page = r4k_flush_data_cache_page; |
1202 | flush_icache_range = r4k_flush_icache_range; | 1204 | flush_icache_range = r4k_flush_icache_range; |
1203 | 1205 | ||
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index 2f08b535f20e..f9b129491b1e 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c | |||
@@ -528,6 +528,7 @@ void sb1_cache_init(void) | |||
528 | flush_cache_page = sb1_flush_cache_page; | 528 | flush_cache_page = sb1_flush_cache_page; |
529 | 529 | ||
530 | flush_cache_sigtramp = sb1_flush_cache_sigtramp; | 530 | flush_cache_sigtramp = sb1_flush_cache_sigtramp; |
531 | local_flush_data_cache_page = (void *) sb1_nop; | ||
531 | flush_data_cache_page = (void *) sb1_nop; | 532 | flush_data_cache_page = (void *) sb1_nop; |
532 | 533 | ||
533 | /* Full flush */ | 534 | /* Full flush */ |
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index fe232e3988e3..5dfc9b1901f6 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c | |||
@@ -216,6 +216,11 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page | |||
216 | tx39_blast_icache_page_indexed(page); | 216 | tx39_blast_icache_page_indexed(page); |
217 | } | 217 | } |
218 | 218 | ||
219 | static void local_tx39_flush_data_cache_page(void * addr) | ||
220 | { | ||
221 | tx39_blast_dcache_page(addr); | ||
222 | } | ||
223 | |||
219 | static void tx39_flush_data_cache_page(unsigned long addr) | 224 | static void tx39_flush_data_cache_page(unsigned long addr) |
220 | { | 225 | { |
221 | tx39_blast_dcache_page(addr); | 226 | tx39_blast_dcache_page(addr); |
@@ -381,6 +386,7 @@ void __init tx39_cache_init(void) | |||
381 | flush_icache_range = (void *) tx39h_flush_icache_all; | 386 | flush_icache_range = (void *) tx39h_flush_icache_all; |
382 | 387 | ||
383 | flush_cache_sigtramp = (void *) tx39h_flush_icache_all; | 388 | flush_cache_sigtramp = (void *) tx39h_flush_icache_all; |
389 | local_flush_data_cache_page = (void *) tx39h_flush_icache_all; | ||
384 | flush_data_cache_page = (void *) tx39h_flush_icache_all; | 390 | flush_data_cache_page = (void *) tx39h_flush_icache_all; |
385 | 391 | ||
386 | _dma_cache_wback_inv = tx39h_dma_cache_wback_inv; | 392 | _dma_cache_wback_inv = tx39h_dma_cache_wback_inv; |
@@ -406,6 +412,7 @@ void __init tx39_cache_init(void) | |||
406 | flush_icache_range = tx39_flush_icache_range; | 412 | flush_icache_range = tx39_flush_icache_range; |
407 | 413 | ||
408 | flush_cache_sigtramp = tx39_flush_cache_sigtramp; | 414 | flush_cache_sigtramp = tx39_flush_cache_sigtramp; |
415 | local_flush_data_cache_page = local_tx39_flush_data_cache_page; | ||
409 | flush_data_cache_page = tx39_flush_data_cache_page; | 416 | flush_data_cache_page = tx39_flush_data_cache_page; |
410 | 417 | ||
411 | _dma_cache_wback_inv = tx39_dma_cache_wback_inv; | 418 | _dma_cache_wback_inv = tx39_dma_cache_wback_inv; |
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 591c22b080e4..83a56296be86 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
@@ -30,6 +30,7 @@ void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); | |||
30 | 30 | ||
31 | /* MIPS specific cache operations */ | 31 | /* MIPS specific cache operations */ |
32 | void (*flush_cache_sigtramp)(unsigned long addr); | 32 | void (*flush_cache_sigtramp)(unsigned long addr); |
33 | void (*local_flush_data_cache_page)(void * addr); | ||
33 | void (*flush_data_cache_page)(unsigned long addr); | 34 | void (*flush_data_cache_page)(unsigned long addr); |
34 | void (*flush_icache_all)(void); | 35 | void (*flush_icache_all)(void); |
35 | 36 | ||
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 2d9624fd10ec..e3a617224868 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c | |||
@@ -157,7 +157,6 @@ no_context: | |||
157 | * Oops. The kernel tried to access some bad page. We'll have to | 157 | * Oops. The kernel tried to access some bad page. We'll have to |
158 | * terminate things with extreme prejudice. | 158 | * terminate things with extreme prejudice. |
159 | */ | 159 | */ |
160 | |||
161 | bust_spinlocks(1); | 160 | bust_spinlocks(1); |
162 | 161 | ||
163 | printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at " | 162 | printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at " |
@@ -188,11 +187,20 @@ do_sigbus: | |||
188 | /* Kernel mode? Handle exceptions or die */ | 187 | /* Kernel mode? Handle exceptions or die */ |
189 | if (!user_mode(regs)) | 188 | if (!user_mode(regs)) |
190 | goto no_context; | 189 | goto no_context; |
191 | 190 | else | |
192 | /* | 191 | /* |
193 | * Send a sigbus, regardless of whether we were in kernel | 192 | * Send a sigbus, regardless of whether we were in kernel |
194 | * or user mode. | 193 | * or user mode. |
195 | */ | 194 | */ |
195 | #if 0 | ||
196 | printk("do_page_fault() #3: sending SIGBUS to %s for " | ||
197 | "invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n", | ||
198 | tsk->comm, | ||
199 | write ? "write access to" : "read access from", | ||
200 | field, address, | ||
201 | field, (unsigned long) regs->cp0_epc, | ||
202 | field, (unsigned long) regs->regs[31]); | ||
203 | #endif | ||
196 | tsk->thread.cp0_badvaddr = address; | 204 | tsk->thread.cp0_badvaddr = address; |
197 | info.si_signo = SIGBUS; | 205 | info.si_signo = SIGBUS; |
198 | info.si_errno = 0; | 206 | info.si_errno = 0; |
@@ -201,7 +209,6 @@ do_sigbus: | |||
201 | force_sig_info(SIGBUS, &info, tsk); | 209 | force_sig_info(SIGBUS, &info, tsk); |
202 | 210 | ||
203 | return; | 211 | return; |
204 | |||
205 | vmalloc_fault: | 212 | vmalloc_fault: |
206 | { | 213 | { |
207 | /* | 214 | /* |
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 1f7b37b38f5c..0c544375b856 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c | |||
@@ -83,6 +83,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) | |||
83 | preempt_check_resched(); | 83 | preempt_check_resched(); |
84 | } | 84 | } |
85 | 85 | ||
86 | #ifndef CONFIG_LIMITED_DMA | ||
86 | /* | 87 | /* |
87 | * This is the same as kmap_atomic() but can map memory that doesn't | 88 | * This is the same as kmap_atomic() but can map memory that doesn't |
88 | * have a struct page associated with it. | 89 | * have a struct page associated with it. |
@@ -101,6 +102,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | |||
101 | 102 | ||
102 | return (void*) vaddr; | 103 | return (void*) vaddr; |
103 | } | 104 | } |
105 | #endif /* CONFIG_LIMITED_DMA */ | ||
104 | 106 | ||
105 | struct page *__kmap_atomic_to_page(void *ptr) | 107 | struct page *__kmap_atomic_to_page(void *ptr) |
106 | { | 108 | { |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index ad89c442f299..c22308b93ff0 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -276,6 +276,20 @@ void __init mem_init(void) | |||
276 | } | 276 | } |
277 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ | 277 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ |
278 | 278 | ||
279 | void free_init_pages(char *what, unsigned long begin, unsigned long end) | ||
280 | { | ||
281 | unsigned long addr; | ||
282 | |||
283 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | ||
284 | ClearPageReserved(virt_to_page(addr)); | ||
285 | init_page_count(virt_to_page(addr)); | ||
286 | memset((void *)addr, 0xcc, PAGE_SIZE); | ||
287 | free_page(addr); | ||
288 | totalram_pages++; | ||
289 | } | ||
290 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | ||
291 | } | ||
292 | |||
279 | #ifdef CONFIG_BLK_DEV_INITRD | 293 | #ifdef CONFIG_BLK_DEV_INITRD |
280 | void free_initrd_mem(unsigned long start, unsigned long end) | 294 | void free_initrd_mem(unsigned long start, unsigned long end) |
281 | { | 295 | { |
@@ -284,16 +298,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) | |||
284 | start = (unsigned long)phys_to_virt(CPHYSADDR(start)); | 298 | start = (unsigned long)phys_to_virt(CPHYSADDR(start)); |
285 | end = (unsigned long)phys_to_virt(CPHYSADDR(end)); | 299 | end = (unsigned long)phys_to_virt(CPHYSADDR(end)); |
286 | #endif | 300 | #endif |
287 | if (start < end) | 301 | free_init_pages("initrd memory", start, end); |
288 | printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", | ||
289 | (end - start) >> 10); | ||
290 | |||
291 | for (; start < end; start += PAGE_SIZE) { | ||
292 | ClearPageReserved(virt_to_page(start)); | ||
293 | init_page_count(virt_to_page(start)); | ||
294 | free_page(start); | ||
295 | totalram_pages++; | ||
296 | } | ||
297 | } | 302 | } |
298 | #endif | 303 | #endif |
299 | 304 | ||
@@ -301,24 +306,17 @@ extern unsigned long prom_free_prom_memory(void); | |||
301 | 306 | ||
302 | void free_initmem(void) | 307 | void free_initmem(void) |
303 | { | 308 | { |
304 | unsigned long addr, page, freed; | 309 | unsigned long start, end, freed; |
305 | 310 | ||
306 | freed = prom_free_prom_memory(); | 311 | freed = prom_free_prom_memory(); |
312 | if (freed) | ||
313 | printk(KERN_INFO "Freeing firmware memory: %ldk freed\n",freed); | ||
307 | 314 | ||
308 | addr = (unsigned long) &__init_begin; | 315 | start = (unsigned long)(&__init_begin); |
309 | while (addr < (unsigned long) &__init_end) { | 316 | end = (unsigned long)(&__init_end); |
310 | #ifdef CONFIG_64BIT | 317 | #ifdef CONFIG_64BIT |
311 | page = PAGE_OFFSET | CPHYSADDR(addr); | 318 | start = PAGE_OFFSET | CPHYSADDR(start); |
312 | #else | 319 | end = PAGE_OFFSET | CPHYSADDR(end); |
313 | page = addr; | ||
314 | #endif | 320 | #endif |
315 | ClearPageReserved(virt_to_page(page)); | 321 | free_init_pages("unused kernel memory", start, end); |
316 | init_page_count(virt_to_page(page)); | ||
317 | free_page(page); | ||
318 | totalram_pages++; | ||
319 | freed += PAGE_SIZE; | ||
320 | addr += PAGE_SIZE; | ||
321 | } | ||
322 | printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n", | ||
323 | freed >> 10); | ||
324 | } | 322 | } |
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c index 3b6cc9ba1b05..31ec73052423 100644 --- a/arch/mips/mm/sc-rm7k.c +++ b/arch/mips/mm/sc-rm7k.c | |||
@@ -138,7 +138,7 @@ void __init rm7k_sc_init(void) | |||
138 | 138 | ||
139 | c->scache.linesz = sc_lsize; | 139 | c->scache.linesz = sc_lsize; |
140 | c->scache.ways = 4; | 140 | c->scache.ways = 4; |
141 | c->scache.waybit= ffs(scache_size / c->scache.ways) - 1; | 141 | c->scache.waybit= __ffs(scache_size / c->scache.ways); |
142 | c->scache.waysize = scache_size / c->scache.ways; | 142 | c->scache.waysize = scache_size / c->scache.ways; |
143 | c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); | 143 | c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); |
144 | printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n", | 144 | printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n", |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index a865f2394cb0..9dca099ba16b 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -32,13 +32,35 @@ extern void build_tlb_refill_handler(void); | |||
32 | "nop; nop; nop; nop; nop; nop;\n\t" \ | 32 | "nop; nop; nop; nop; nop; nop;\n\t" \ |
33 | ".set reorder\n\t") | 33 | ".set reorder\n\t") |
34 | 34 | ||
35 | /* Atomicity and interruptability */ | ||
36 | #ifdef CONFIG_MIPS_MT_SMTC | ||
37 | |||
38 | #include <asm/smtc.h> | ||
39 | #include <asm/mipsmtregs.h> | ||
40 | |||
41 | #define ENTER_CRITICAL(flags) \ | ||
42 | { \ | ||
43 | unsigned int mvpflags; \ | ||
44 | local_irq_save(flags);\ | ||
45 | mvpflags = dvpe() | ||
46 | #define EXIT_CRITICAL(flags) \ | ||
47 | evpe(mvpflags); \ | ||
48 | local_irq_restore(flags); \ | ||
49 | } | ||
50 | #else | ||
51 | |||
52 | #define ENTER_CRITICAL(flags) local_irq_save(flags) | ||
53 | #define EXIT_CRITICAL(flags) local_irq_restore(flags) | ||
54 | |||
55 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
56 | |||
35 | void local_flush_tlb_all(void) | 57 | void local_flush_tlb_all(void) |
36 | { | 58 | { |
37 | unsigned long flags; | 59 | unsigned long flags; |
38 | unsigned long old_ctx; | 60 | unsigned long old_ctx; |
39 | int entry; | 61 | int entry; |
40 | 62 | ||
41 | local_irq_save(flags); | 63 | ENTER_CRITICAL(flags); |
42 | /* Save old context and create impossible VPN2 value */ | 64 | /* Save old context and create impossible VPN2 value */ |
43 | old_ctx = read_c0_entryhi(); | 65 | old_ctx = read_c0_entryhi(); |
44 | write_c0_entrylo0(0); | 66 | write_c0_entrylo0(0); |
@@ -57,7 +79,7 @@ void local_flush_tlb_all(void) | |||
57 | } | 79 | } |
58 | tlbw_use_hazard(); | 80 | tlbw_use_hazard(); |
59 | write_c0_entryhi(old_ctx); | 81 | write_c0_entryhi(old_ctx); |
60 | local_irq_restore(flags); | 82 | EXIT_CRITICAL(flags); |
61 | } | 83 | } |
62 | 84 | ||
63 | /* All entries common to a mm share an asid. To effectively flush | 85 | /* All entries common to a mm share an asid. To effectively flush |
@@ -87,6 +109,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
87 | unsigned long flags; | 109 | unsigned long flags; |
88 | int size; | 110 | int size; |
89 | 111 | ||
112 | ENTER_CRITICAL(flags); | ||
90 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 113 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
91 | size = (size + 1) >> 1; | 114 | size = (size + 1) >> 1; |
92 | local_irq_save(flags); | 115 | local_irq_save(flags); |
@@ -120,7 +143,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
120 | } else { | 143 | } else { |
121 | drop_mmu_context(mm, cpu); | 144 | drop_mmu_context(mm, cpu); |
122 | } | 145 | } |
123 | local_irq_restore(flags); | 146 | EXIT_CRITICAL(flags); |
124 | } | 147 | } |
125 | } | 148 | } |
126 | 149 | ||
@@ -129,9 +152,9 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
129 | unsigned long flags; | 152 | unsigned long flags; |
130 | int size; | 153 | int size; |
131 | 154 | ||
155 | ENTER_CRITICAL(flags); | ||
132 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 156 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
133 | size = (size + 1) >> 1; | 157 | size = (size + 1) >> 1; |
134 | local_irq_save(flags); | ||
135 | if (size <= current_cpu_data.tlbsize / 2) { | 158 | if (size <= current_cpu_data.tlbsize / 2) { |
136 | int pid = read_c0_entryhi(); | 159 | int pid = read_c0_entryhi(); |
137 | 160 | ||
@@ -162,7 +185,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
162 | } else { | 185 | } else { |
163 | local_flush_tlb_all(); | 186 | local_flush_tlb_all(); |
164 | } | 187 | } |
165 | local_irq_restore(flags); | 188 | EXIT_CRITICAL(flags); |
166 | } | 189 | } |
167 | 190 | ||
168 | void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | 191 | void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) |
@@ -175,7 +198,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
175 | 198 | ||
176 | newpid = cpu_asid(cpu, vma->vm_mm); | 199 | newpid = cpu_asid(cpu, vma->vm_mm); |
177 | page &= (PAGE_MASK << 1); | 200 | page &= (PAGE_MASK << 1); |
178 | local_irq_save(flags); | 201 | ENTER_CRITICAL(flags); |
179 | oldpid = read_c0_entryhi(); | 202 | oldpid = read_c0_entryhi(); |
180 | write_c0_entryhi(page | newpid); | 203 | write_c0_entryhi(page | newpid); |
181 | mtc0_tlbw_hazard(); | 204 | mtc0_tlbw_hazard(); |
@@ -194,7 +217,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
194 | 217 | ||
195 | finish: | 218 | finish: |
196 | write_c0_entryhi(oldpid); | 219 | write_c0_entryhi(oldpid); |
197 | local_irq_restore(flags); | 220 | EXIT_CRITICAL(flags); |
198 | } | 221 | } |
199 | } | 222 | } |
200 | 223 | ||
@@ -207,7 +230,7 @@ void local_flush_tlb_one(unsigned long page) | |||
207 | unsigned long flags; | 230 | unsigned long flags; |
208 | int oldpid, idx; | 231 | int oldpid, idx; |
209 | 232 | ||
210 | local_irq_save(flags); | 233 | ENTER_CRITICAL(flags); |
211 | oldpid = read_c0_entryhi(); | 234 | oldpid = read_c0_entryhi(); |
212 | page &= (PAGE_MASK << 1); | 235 | page &= (PAGE_MASK << 1); |
213 | write_c0_entryhi(page); | 236 | write_c0_entryhi(page); |
@@ -226,7 +249,7 @@ void local_flush_tlb_one(unsigned long page) | |||
226 | } | 249 | } |
227 | write_c0_entryhi(oldpid); | 250 | write_c0_entryhi(oldpid); |
228 | 251 | ||
229 | local_irq_restore(flags); | 252 | EXIT_CRITICAL(flags); |
230 | } | 253 | } |
231 | 254 | ||
232 | /* | 255 | /* |
@@ -249,7 +272,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
249 | if (current->active_mm != vma->vm_mm) | 272 | if (current->active_mm != vma->vm_mm) |
250 | return; | 273 | return; |
251 | 274 | ||
252 | local_irq_save(flags); | 275 | ENTER_CRITICAL(flags); |
253 | 276 | ||
254 | pid = read_c0_entryhi() & ASID_MASK; | 277 | pid = read_c0_entryhi() & ASID_MASK; |
255 | address &= (PAGE_MASK << 1); | 278 | address &= (PAGE_MASK << 1); |
@@ -277,7 +300,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
277 | else | 300 | else |
278 | tlb_write_indexed(); | 301 | tlb_write_indexed(); |
279 | tlbw_use_hazard(); | 302 | tlbw_use_hazard(); |
280 | local_irq_restore(flags); | 303 | EXIT_CRITICAL(flags); |
281 | } | 304 | } |
282 | 305 | ||
283 | #if 0 | 306 | #if 0 |
@@ -291,7 +314,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, | |||
291 | pte_t *ptep; | 314 | pte_t *ptep; |
292 | int idx; | 315 | int idx; |
293 | 316 | ||
294 | local_irq_save(flags); | 317 | ENTER_CRITICAL(flags); |
295 | address &= (PAGE_MASK << 1); | 318 | address &= (PAGE_MASK << 1); |
296 | asid = read_c0_entryhi() & ASID_MASK; | 319 | asid = read_c0_entryhi() & ASID_MASK; |
297 | write_c0_entryhi(address | asid); | 320 | write_c0_entryhi(address | asid); |
@@ -310,7 +333,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, | |||
310 | else | 333 | else |
311 | tlb_write_indexed(); | 334 | tlb_write_indexed(); |
312 | tlbw_use_hazard(); | 335 | tlbw_use_hazard(); |
313 | local_irq_restore(flags); | 336 | EXIT_CRITICAL(flags); |
314 | } | 337 | } |
315 | #endif | 338 | #endif |
316 | 339 | ||
@@ -322,7 +345,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
322 | unsigned long old_pagemask; | 345 | unsigned long old_pagemask; |
323 | unsigned long old_ctx; | 346 | unsigned long old_ctx; |
324 | 347 | ||
325 | local_irq_save(flags); | 348 | ENTER_CRITICAL(flags); |
326 | /* Save old context and create impossible VPN2 value */ | 349 | /* Save old context and create impossible VPN2 value */ |
327 | old_ctx = read_c0_entryhi(); | 350 | old_ctx = read_c0_entryhi(); |
328 | old_pagemask = read_c0_pagemask(); | 351 | old_pagemask = read_c0_pagemask(); |
@@ -342,7 +365,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
342 | BARRIER; | 365 | BARRIER; |
343 | write_c0_pagemask(old_pagemask); | 366 | write_c0_pagemask(old_pagemask); |
344 | local_flush_tlb_all(); | 367 | local_flush_tlb_all(); |
345 | local_irq_restore(flags); | 368 | EXIT_CRITICAL(flags); |
346 | } | 369 | } |
347 | 370 | ||
348 | /* | 371 | /* |
@@ -362,7 +385,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
362 | unsigned long old_pagemask; | 385 | unsigned long old_pagemask; |
363 | unsigned long old_ctx; | 386 | unsigned long old_ctx; |
364 | 387 | ||
365 | local_irq_save(flags); | 388 | ENTER_CRITICAL(flags); |
366 | /* Save old context and create impossible VPN2 value */ | 389 | /* Save old context and create impossible VPN2 value */ |
367 | old_ctx = read_c0_entryhi(); | 390 | old_ctx = read_c0_entryhi(); |
368 | old_pagemask = read_c0_pagemask(); | 391 | old_pagemask = read_c0_pagemask(); |
@@ -386,10 +409,11 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
386 | write_c0_entryhi(old_ctx); | 409 | write_c0_entryhi(old_ctx); |
387 | write_c0_pagemask(old_pagemask); | 410 | write_c0_pagemask(old_pagemask); |
388 | out: | 411 | out: |
389 | local_irq_restore(flags); | 412 | EXIT_CRITICAL(flags); |
390 | return ret; | 413 | return ret; |
391 | } | 414 | } |
392 | 415 | ||
416 | extern void __init sanitize_tlb_entries(void); | ||
393 | static void __init probe_tlb(unsigned long config) | 417 | static void __init probe_tlb(unsigned long config) |
394 | { | 418 | { |
395 | struct cpuinfo_mips *c = ¤t_cpu_data; | 419 | struct cpuinfo_mips *c = ¤t_cpu_data; |
@@ -402,6 +426,14 @@ static void __init probe_tlb(unsigned long config) | |||
402 | */ | 426 | */ |
403 | if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) | 427 | if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) |
404 | return; | 428 | return; |
429 | #ifdef CONFIG_MIPS_MT_SMTC | ||
430 | /* | ||
431 | * If TLB is shared in SMTC system, total size already | ||
432 | * has been calculated and written into cpu_data tlbsize | ||
433 | */ | ||
434 | if((smtc_status & SMTC_TLB_SHARED) == SMTC_TLB_SHARED) | ||
435 | return; | ||
436 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
405 | 437 | ||
406 | reg = read_c0_config1(); | 438 | reg = read_c0_config1(); |
407 | if (!((config >> 7) & 3)) | 439 | if (!((config >> 7) & 3)) |
@@ -410,6 +442,15 @@ static void __init probe_tlb(unsigned long config) | |||
410 | c->tlbsize = ((reg >> 25) & 0x3f) + 1; | 442 | c->tlbsize = ((reg >> 25) & 0x3f) + 1; |
411 | } | 443 | } |
412 | 444 | ||
445 | static int __initdata ntlb = 0; | ||
446 | static int __init set_ntlb(char *str) | ||
447 | { | ||
448 | get_option(&str, &ntlb); | ||
449 | return 1; | ||
450 | } | ||
451 | |||
452 | __setup("ntlb=", set_ntlb); | ||
453 | |||
413 | void __init tlb_init(void) | 454 | void __init tlb_init(void) |
414 | { | 455 | { |
415 | unsigned int config = read_c0_config(); | 456 | unsigned int config = read_c0_config(); |
@@ -432,5 +473,15 @@ void __init tlb_init(void) | |||
432 | 473 | ||
433 | /* Did I tell you that ARC SUCKS? */ | 474 | /* Did I tell you that ARC SUCKS? */ |
434 | 475 | ||
476 | if (ntlb) { | ||
477 | if (ntlb > 1 && ntlb <= current_cpu_data.tlbsize) { | ||
478 | int wired = current_cpu_data.tlbsize - ntlb; | ||
479 | write_c0_wired(wired); | ||
480 | write_c0_index(wired-1); | ||
481 | printk ("Restricting TLB to %d entries\n", ntlb); | ||
482 | } else | ||
483 | printk("Ignoring invalid argument ntlb=%d\n", ntlb); | ||
484 | } | ||
485 | |||
435 | build_tlb_refill_handler(); | 486 | build_tlb_refill_handler(); |
436 | } | 487 | } |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 599b3c297186..053dbacac56b 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -7,6 +7,16 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2004,2005 by Thiemo Seufer | 8 | * Copyright (C) 2004,2005 by Thiemo Seufer |
9 | * Copyright (C) 2005 Maciej W. Rozycki | 9 | * Copyright (C) 2005 Maciej W. Rozycki |
10 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | ||
11 | * | ||
12 | * ... and the days got worse and worse and now you see | ||
13 | * I've gone completly out of my mind. | ||
14 | * | ||
15 | * They're coming to take me a away haha | ||
16 | * they're coming to take me a away hoho hihi haha | ||
17 | * to the funny farm where code is beautiful all the time ... | ||
18 | * | ||
19 | * (Condolences to Napoleon XIV) | ||
10 | */ | 20 | */ |
11 | 21 | ||
12 | #include <stdarg.h> | 22 | #include <stdarg.h> |
@@ -68,6 +78,7 @@ enum fields | |||
68 | BIMM = 0x040, | 78 | BIMM = 0x040, |
69 | JIMM = 0x080, | 79 | JIMM = 0x080, |
70 | FUNC = 0x100, | 80 | FUNC = 0x100, |
81 | SET = 0x200 | ||
71 | }; | 82 | }; |
72 | 83 | ||
73 | #define OP_MASK 0x2f | 84 | #define OP_MASK 0x2f |
@@ -86,6 +97,8 @@ enum fields | |||
86 | #define JIMM_SH 0 | 97 | #define JIMM_SH 0 |
87 | #define FUNC_MASK 0x2f | 98 | #define FUNC_MASK 0x2f |
88 | #define FUNC_SH 0 | 99 | #define FUNC_SH 0 |
100 | #define SET_MASK 0x7 | ||
101 | #define SET_SH 0 | ||
89 | 102 | ||
90 | enum opcode { | 103 | enum opcode { |
91 | insn_invalid, | 104 | insn_invalid, |
@@ -129,8 +142,8 @@ static __initdata struct insn insn_table[] = { | |||
129 | { insn_bne, M(bne_op,0,0,0,0,0), RS | RT | BIMM }, | 142 | { insn_bne, M(bne_op,0,0,0,0,0), RS | RT | BIMM }, |
130 | { insn_daddiu, M(daddiu_op,0,0,0,0,0), RS | RT | SIMM }, | 143 | { insn_daddiu, M(daddiu_op,0,0,0,0,0), RS | RT | SIMM }, |
131 | { insn_daddu, M(spec_op,0,0,0,0,daddu_op), RS | RT | RD }, | 144 | { insn_daddu, M(spec_op,0,0,0,0,daddu_op), RS | RT | RD }, |
132 | { insn_dmfc0, M(cop0_op,dmfc_op,0,0,0,0), RT | RD }, | 145 | { insn_dmfc0, M(cop0_op,dmfc_op,0,0,0,0), RT | RD | SET}, |
133 | { insn_dmtc0, M(cop0_op,dmtc_op,0,0,0,0), RT | RD }, | 146 | { insn_dmtc0, M(cop0_op,dmtc_op,0,0,0,0), RT | RD | SET}, |
134 | { insn_dsll, M(spec_op,0,0,0,0,dsll_op), RT | RD | RE }, | 147 | { insn_dsll, M(spec_op,0,0,0,0,dsll_op), RT | RD | RE }, |
135 | { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, | 148 | { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, |
136 | { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, | 149 | { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, |
@@ -145,8 +158,8 @@ static __initdata struct insn insn_table[] = { | |||
145 | { insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM }, | 158 | { insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM }, |
146 | { insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM }, | 159 | { insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM }, |
147 | { insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM }, | 160 | { insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM }, |
148 | { insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD }, | 161 | { insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD | SET}, |
149 | { insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD }, | 162 | { insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD | SET}, |
150 | { insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM }, | 163 | { insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM }, |
151 | { insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 }, | 164 | { insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 }, |
152 | { insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM }, | 165 | { insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM }, |
@@ -242,6 +255,14 @@ static __init u32 build_func(u32 arg) | |||
242 | return arg & FUNC_MASK; | 255 | return arg & FUNC_MASK; |
243 | } | 256 | } |
244 | 257 | ||
258 | static __init u32 build_set(u32 arg) | ||
259 | { | ||
260 | if (arg & ~SET_MASK) | ||
261 | printk(KERN_WARNING "TLB synthesizer field overflow\n"); | ||
262 | |||
263 | return arg & SET_MASK; | ||
264 | } | ||
265 | |||
245 | /* | 266 | /* |
246 | * The order of opcode arguments is implicitly left to right, | 267 | * The order of opcode arguments is implicitly left to right, |
247 | * starting with RS and ending with FUNC or IMM. | 268 | * starting with RS and ending with FUNC or IMM. |
@@ -273,6 +294,7 @@ static void __init build_insn(u32 **buf, enum opcode opc, ...) | |||
273 | if (ip->fields & BIMM) op |= build_bimm(va_arg(ap, s32)); | 294 | if (ip->fields & BIMM) op |= build_bimm(va_arg(ap, s32)); |
274 | if (ip->fields & JIMM) op |= build_jimm(va_arg(ap, u32)); | 295 | if (ip->fields & JIMM) op |= build_jimm(va_arg(ap, u32)); |
275 | if (ip->fields & FUNC) op |= build_func(va_arg(ap, u32)); | 296 | if (ip->fields & FUNC) op |= build_func(va_arg(ap, u32)); |
297 | if (ip->fields & SET) op |= build_set(va_arg(ap, u32)); | ||
276 | va_end(ap); | 298 | va_end(ap); |
277 | 299 | ||
278 | **buf = op; | 300 | **buf = op; |
@@ -358,8 +380,8 @@ I_u1s2(_bgezl); | |||
358 | I_u1s2(_bltz); | 380 | I_u1s2(_bltz); |
359 | I_u1s2(_bltzl); | 381 | I_u1s2(_bltzl); |
360 | I_u1u2s3(_bne); | 382 | I_u1u2s3(_bne); |
361 | I_u1u2(_dmfc0); | 383 | I_u1u2u3(_dmfc0); |
362 | I_u1u2(_dmtc0); | 384 | I_u1u2u3(_dmtc0); |
363 | I_u2u1s3(_daddiu); | 385 | I_u2u1s3(_daddiu); |
364 | I_u3u1u2(_daddu); | 386 | I_u3u1u2(_daddu); |
365 | I_u2u1u3(_dsll); | 387 | I_u2u1u3(_dsll); |
@@ -376,8 +398,8 @@ I_u2s3u1(_ll); | |||
376 | I_u2s3u1(_lld); | 398 | I_u2s3u1(_lld); |
377 | I_u1s2(_lui); | 399 | I_u1s2(_lui); |
378 | I_u2s3u1(_lw); | 400 | I_u2s3u1(_lw); |
379 | I_u1u2(_mfc0); | 401 | I_u1u2u3(_mfc0); |
380 | I_u1u2(_mtc0); | 402 | I_u1u2u3(_mtc0); |
381 | I_u2u1u3(_ori); | 403 | I_u2u1u3(_ori); |
382 | I_0(_rfe); | 404 | I_0(_rfe); |
383 | I_u2s3u1(_sc); | 405 | I_u2s3u1(_sc); |
@@ -451,8 +473,8 @@ L_LA(_r3000_write_probe_fail) | |||
451 | # define i_SLL(buf, rs, rt, sh) i_dsll(buf, rs, rt, sh) | 473 | # define i_SLL(buf, rs, rt, sh) i_dsll(buf, rs, rt, sh) |
452 | # define i_SRA(buf, rs, rt, sh) i_dsra(buf, rs, rt, sh) | 474 | # define i_SRA(buf, rs, rt, sh) i_dsra(buf, rs, rt, sh) |
453 | # define i_SRL(buf, rs, rt, sh) i_dsrl(buf, rs, rt, sh) | 475 | # define i_SRL(buf, rs, rt, sh) i_dsrl(buf, rs, rt, sh) |
454 | # define i_MFC0(buf, rt, rd) i_dmfc0(buf, rt, rd) | 476 | # define i_MFC0(buf, rt, rd...) i_dmfc0(buf, rt, rd) |
455 | # define i_MTC0(buf, rt, rd) i_dmtc0(buf, rt, rd) | 477 | # define i_MTC0(buf, rt, rd...) i_dmtc0(buf, rt, rd) |
456 | # define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val) | 478 | # define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val) |
457 | # define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd) | 479 | # define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd) |
458 | # define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd) | 480 | # define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd) |
@@ -464,8 +486,8 @@ L_LA(_r3000_write_probe_fail) | |||
464 | # define i_SLL(buf, rs, rt, sh) i_sll(buf, rs, rt, sh) | 486 | # define i_SLL(buf, rs, rt, sh) i_sll(buf, rs, rt, sh) |
465 | # define i_SRA(buf, rs, rt, sh) i_sra(buf, rs, rt, sh) | 487 | # define i_SRA(buf, rs, rt, sh) i_sra(buf, rs, rt, sh) |
466 | # define i_SRL(buf, rs, rt, sh) i_srl(buf, rs, rt, sh) | 488 | # define i_SRL(buf, rs, rt, sh) i_srl(buf, rs, rt, sh) |
467 | # define i_MFC0(buf, rt, rd) i_mfc0(buf, rt, rd) | 489 | # define i_MFC0(buf, rt, rd...) i_mfc0(buf, rt, rd) |
468 | # define i_MTC0(buf, rt, rd) i_mtc0(buf, rt, rd) | 490 | # define i_MTC0(buf, rt, rd...) i_mtc0(buf, rt, rd) |
469 | # define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val) | 491 | # define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val) |
470 | # define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd) | 492 | # define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd) |
471 | # define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd) | 493 | # define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd) |
@@ -670,14 +692,15 @@ static void __init il_bgezl(u32 **p, struct reloc **r, unsigned int reg, | |||
670 | #define K1 27 | 692 | #define K1 27 |
671 | 693 | ||
672 | /* Some CP0 registers */ | 694 | /* Some CP0 registers */ |
673 | #define C0_INDEX 0 | 695 | #define C0_INDEX 0, 0 |
674 | #define C0_ENTRYLO0 2 | 696 | #define C0_ENTRYLO0 2, 0 |
675 | #define C0_ENTRYLO1 3 | 697 | #define C0_TCBIND 2, 2 |
676 | #define C0_CONTEXT 4 | 698 | #define C0_ENTRYLO1 3, 0 |
677 | #define C0_BADVADDR 8 | 699 | #define C0_CONTEXT 4, 0 |
678 | #define C0_ENTRYHI 10 | 700 | #define C0_BADVADDR 8, 0 |
679 | #define C0_EPC 14 | 701 | #define C0_ENTRYHI 10, 0 |
680 | #define C0_XCONTEXT 20 | 702 | #define C0_EPC 14, 0 |
703 | #define C0_XCONTEXT 20, 0 | ||
681 | 704 | ||
682 | #ifdef CONFIG_64BIT | 705 | #ifdef CONFIG_64BIT |
683 | # define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_XCONTEXT) | 706 | # define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_XCONTEXT) |
@@ -742,7 +765,7 @@ static void __init build_r3000_tlb_refill_handler(void) | |||
742 | } | 765 | } |
743 | #endif | 766 | #endif |
744 | 767 | ||
745 | memcpy((void *)CAC_BASE, tlb_handler, 0x80); | 768 | memcpy((void *)ebase, tlb_handler, 0x80); |
746 | } | 769 | } |
747 | 770 | ||
748 | /* | 771 | /* |
@@ -951,12 +974,20 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, | |||
951 | /* No i_nop needed here, since the next insn doesn't touch TMP. */ | 974 | /* No i_nop needed here, since the next insn doesn't touch TMP. */ |
952 | 975 | ||
953 | #ifdef CONFIG_SMP | 976 | #ifdef CONFIG_SMP |
977 | # ifdef CONFIG_MIPS_MT_SMTC | ||
978 | /* | ||
979 | * SMTC uses TCBind value as "CPU" index | ||
980 | */ | ||
981 | i_mfc0(p, ptr, C0_TCBIND); | ||
982 | i_dsrl(p, ptr, ptr, 19); | ||
983 | # else | ||
954 | /* | 984 | /* |
955 | * 64 bit SMP running in XKPHYS has smp_processor_id() << 3 | 985 | * 64 bit SMP running in XKPHYS has smp_processor_id() << 3 |
956 | * stored in CONTEXT. | 986 | * stored in CONTEXT. |
957 | */ | 987 | */ |
958 | i_dmfc0(p, ptr, C0_CONTEXT); | 988 | i_dmfc0(p, ptr, C0_CONTEXT); |
959 | i_dsrl(p, ptr, ptr, 23); | 989 | i_dsrl(p, ptr, ptr, 23); |
990 | #endif | ||
960 | i_LA_mostly(p, tmp, pgdc); | 991 | i_LA_mostly(p, tmp, pgdc); |
961 | i_daddu(p, ptr, ptr, tmp); | 992 | i_daddu(p, ptr, ptr, tmp); |
962 | i_dmfc0(p, tmp, C0_BADVADDR); | 993 | i_dmfc0(p, tmp, C0_BADVADDR); |
@@ -1014,9 +1045,21 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) | |||
1014 | 1045 | ||
1015 | /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */ | 1046 | /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */ |
1016 | #ifdef CONFIG_SMP | 1047 | #ifdef CONFIG_SMP |
1048 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1049 | /* | ||
1050 | * SMTC uses TCBind value as "CPU" index | ||
1051 | */ | ||
1052 | i_mfc0(p, ptr, C0_TCBIND); | ||
1053 | i_LA_mostly(p, tmp, pgdc); | ||
1054 | i_srl(p, ptr, ptr, 19); | ||
1055 | #else | ||
1056 | /* | ||
1057 | * smp_processor_id() << 3 is stored in CONTEXT. | ||
1058 | */ | ||
1017 | i_mfc0(p, ptr, C0_CONTEXT); | 1059 | i_mfc0(p, ptr, C0_CONTEXT); |
1018 | i_LA_mostly(p, tmp, pgdc); | 1060 | i_LA_mostly(p, tmp, pgdc); |
1019 | i_srl(p, ptr, ptr, 23); | 1061 | i_srl(p, ptr, ptr, 23); |
1062 | #endif | ||
1020 | i_addu(p, ptr, tmp, ptr); | 1063 | i_addu(p, ptr, tmp, ptr); |
1021 | #else | 1064 | #else |
1022 | i_LA_mostly(p, ptr, pgdc); | 1065 | i_LA_mostly(p, ptr, pgdc); |
@@ -1247,7 +1290,7 @@ static void __init build_r4000_tlb_refill_handler(void) | |||
1247 | } | 1290 | } |
1248 | #endif | 1291 | #endif |
1249 | 1292 | ||
1250 | memcpy((void *)CAC_BASE, final_handler, 0x100); | 1293 | memcpy((void *)ebase, final_handler, 0x100); |
1251 | } | 1294 | } |
1252 | 1295 | ||
1253 | /* | 1296 | /* |
diff --git a/arch/mips/momentum/jaguar_atx/Makefile b/arch/mips/momentum/jaguar_atx/Makefile index 20bbd3ea44a8..67372f3f9654 100644 --- a/arch/mips/momentum/jaguar_atx/Makefile +++ b/arch/mips/momentum/jaguar_atx/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | # unless it's something special (ie not a .c file). | 6 | # unless it's something special (ie not a .c file). |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += int-handler.o irq.o prom.o reset.o setup.o | 9 | obj-y += irq.o prom.o reset.o setup.o |
10 | 10 | ||
11 | obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o | 11 | obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o |
12 | obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o | 12 | obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o |
diff --git a/arch/mips/momentum/jaguar_atx/int-handler.S b/arch/mips/momentum/jaguar_atx/int-handler.S deleted file mode 100644 index 55bc789733f2..000000000000 --- a/arch/mips/momentum/jaguar_atx/int-handler.S +++ /dev/null | |||
@@ -1,128 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2002 Momentum Computer Inc. | ||
3 | * Author: Matthew Dharm <mdharm@momenco.com> | ||
4 | * | ||
5 | * Based on work: | ||
6 | * Copyright 2001 MontaVista Software Inc. | ||
7 | * Author: jsun@mvista.com or jsun@junsun.net | ||
8 | * | ||
9 | * First-level interrupt dispatcher for Jaguar-ATX board. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | */ | ||
16 | #include <asm/asm.h> | ||
17 | #include <asm/mipsregs.h> | ||
18 | #include <asm/addrspace.h> | ||
19 | #include <asm/regdef.h> | ||
20 | #include <asm/stackframe.h> | ||
21 | |||
22 | /* | ||
23 | * First level interrupt dispatcher for Ocelot-CS board | ||
24 | */ | ||
25 | .align 5 | ||
26 | NESTED(jaguar_handle_int, PT_SIZE, sp) | ||
27 | SAVE_ALL | ||
28 | CLI | ||
29 | .set at | ||
30 | mfc0 t0, CP0_CAUSE | ||
31 | mfc0 t2, CP0_STATUS | ||
32 | |||
33 | and t0, t2 | ||
34 | |||
35 | andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */ | ||
36 | bnez t1, ll_sw0_irq | ||
37 | andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */ | ||
38 | bnez t1, ll_sw1_irq | ||
39 | andi t1, t0, STATUSF_IP2 /* int0 hardware line */ | ||
40 | bnez t1, ll_pcixa_irq | ||
41 | andi t1, t0, STATUSF_IP3 /* int1 hardware line */ | ||
42 | bnez t1, ll_pcixb_irq | ||
43 | andi t1, t0, STATUSF_IP4 /* int2 hardware line */ | ||
44 | bnez t1, ll_pcia_irq | ||
45 | andi t1, t0, STATUSF_IP5 /* int3 hardware line */ | ||
46 | bnez t1, ll_pcib_irq | ||
47 | andi t1, t0, STATUSF_IP6 /* int4 hardware line */ | ||
48 | bnez t1, ll_uart_irq | ||
49 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
50 | bnez t1, ll_cputimer_irq | ||
51 | |||
52 | nop | ||
53 | nop | ||
54 | |||
55 | /* now look at extended interrupts */ | ||
56 | mfc0 t0, CP0_CAUSE | ||
57 | cfc0 t1, CP0_S1_INTCONTROL | ||
58 | |||
59 | /* shift the mask 8 bits left to line up the bits */ | ||
60 | sll t2, t1, 8 | ||
61 | |||
62 | and t0, t2 | ||
63 | srl t0, t0, 16 | ||
64 | |||
65 | andi t1, t0, STATUSF_IP8 /* int6 hardware line */ | ||
66 | bnez t1, ll_mv64340_decode_irq | ||
67 | |||
68 | nop | ||
69 | nop | ||
70 | |||
71 | .set reorder | ||
72 | |||
73 | /* wrong alarm or masked ... */ | ||
74 | j spurious_interrupt | ||
75 | nop | ||
76 | END(jaguar_handle_int) | ||
77 | |||
78 | .align 5 | ||
79 | ll_sw0_irq: | ||
80 | li a0, 0 | ||
81 | move a1, sp | ||
82 | jal do_IRQ | ||
83 | j ret_from_irq | ||
84 | ll_sw1_irq: | ||
85 | li a0, 1 | ||
86 | move a1, sp | ||
87 | jal do_IRQ | ||
88 | j ret_from_irq | ||
89 | ll_pcixa_irq: | ||
90 | li a0, 2 | ||
91 | move a1, sp | ||
92 | jal do_IRQ | ||
93 | j ret_from_irq | ||
94 | |||
95 | ll_pcixb_irq: | ||
96 | li a0, 3 | ||
97 | move a1, sp | ||
98 | jal do_IRQ | ||
99 | j ret_from_irq | ||
100 | |||
101 | ll_pcia_irq: | ||
102 | li a0, 4 | ||
103 | move a1, sp | ||
104 | jal do_IRQ | ||
105 | j ret_from_irq | ||
106 | |||
107 | ll_pcib_irq: | ||
108 | li a0, 5 | ||
109 | move a1, sp | ||
110 | jal do_IRQ | ||
111 | j ret_from_irq | ||
112 | |||
113 | ll_uart_irq: | ||
114 | li a0, 6 | ||
115 | move a1, sp | ||
116 | jal do_IRQ | ||
117 | j ret_from_irq | ||
118 | |||
119 | ll_cputimer_irq: | ||
120 | li a0, 7 | ||
121 | move a1, sp | ||
122 | jal ll_timer_interrupt | ||
123 | j ret_from_irq | ||
124 | |||
125 | ll_mv64340_decode_irq: | ||
126 | move a0, sp | ||
127 | jal ll_mv64340_irq | ||
128 | j ret_from_irq | ||
diff --git a/arch/mips/momentum/jaguar_atx/irq.c b/arch/mips/momentum/jaguar_atx/irq.c index 15588f91ace2..ec4032b38f19 100644 --- a/arch/mips/momentum/jaguar_atx/irq.c +++ b/arch/mips/momentum/jaguar_atx/irq.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * Copyright 2001 MontaVista Software Inc. | 10 | * Copyright 2001 MontaVista Software Inc. |
11 | * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net | 11 | * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net |
12 | * | 12 | * |
13 | * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) | 13 | * Copyright (C) 2000, 01, 06 Ralf Baechle (ralf@linux-mips.org) |
14 | * | 14 | * |
15 | * This program is free software; you can redistribute it and/or modify it | 15 | * This program is free software; you can redistribute it and/or modify it |
16 | * under the terms of the GNU General Public License as published by the | 16 | * under the terms of the GNU General Public License as published by the |
@@ -38,8 +38,37 @@ | |||
38 | #include <linux/types.h> | 38 | #include <linux/types.h> |
39 | #include <asm/irq_cpu.h> | 39 | #include <asm/irq_cpu.h> |
40 | #include <asm/mipsregs.h> | 40 | #include <asm/mipsregs.h> |
41 | #include <asm/time.h> | ||
41 | 42 | ||
42 | extern asmlinkage void jaguar_handle_int(void); | 43 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
44 | { | ||
45 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
46 | |||
47 | if (pending & STATUSF_IP0) | ||
48 | do_IRQ(0, regs); | ||
49 | else if (pending & STATUSF_IP1) | ||
50 | do_IRQ(1, regs); | ||
51 | else if (pending & STATUSF_IP2) | ||
52 | do_IRQ(2, regs); | ||
53 | else if (pending & STATUSF_IP3) | ||
54 | do_IRQ(3, regs); | ||
55 | else if (pending & STATUSF_IP4) | ||
56 | do_IRQ(4, regs); | ||
57 | else if (pending & STATUSF_IP5) | ||
58 | do_IRQ(5, regs); | ||
59 | else if (pending & STATUSF_IP6) | ||
60 | do_IRQ(6, regs); | ||
61 | else if (pending & STATUSF_IP7) | ||
62 | ll_timer_interrupt(7, regs); | ||
63 | else { | ||
64 | /* | ||
65 | * Now look at the extended interrupts | ||
66 | */ | ||
67 | pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; | ||
68 | if (pending & STATUSF_IP8) | ||
69 | ll_mv64340_irq(regs); | ||
70 | } | ||
71 | } | ||
43 | 72 | ||
44 | static struct irqaction cascade_mv64340 = { | 73 | static struct irqaction cascade_mv64340 = { |
45 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL | 74 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL |
@@ -53,8 +82,6 @@ void __init arch_init_irq(void) | |||
53 | */ | 82 | */ |
54 | clear_c0_status(ST0_IM); | 83 | clear_c0_status(ST0_IM); |
55 | 84 | ||
56 | /* Sets the first-level interrupt dispatcher. */ | ||
57 | set_except_vector(0, jaguar_handle_int); | ||
58 | mips_cpu_irq_init(0); | 85 | mips_cpu_irq_init(0); |
59 | rm7k_cpu_irq_init(8); | 86 | rm7k_cpu_irq_init(8); |
60 | 87 | ||
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c index 91d9637143d7..1379c76845dc 100644 --- a/arch/mips/momentum/jaguar_atx/setup.c +++ b/arch/mips/momentum/jaguar_atx/setup.c | |||
@@ -381,24 +381,24 @@ void __init plat_setup(void) | |||
381 | * shut down ethernet ports, just to be sure our memory doesn't get | 381 | * shut down ethernet ports, just to be sure our memory doesn't get |
382 | * corrupted by random ethernet traffic. | 382 | * corrupted by random ethernet traffic. |
383 | */ | 383 | */ |
384 | MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); | 384 | MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); |
385 | MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); | 385 | MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); |
386 | MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2), 0xff << 8); | 386 | MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(2), 0xff << 8); |
387 | MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); | 387 | MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); |
388 | MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); | 388 | MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); |
389 | MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0xff << 8); | 389 | MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0xff << 8); |
390 | while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); | 390 | while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); |
391 | while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); | 391 | while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); |
392 | while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2)) & 0xff); | 392 | while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(2)) & 0xff); |
393 | while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); | 393 | while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); |
394 | while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); | 394 | while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); |
395 | while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2)) & 0xff); | 395 | while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(2)) & 0xff); |
396 | MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), | 396 | MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0), |
397 | MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); | 397 | MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); |
398 | MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), | 398 | MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1), |
399 | MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); | 399 | MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); |
400 | MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2), | 400 | MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(2), |
401 | MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2)) & ~1); | 401 | MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(2)) & ~1); |
402 | 402 | ||
403 | /* Turn off the Bit-Error LED */ | 403 | /* Turn off the Bit-Error LED */ |
404 | JAGUAR_FPGA_WRITE(0x80, CLR); | 404 | JAGUAR_FPGA_WRITE(0x80, CLR); |
diff --git a/arch/mips/momentum/ocelot_3/Makefile b/arch/mips/momentum/ocelot_3/Makefile index aab8fd89f830..8bcea64dd27b 100644 --- a/arch/mips/momentum/ocelot_3/Makefile +++ b/arch/mips/momentum/ocelot_3/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | # removes any old dependencies. DON'T put your own dependencies here | 5 | # removes any old dependencies. DON'T put your own dependencies here |
6 | # unless it's something special (ie not a .c file). | 6 | # unless it's something special (ie not a .c file). |
7 | # | 7 | # |
8 | obj-y += int-handler.o irq.o prom.o reset.o setup.o | 8 | obj-y += irq.o prom.o reset.o setup.o |
diff --git a/arch/mips/momentum/ocelot_3/int-handler.S b/arch/mips/momentum/ocelot_3/int-handler.S deleted file mode 100644 index 4522f09ed769..000000000000 --- a/arch/mips/momentum/ocelot_3/int-handler.S +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2002 Momentum Computer Inc. | ||
3 | * Author: Matthew Dharm <mdharm@momenco.com> | ||
4 | * | ||
5 | * Copyright 2001 MontaVista Software Inc. | ||
6 | * Author: jsun@mvista.com or jsun@junsun.net | ||
7 | * | ||
8 | * Copyright 2004 PMC-Sierra | ||
9 | * Author: Manish Lachwani (lachwani@pmc-sierra.com) | ||
10 | * | ||
11 | * Copyright (C) 2004 MontaVista Software Inc. | ||
12 | * Author: Manish Lachwani, mlachwani@mvista.com | ||
13 | * | ||
14 | * First-level interrupt dispatcher for Ocelot-3 board. | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify it | ||
17 | * under the terms of the GNU General Public License as published by the | ||
18 | * Free Software Foundation; either version 2 of the License, or (at your | ||
19 | * option) any later version. | ||
20 | */ | ||
21 | #include <asm/asm.h> | ||
22 | #include <asm/mipsregs.h> | ||
23 | #include <asm/addrspace.h> | ||
24 | #include <asm/regdef.h> | ||
25 | #include <asm/stackframe.h> | ||
26 | |||
27 | /* | ||
28 | * First level interrupt dispatcher for Ocelot-3 board | ||
29 | */ | ||
30 | .align 5 | ||
31 | NESTED(ocelot3_handle_int, PT_SIZE, sp) | ||
32 | SAVE_ALL | ||
33 | CLI | ||
34 | .set at | ||
35 | |||
36 | mfc0 t0, CP0_CAUSE | ||
37 | mfc0 t2, CP0_STATUS | ||
38 | |||
39 | and t0, t2 | ||
40 | |||
41 | andi t1, t0, STATUSF_IP0 /* sw0 software interrupt (IRQ0) */ | ||
42 | bnez t1, ll_sw0_irq | ||
43 | |||
44 | andi t1, t0, STATUSF_IP1 /* sw1 software interrupt (IRQ1) */ | ||
45 | bnez t1, ll_sw1_irq | ||
46 | |||
47 | andi t1, t0, STATUSF_IP2 /* int0 hardware line (IRQ2) */ | ||
48 | bnez t1, ll_pci0slot1_irq | ||
49 | |||
50 | andi t1, t0, STATUSF_IP3 /* int1 hardware line (IRQ3) */ | ||
51 | bnez t1, ll_pci0slot2_irq | ||
52 | |||
53 | andi t1, t0, STATUSF_IP4 /* int2 hardware line (IRQ4) */ | ||
54 | bnez t1, ll_pci1slot1_irq | ||
55 | |||
56 | andi t1, t0, STATUSF_IP5 /* int3 hardware line (IRQ5) */ | ||
57 | bnez t1, ll_pci1slot2_irq | ||
58 | |||
59 | andi t1, t0, STATUSF_IP6 /* int4 hardware line (IRQ6) */ | ||
60 | bnez t1, ll_uart_irq | ||
61 | |||
62 | andi t1, t0, STATUSF_IP7 /* cpu timer (IRQ7) */ | ||
63 | bnez t1, ll_cputimer_irq | ||
64 | |||
65 | /* now look at extended interrupts */ | ||
66 | mfc0 t0, CP0_CAUSE | ||
67 | cfc0 t1, CP0_S1_INTCONTROL | ||
68 | |||
69 | /* shift the mask 8 bits left to line up the bits */ | ||
70 | sll t2, t1, 8 | ||
71 | |||
72 | and t0, t2 | ||
73 | srl t0, t0, 16 | ||
74 | |||
75 | andi t1, t0, STATUSF_IP8 /* int6 hardware line (IRQ9) */ | ||
76 | bnez t1, ll_mv64340_decode_irq | ||
77 | |||
78 | .set reorder | ||
79 | |||
80 | /* wrong alarm or masked ... */ | ||
81 | j spurious_interrupt | ||
82 | nop | ||
83 | END(ocelot3_handle_int) | ||
84 | |||
85 | .align 5 | ||
86 | ll_sw0_irq: | ||
87 | li a0, 0 /* IRQ 1 */ | ||
88 | move a1, sp | ||
89 | jal do_IRQ | ||
90 | j ret_from_irq | ||
91 | ll_sw1_irq: | ||
92 | li a0, 1 /* IRQ 2 */ | ||
93 | move a1, sp | ||
94 | jal do_IRQ | ||
95 | j ret_from_irq | ||
96 | |||
97 | ll_pci0slot1_irq: | ||
98 | li a0, 2 /* IRQ 3 */ | ||
99 | move a1, sp | ||
100 | jal do_IRQ | ||
101 | j ret_from_irq | ||
102 | |||
103 | ll_pci0slot2_irq: | ||
104 | li a0, 3 /* IRQ 4 */ | ||
105 | move a1, sp | ||
106 | jal do_IRQ | ||
107 | j ret_from_irq | ||
108 | |||
109 | ll_pci1slot1_irq: | ||
110 | li a0, 4 /* IRQ 5 */ | ||
111 | move a1, sp | ||
112 | jal do_IRQ | ||
113 | j ret_from_irq | ||
114 | |||
115 | ll_pci1slot2_irq: | ||
116 | li a0, 5 /* IRQ 6 */ | ||
117 | move a1, sp | ||
118 | jal do_IRQ | ||
119 | j ret_from_irq | ||
120 | |||
121 | ll_uart_irq: | ||
122 | li a0, 6 /* IRQ 7 */ | ||
123 | move a1, sp | ||
124 | jal do_IRQ | ||
125 | j ret_from_irq | ||
126 | |||
127 | ll_cputimer_irq: | ||
128 | li a0, 7 /* IRQ 8 */ | ||
129 | move a1, sp | ||
130 | jal do_IRQ | ||
131 | j ret_from_irq | ||
132 | |||
133 | ll_mv64340_decode_irq: | ||
134 | move a0, sp | ||
135 | jal ll_mv64340_irq | ||
136 | j ret_from_irq | ||
137 | |||
diff --git a/arch/mips/momentum/ocelot_3/irq.c b/arch/mips/momentum/ocelot_3/irq.c index 42464dbd4ad2..87c63c340ae3 100644 --- a/arch/mips/momentum/ocelot_3/irq.c +++ b/arch/mips/momentum/ocelot_3/irq.c | |||
@@ -53,8 +53,6 @@ | |||
53 | #include <asm/mipsregs.h> | 53 | #include <asm/mipsregs.h> |
54 | #include <asm/system.h> | 54 | #include <asm/system.h> |
55 | 55 | ||
56 | extern asmlinkage void ocelot3_handle_int(void); | ||
57 | |||
58 | static struct irqaction cascade_mv64340 = { | 56 | static struct irqaction cascade_mv64340 = { |
59 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL | 57 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL |
60 | }; | 58 | }; |
@@ -67,9 +65,6 @@ void __init arch_init_irq(void) | |||
67 | */ | 65 | */ |
68 | clear_c0_status(ST0_IM | ST0_BEV); | 66 | clear_c0_status(ST0_IM | ST0_BEV); |
69 | 67 | ||
70 | /* Sets the first-level interrupt dispatcher. */ | ||
71 | set_except_vector(0, ocelot3_handle_int); | ||
72 | mips_cpu_irq_init(0); | ||
73 | rm7k_cpu_irq_init(8); | 68 | rm7k_cpu_irq_init(8); |
74 | 69 | ||
75 | /* set up the cascading interrupts */ | 70 | /* set up the cascading interrupts */ |
@@ -79,3 +74,36 @@ void __init arch_init_irq(void) | |||
79 | set_c0_status(ST0_IM); /* IE in the status register */ | 74 | set_c0_status(ST0_IM); /* IE in the status register */ |
80 | 75 | ||
81 | } | 76 | } |
77 | |||
78 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
79 | { | ||
80 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
81 | |||
82 | if (pending & STATUSF_IP0) | ||
83 | do_IRQ(0, regs); | ||
84 | else if (pending & STATUSF_IP1) | ||
85 | do_IRQ(1, regs); | ||
86 | else if (pending & STATUSF_IP2) | ||
87 | do_IRQ(2, regs); | ||
88 | else if (pending & STATUSF_IP3) | ||
89 | do_IRQ(3, regs); | ||
90 | else if (pending & STATUSF_IP4) | ||
91 | do_IRQ(4, regs); | ||
92 | else if (pending & STATUSF_IP5) | ||
93 | do_IRQ(5, regs); | ||
94 | else if (pending & STATUSF_IP6) | ||
95 | do_IRQ(6, regs); | ||
96 | else if (pending & STATUSF_IP7) | ||
97 | do_IRQ(7, regs); | ||
98 | else { | ||
99 | /* | ||
100 | * Now look at the extended interrupts | ||
101 | */ | ||
102 | pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; | ||
103 | |||
104 | if (pending & STATUSF_IP8) | ||
105 | ll_mv64340_irq(regs); | ||
106 | else | ||
107 | spurious_interrupt(regs); | ||
108 | } | ||
109 | } | ||
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c index 370e75d0e75c..c69195234309 100644 --- a/arch/mips/momentum/ocelot_3/setup.c +++ b/arch/mips/momentum/ocelot_3/setup.c | |||
@@ -329,22 +329,22 @@ void __init plat_setup(void) | |||
329 | /* shut down ethernet ports, just to be sure our memory doesn't get | 329 | /* shut down ethernet ports, just to be sure our memory doesn't get |
330 | * corrupted by random ethernet traffic. | 330 | * corrupted by random ethernet traffic. |
331 | */ | 331 | */ |
332 | MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); | 332 | MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); |
333 | MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); | 333 | MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); |
334 | MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); | 334 | MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); |
335 | MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); | 335 | MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); |
336 | do {} | 336 | do {} |
337 | while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); | 337 | while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); |
338 | do {} | 338 | do {} |
339 | while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); | 339 | while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); |
340 | do {} | 340 | do {} |
341 | while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); | 341 | while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); |
342 | do {} | 342 | do {} |
343 | while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); | 343 | while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); |
344 | MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), | 344 | MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0), |
345 | MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); | 345 | MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); |
346 | MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), | 346 | MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1), |
347 | MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); | 347 | MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); |
348 | 348 | ||
349 | /* Turn off the Bit-Error LED */ | 349 | /* Turn off the Bit-Error LED */ |
350 | OCELOT_FPGA_WRITE(0x80, CLR); | 350 | OCELOT_FPGA_WRITE(0x80, CLR); |
diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile index 91240777f978..94802b4db472 100644 --- a/arch/mips/momentum/ocelot_c/Makefile +++ b/arch/mips/momentum/ocelot_c/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for Momentum Computer's Ocelot-C and -CS boards. | 2 | # Makefile for Momentum Computer's Ocelot-C and -CS boards. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += cpci-irq.o int-handler.o irq.o prom.o reset.o \ | 5 | obj-y += cpci-irq.o irq.o prom.o reset.o \ |
6 | setup.o uart-irq.o | 6 | setup.o uart-irq.o |
7 | 7 | ||
8 | obj-$(CONFIG_KGDB) += dbg_io.o | 8 | obj-$(CONFIG_KGDB) += dbg_io.o |
diff --git a/arch/mips/momentum/ocelot_c/int-handler.S b/arch/mips/momentum/ocelot_c/int-handler.S deleted file mode 100644 index 52349d9bf1be..000000000000 --- a/arch/mips/momentum/ocelot_c/int-handler.S +++ /dev/null | |||
@@ -1,102 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2002 Momentum Computer Inc. | ||
3 | * Author: Matthew Dharm <mdharm@momenco.com> | ||
4 | * | ||
5 | * Copyright 2001 MontaVista Software Inc. | ||
6 | * Author: jsun@mvista.com or jsun@junsun.net | ||
7 | * | ||
8 | * First-level interrupt dispatcher for Ocelot-CS board. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | #include <asm/asm.h> | ||
16 | #include <asm/mipsregs.h> | ||
17 | #include <asm/addrspace.h> | ||
18 | #include <asm/regdef.h> | ||
19 | #include <asm/stackframe.h> | ||
20 | #include "ocelot_c_fpga.h" | ||
21 | |||
22 | /* | ||
23 | * First level interrupt dispatcher for Ocelot-CS board | ||
24 | */ | ||
25 | .align 5 | ||
26 | NESTED(ocelot_handle_int, PT_SIZE, sp) | ||
27 | SAVE_ALL | ||
28 | CLI | ||
29 | .set at | ||
30 | mfc0 t0, CP0_CAUSE | ||
31 | mfc0 t2, CP0_STATUS | ||
32 | |||
33 | and t0, t2 | ||
34 | |||
35 | andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */ | ||
36 | bnez t1, ll_sw0_irq | ||
37 | andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */ | ||
38 | bnez t1, ll_sw1_irq | ||
39 | andi t1, t0, STATUSF_IP2 /* int0 hardware line */ | ||
40 | bnez t1, ll_scsi_irq | ||
41 | andi t1, t0, STATUSF_IP3 /* int1 hardware line */ | ||
42 | bnez t1, ll_uart_decode_irq | ||
43 | andi t1, t0, STATUSF_IP4 /* int2 hardware line */ | ||
44 | bnez t1, ll_pmc_irq | ||
45 | andi t1, t0, STATUSF_IP5 /* int3 hardware line */ | ||
46 | bnez t1, ll_cpci_decode_irq | ||
47 | andi t1, t0, STATUSF_IP6 /* int4 hardware line */ | ||
48 | bnez t1, ll_mv64340_decode_irq | ||
49 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
50 | bnez t1, ll_cputimer_irq | ||
51 | |||
52 | .set reorder | ||
53 | |||
54 | /* wrong alarm or masked ... */ | ||
55 | j spurious_interrupt | ||
56 | nop | ||
57 | END(ocelot_handle_int) | ||
58 | |||
59 | .align 5 | ||
60 | ll_sw0_irq: | ||
61 | li a0, 0 | ||
62 | move a1, sp | ||
63 | jal do_IRQ | ||
64 | j ret_from_irq | ||
65 | ll_sw1_irq: | ||
66 | li a0, 1 | ||
67 | move a1, sp | ||
68 | jal do_IRQ | ||
69 | j ret_from_irq | ||
70 | ll_scsi_irq: | ||
71 | li a0, 2 | ||
72 | move a1, sp | ||
73 | jal do_IRQ | ||
74 | j ret_from_irq | ||
75 | |||
76 | ll_uart_decode_irq: | ||
77 | move a0, sp | ||
78 | jal ll_uart_irq | ||
79 | j ret_from_irq | ||
80 | |||
81 | ll_pmc_irq: | ||
82 | li a0, 4 | ||
83 | move a1, sp | ||
84 | jal do_IRQ | ||
85 | j ret_from_irq | ||
86 | |||
87 | ll_cpci_decode_irq: | ||
88 | move a0, sp | ||
89 | jal ll_cpci_irq | ||
90 | j ret_from_irq | ||
91 | |||
92 | ll_mv64340_decode_irq: | ||
93 | move a0, sp | ||
94 | jal ll_mv64340_irq | ||
95 | j ret_from_irq | ||
96 | |||
97 | ll_cputimer_irq: | ||
98 | li a0, 7 | ||
99 | move a1, sp | ||
100 | jal do_IRQ | ||
101 | j ret_from_irq | ||
102 | |||
diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c index a5764bc20e36..86f61ce59e53 100644 --- a/arch/mips/momentum/ocelot_c/irq.c +++ b/arch/mips/momentum/ocelot_c/irq.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <asm/mipsregs.h> | 48 | #include <asm/mipsregs.h> |
49 | #include <asm/system.h> | 49 | #include <asm/system.h> |
50 | 50 | ||
51 | extern asmlinkage void ocelot_handle_int(void); | ||
52 | extern void uart_irq_init(void); | 51 | extern void uart_irq_init(void); |
53 | extern void cpci_irq_init(void); | 52 | extern void cpci_irq_init(void); |
54 | 53 | ||
@@ -60,6 +59,33 @@ static struct irqaction cascade_mv64340 = { | |||
60 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL | 59 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL |
61 | }; | 60 | }; |
62 | 61 | ||
62 | extern void ll_uart_irq(struct pt_regs *regs); | ||
63 | extern void ll_cpci_irq(struct pt_regs *regs); | ||
64 | |||
65 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
66 | { | ||
67 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
68 | |||
69 | if (pending & STATUSF_IP0) | ||
70 | do_IRQ(0, regs); | ||
71 | else if (pending & STATUSF_IP1) | ||
72 | do_IRQ(1, regs); | ||
73 | else if (pending & STATUSF_IP2) | ||
74 | do_IRQ(2, regs); | ||
75 | else if (pending & STATUSF_IP3) | ||
76 | ll_uart_irq(regs); | ||
77 | else if (pending & STATUSF_IP4) | ||
78 | do_IRQ(4, regs); | ||
79 | else if (pending & STATUSF_IP5) | ||
80 | ll_cpci_irq(regs); | ||
81 | else if (pending & STATUSF_IP6) | ||
82 | ll_mv64340_irq(regs); | ||
83 | else if (pending & STATUSF_IP7) | ||
84 | do_IRQ(7, regs); | ||
85 | else | ||
86 | spurious_interrupt(regs); | ||
87 | } | ||
88 | |||
63 | void __init arch_init_irq(void) | 89 | void __init arch_init_irq(void) |
64 | { | 90 | { |
65 | /* | 91 | /* |
@@ -68,8 +94,6 @@ void __init arch_init_irq(void) | |||
68 | */ | 94 | */ |
69 | clear_c0_status(ST0_IM); | 95 | clear_c0_status(ST0_IM); |
70 | 96 | ||
71 | /* Sets the first-level interrupt dispatcher. */ | ||
72 | set_except_vector(0, ocelot_handle_int); | ||
73 | mips_cpu_irq_init(0); | 97 | mips_cpu_irq_init(0); |
74 | 98 | ||
75 | /* set up the cascading interrupts */ | 99 | /* set up the cascading interrupts */ |
diff --git a/arch/mips/momentum/ocelot_g/Makefile b/arch/mips/momentum/ocelot_g/Makefile index e5f1cb086973..adb5665d40a9 100644 --- a/arch/mips/momentum/ocelot_g/Makefile +++ b/arch/mips/momentum/ocelot_g/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for Momentum Computer's Ocelot-G board. | 2 | # Makefile for Momentum Computer's Ocelot-G board. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += int-handler.o irq.o gt-irq.o prom.o reset.o setup.o | 5 | obj-y += irq.o gt-irq.o prom.o reset.o setup.o |
6 | obj-$(CONFIG_KGDB) += dbg_io.o | 6 | obj-$(CONFIG_KGDB) += dbg_io.o |
7 | 7 | ||
8 | EXTRA_AFLAGS := $(CFLAGS) | 8 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/momentum/ocelot_g/int-handler.S b/arch/mips/momentum/ocelot_g/int-handler.S deleted file mode 100644 index 772e8f713176..000000000000 --- a/arch/mips/momentum/ocelot_g/int-handler.S +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: jsun@mvista.com or jsun@junsun.net | ||
4 | * | ||
5 | * First-level interrupt dispatcher for ocelot board. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | |||
18 | /* | ||
19 | * first level interrupt dispatcher for ocelot board - | ||
20 | * We check for the timer first, then check PCI ints A and D. | ||
21 | * Then check for serial IRQ and fall through. | ||
22 | */ | ||
23 | .align 5 | ||
24 | NESTED(ocelot_handle_int, PT_SIZE, sp) | ||
25 | SAVE_ALL | ||
26 | CLI | ||
27 | .set at | ||
28 | mfc0 t0, CP0_CAUSE | ||
29 | mfc0 t2, CP0_STATUS | ||
30 | |||
31 | and t0, t2 | ||
32 | |||
33 | andi t1, t0, STATUSF_IP2 /* int0 hardware line */ | ||
34 | bnez t1, ll_pri_enet_irq | ||
35 | andi t1, t0, STATUSF_IP3 /* int1 hardware line */ | ||
36 | bnez t1, ll_sec_enet_irq | ||
37 | andi t1, t0, STATUSF_IP4 /* int2 hardware line */ | ||
38 | bnez t1, ll_uart_irq | ||
39 | andi t1, t0, STATUSF_IP5 /* int3 hardware line */ | ||
40 | bnez t1, ll_cpci_irq | ||
41 | andi t1, t0, STATUSF_IP6 /* int4 hardware line */ | ||
42 | bnez t1, ll_galileo_p0_irq | ||
43 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
44 | bnez t1, ll_cputimer_irq | ||
45 | |||
46 | /* now look at the extended interrupts */ | ||
47 | mfc0 t0, CP0_CAUSE | ||
48 | cfc0 t1, CP0_S1_INTCONTROL | ||
49 | |||
50 | /* shift the mask 8 bits left to line up the bits */ | ||
51 | sll t2, t1, 8 | ||
52 | |||
53 | and t0, t2 | ||
54 | srl t0, t0, 16 | ||
55 | |||
56 | andi t1, t0, STATUSF_IP8 /* int6 hardware line */ | ||
57 | bnez t1, ll_galileo_p1_irq | ||
58 | andi t1, t0, STATUSF_IP9 /* int7 hardware line */ | ||
59 | bnez t1, ll_pmc_irq | ||
60 | andi t1, t0, STATUSF_IP10 /* int8 hardware line */ | ||
61 | bnez t1, ll_cpci_abcd_irq | ||
62 | andi t1, t0, STATUSF_IP11 /* int9 hardware line */ | ||
63 | bnez t1, ll_testpoint_irq | ||
64 | |||
65 | .set reorder | ||
66 | |||
67 | /* wrong alarm or masked ... */ | ||
68 | j spurious_interrupt | ||
69 | nop | ||
70 | END(ocelot_handle_int) | ||
71 | |||
72 | .align 5 | ||
73 | ll_pri_enet_irq: | ||
74 | li a0, 2 | ||
75 | move a1, sp | ||
76 | jal do_IRQ | ||
77 | j ret_from_irq | ||
78 | |||
79 | ll_sec_enet_irq: | ||
80 | li a0, 3 | ||
81 | move a1, sp | ||
82 | jal do_IRQ | ||
83 | j ret_from_irq | ||
84 | |||
85 | ll_uart_irq: | ||
86 | li a0, 4 | ||
87 | move a1, sp | ||
88 | jal do_IRQ | ||
89 | j ret_from_irq | ||
90 | |||
91 | ll_cpci_irq: | ||
92 | li a0, 5 | ||
93 | move a1, sp | ||
94 | jal do_IRQ | ||
95 | j ret_from_irq | ||
96 | |||
97 | ll_galileo_p0_irq: | ||
98 | li a0, 6 | ||
99 | move a1, sp | ||
100 | jal do_IRQ | ||
101 | j ret_from_irq | ||
102 | |||
103 | ll_cputimer_irq: | ||
104 | li a0, 7 | ||
105 | move a1, sp | ||
106 | jal do_IRQ | ||
107 | j ret_from_irq | ||
108 | |||
109 | ll_galileo_p1_irq: | ||
110 | li a0, 8 | ||
111 | move a1, sp | ||
112 | jal do_IRQ | ||
113 | j ret_from_irq | ||
114 | |||
115 | ll_pmc_irq: | ||
116 | li a0, 9 | ||
117 | move a1, sp | ||
118 | jal do_IRQ | ||
119 | j ret_from_irq | ||
120 | |||
121 | ll_cpci_abcd_irq: | ||
122 | li a0, 10 | ||
123 | move a1, sp | ||
124 | jal do_IRQ | ||
125 | j ret_from_irq | ||
126 | |||
127 | ll_testpoint_irq: | ||
128 | li a0, 11 | ||
129 | move a1, sp | ||
130 | jal do_IRQ | ||
131 | j ret_from_irq | ||
diff --git a/arch/mips/momentum/ocelot_g/irq.c b/arch/mips/momentum/ocelot_g/irq.c index 5eb85b164205..7a4a419804f1 100644 --- a/arch/mips/momentum/ocelot_g/irq.c +++ b/arch/mips/momentum/ocelot_g/irq.c | |||
@@ -48,7 +48,41 @@ | |||
48 | #include <asm/mipsregs.h> | 48 | #include <asm/mipsregs.h> |
49 | #include <asm/system.h> | 49 | #include <asm/system.h> |
50 | 50 | ||
51 | extern asmlinkage void ocelot_handle_int(void); | 51 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
52 | { | ||
53 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
54 | |||
55 | if (pending & STATUSF_IP2) | ||
56 | do_IRQ(2, regs); | ||
57 | else if (pending & STATUSF_IP3) | ||
58 | do_IRQ(3, regs); | ||
59 | else if (pending & STATUSF_IP4) | ||
60 | do_IRQ(4, regs); | ||
61 | else if (pending & STATUSF_IP5) | ||
62 | do_IRQ(5, regs); | ||
63 | else if (pending & STATUSF_IP6) | ||
64 | do_IRQ(6, regs); | ||
65 | else if (pending & STATUSF_IP7) | ||
66 | do_IRQ(7, regs); | ||
67 | else { | ||
68 | /* | ||
69 | * Now look at the extended interrupts | ||
70 | */ | ||
71 | pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; | ||
72 | |||
73 | if (pending & STATUSF_IP8) | ||
74 | do_IRQ(8, regs); | ||
75 | else if (pending & STATUSF_IP9) | ||
76 | do_IRQ(9, regs); | ||
77 | else if (pending & STATUSF_IP10) | ||
78 | do_IRQ(10, regs); | ||
79 | else if (pending & STATUSF_IP11) | ||
80 | do_IRQ(11, regs); | ||
81 | else | ||
82 | spurious_interrupt(regs); | ||
83 | } | ||
84 | } | ||
85 | |||
52 | extern void gt64240_irq_init(void); | 86 | extern void gt64240_irq_init(void); |
53 | 87 | ||
54 | void __init arch_init_irq(void) | 88 | void __init arch_init_irq(void) |
@@ -60,8 +94,6 @@ void __init arch_init_irq(void) | |||
60 | clear_c0_status(ST0_IM); | 94 | clear_c0_status(ST0_IM); |
61 | local_irq_disable(); | 95 | local_irq_disable(); |
62 | 96 | ||
63 | /* Sets the first-level interrupt dispatcher. */ | ||
64 | set_except_vector(0, ocelot_handle_int); | ||
65 | mips_cpu_irq_init(0); | 97 | mips_cpu_irq_init(0); |
66 | rm7k_cpu_irq_init(8); | 98 | rm7k_cpu_irq_init(8); |
67 | 99 | ||
diff --git a/arch/mips/philips/pnx8550/common/Makefile b/arch/mips/philips/pnx8550/common/Makefile index 6e38f3bc443c..b7c638166e9f 100644 --- a/arch/mips/philips/pnx8550/common/Makefile +++ b/arch/mips/philips/pnx8550/common/Makefile | |||
@@ -22,6 +22,6 @@ | |||
22 | # under Linux. | 22 | # under Linux. |
23 | # | 23 | # |
24 | 24 | ||
25 | obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o | 25 | obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o |
26 | obj-$(CONFIG_PCI) += pci.o | 26 | obj-$(CONFIG_PCI) += pci.o |
27 | obj-$(CONFIG_KGDB) += gdb_hook.o | 27 | obj-$(CONFIG_KGDB) += gdb_hook.o |
diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c index c500e2d41f2c..39ee6314f627 100644 --- a/arch/mips/philips/pnx8550/common/int.c +++ b/arch/mips/philips/pnx8550/common/int.c | |||
@@ -38,8 +38,6 @@ | |||
38 | #include <int.h> | 38 | #include <int.h> |
39 | #include <uart.h> | 39 | #include <uart.h> |
40 | 40 | ||
41 | extern asmlinkage void cp0_irqdispatch(void); | ||
42 | |||
43 | static DEFINE_SPINLOCK(irq_lock); | 41 | static DEFINE_SPINLOCK(irq_lock); |
44 | 42 | ||
45 | /* default prio for interrupts */ | 43 | /* default prio for interrupts */ |
@@ -55,7 +53,7 @@ static char gic_prio[PNX8550_INT_GIC_TOTINT] = { | |||
55 | 1 // 70 | 53 | 1 // 70 |
56 | }; | 54 | }; |
57 | 55 | ||
58 | void hw0_irqdispatch(int irq, struct pt_regs *regs) | 56 | static void hw0_irqdispatch(int irq, struct pt_regs *regs) |
59 | { | 57 | { |
60 | /* find out which interrupt */ | 58 | /* find out which interrupt */ |
61 | irq = PNX8550_GIC_VECTOR_0 >> 3; | 59 | irq = PNX8550_GIC_VECTOR_0 >> 3; |
@@ -68,7 +66,7 @@ void hw0_irqdispatch(int irq, struct pt_regs *regs) | |||
68 | } | 66 | } |
69 | 67 | ||
70 | 68 | ||
71 | void timer_irqdispatch(int irq, struct pt_regs *regs) | 69 | static void timer_irqdispatch(int irq, struct pt_regs *regs) |
72 | { | 70 | { |
73 | irq = (0x01c0 & read_c0_config7()) >> 6; | 71 | irq = (0x01c0 & read_c0_config7()) >> 6; |
74 | 72 | ||
@@ -88,6 +86,20 @@ void timer_irqdispatch(int irq, struct pt_regs *regs) | |||
88 | } | 86 | } |
89 | } | 87 | } |
90 | 88 | ||
89 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
90 | { | ||
91 | unsigned int pending = read_c0_status() & read_c0_cause(); | ||
92 | |||
93 | if (pending & STATUSF_IP2) | ||
94 | do_IRQ(2, regs); | ||
95 | else if (pending & STATUSF_IP7) { | ||
96 | if (read_c0_config7() & 0x01c0) | ||
97 | timer_irqdispatch(7, regs); | ||
98 | } | ||
99 | |||
100 | spurious_interrupt(regs); | ||
101 | } | ||
102 | |||
91 | static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) | 103 | static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) |
92 | { | 104 | { |
93 | unsigned long status = read_c0_status(); | 105 | unsigned long status = read_c0_status(); |
@@ -223,9 +235,6 @@ void __init arch_init_irq(void) | |||
223 | int i; | 235 | int i; |
224 | int configPR; | 236 | int configPR; |
225 | 237 | ||
226 | /* init of cp0 interrupts */ | ||
227 | set_except_vector(0, cp0_irqdispatch); | ||
228 | |||
229 | for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { | 238 | for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { |
230 | irq_desc[i].handler = &level_irq_type; | 239 | irq_desc[i].handler = &level_irq_type; |
231 | pnx8550_ack(i); /* mask the irq just in case */ | 240 | pnx8550_ack(i); /* mask the irq just in case */ |
diff --git a/arch/mips/philips/pnx8550/common/mipsIRQ.S b/arch/mips/philips/pnx8550/common/mipsIRQ.S deleted file mode 100644 index 338bffda3fab..000000000000 --- a/arch/mips/philips/pnx8550/common/mipsIRQ.S +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2002 Philips, Inc. All rights. | ||
3 | * Copyright (c) 2002 Red Hat, Inc. All rights. | ||
4 | * | ||
5 | * This software may be freely redistributed under the terms of the | ||
6 | * GNU General Public License. | ||
7 | * | ||
8 | * You should have received a copy of the GNU General Public License | ||
9 | * along with this program; if not, write to the Free Software | ||
10 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
11 | * | ||
12 | * Based upon arch/mips/galileo-boards/ev64240/int-handler.S | ||
13 | * | ||
14 | */ | ||
15 | #include <asm/asm.h> | ||
16 | #include <asm/mipsregs.h> | ||
17 | #include <asm/addrspace.h> | ||
18 | #include <asm/regdef.h> | ||
19 | #include <asm/stackframe.h> | ||
20 | |||
21 | /* | ||
22 | * cp0_irqdispatch | ||
23 | * | ||
24 | * Code to handle in-core interrupt exception. | ||
25 | */ | ||
26 | |||
27 | .align 5 | ||
28 | .set reorder | ||
29 | .set noat | ||
30 | NESTED(cp0_irqdispatch, PT_SIZE, sp) | ||
31 | SAVE_ALL | ||
32 | CLI | ||
33 | .set at | ||
34 | mfc0 t0,CP0_CAUSE | ||
35 | mfc0 t2,CP0_STATUS | ||
36 | |||
37 | and t0,t2 | ||
38 | |||
39 | andi t1,t0,STATUSF_IP2 /* int0 hardware line */ | ||
40 | bnez t1,ll_hw0_irq | ||
41 | nop | ||
42 | |||
43 | andi t1,t0,STATUSF_IP7 /* int5 hardware line */ | ||
44 | bnez t1,ll_timer_irq | ||
45 | nop | ||
46 | |||
47 | /* wrong alarm or masked ... */ | ||
48 | |||
49 | j spurious_interrupt | ||
50 | nop | ||
51 | END(cp0_irqdispatch) | ||
52 | |||
53 | .align 5 | ||
54 | .set reorder | ||
55 | ll_hw0_irq: | ||
56 | li a0,2 | ||
57 | move a1,sp | ||
58 | jal hw0_irqdispatch | ||
59 | nop | ||
60 | j ret_from_irq | ||
61 | nop | ||
62 | |||
63 | .align 5 | ||
64 | .set reorder | ||
65 | ll_timer_irq: | ||
66 | mfc0 t3,CP0_CONFIG,7 | ||
67 | andi t4,t3,0x01c0 | ||
68 | beqz t4,ll_timer_out | ||
69 | nop | ||
70 | li a0,7 | ||
71 | move a1,sp | ||
72 | jal timer_irqdispatch | ||
73 | nop | ||
74 | |||
75 | ll_timer_out: j ret_from_irq | ||
76 | nop | ||
diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c index a592260fd673..5436b4b97455 100644 --- a/arch/mips/philips/pnx8550/common/platform.c +++ b/arch/mips/philips/pnx8550/common/platform.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/resource.h> | 18 | #include <linux/resource.h> |
19 | #include <linux/serial.h> | 19 | #include <linux/serial.h> |
20 | #include <linux/serial_ip3106.h> | 20 | #include <linux/serial_ip3106.h> |
21 | #include <linux/platform_device.h> | ||
21 | 22 | ||
22 | #include <int.h> | 23 | #include <int.h> |
23 | #include <usb.h> | 24 | #include <usb.h> |
diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile index ae96a71a3089..e931e0d44229 100644 --- a/arch/mips/pmc-sierra/yosemite/Makefile +++ b/arch/mips/pmc-sierra/yosemite/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the PMC-Sierra Titan | 2 | # Makefile for the PMC-Sierra Titan |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o | 5 | obj-y += irq.o i2c-yosemite.o prom.o py-console.o setup.o |
6 | 6 | ||
7 | obj-$(CONFIG_KGDB) += dbg_io.o | 7 | obj-$(CONFIG_KGDB) += dbg_io.o |
8 | obj-$(CONFIG_SMP) += smp.o | 8 | obj-$(CONFIG_SMP) += smp.o |
diff --git a/arch/mips/pmc-sierra/yosemite/irq-handler.S b/arch/mips/pmc-sierra/yosemite/irq-handler.S deleted file mode 100644 index 33b9c40d4f5c..000000000000 --- a/arch/mips/pmc-sierra/yosemite/irq-handler.S +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2003, 04 PMC-Sierra Inc. | ||
3 | * Author: Manish Lachwani (lachwani@pmc-sierra.com | ||
4 | * Copyright 2004 Ralf Baechle (ralf@linux-mips.org) | ||
5 | * | ||
6 | * First-level interrupt router for the PMC-Sierra Titan board | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * Titan supports Hypertransport or PCI but not both. Hence, one interrupt | ||
14 | * line is shared between the PCI slot A and Hypertransport. This is the | ||
15 | * Processor INTB #0. | ||
16 | */ | ||
17 | |||
18 | #include <linux/config.h> | ||
19 | #include <asm/asm.h> | ||
20 | #include <asm/mipsregs.h> | ||
21 | #include <asm/addrspace.h> | ||
22 | #include <asm/regdef.h> | ||
23 | #include <asm/stackframe.h> | ||
24 | |||
25 | .align 5 | ||
26 | NESTED(titan_handle_int, PT_SIZE, sp) | ||
27 | SAVE_ALL | ||
28 | CLI | ||
29 | .set at | ||
30 | .set noreorder | ||
31 | la ra, ret_from_irq | ||
32 | mfc0 t0, CP0_CAUSE | ||
33 | mfc0 t2, CP0_STATUS | ||
34 | |||
35 | and t0, t2 | ||
36 | |||
37 | andi t2, t0, STATUSF_IP7 /* INTB5 hardware line */ | ||
38 | bnez t2, ll_timer_irq /* Timer */ | ||
39 | andi t1, t0, STATUSF_IP2 /* INTB0 hardware line */ | ||
40 | bnez t1, ll_pcia_irq /* 64-bit PCI */ | ||
41 | andi t2, t0, STATUSF_IP3 /* INTB1 hardware line */ | ||
42 | bnez t2, ll_pcib_irq /* second 64-bit PCI slot */ | ||
43 | andi t1, t0, STATUSF_IP4 /* INTB2 hardware line */ | ||
44 | bnez t1, ll_duart_irq /* UART */ | ||
45 | andi t2, t0, STATUSF_IP5 /* SMP inter-core interrupts */ | ||
46 | bnez t2, ll_smp_irq | ||
47 | andi t1, t0, STATUSF_IP6 | ||
48 | bnez t1, ll_ht_irq /* Hypertransport */ | ||
49 | |||
50 | move a0, sp | ||
51 | j do_extended_irq | ||
52 | END(titan_handle_int) | ||
53 | |||
54 | .set reorder | ||
55 | .align 5 | ||
56 | |||
57 | ll_pcia_irq: | ||
58 | li a0, 2 | ||
59 | move a1, sp | ||
60 | #ifdef CONFIG_HYPERTRANSPORT | ||
61 | j ll_ht_smp_irq_handler | ||
62 | #else | ||
63 | j do_IRQ | ||
64 | #endif | ||
65 | |||
66 | ll_pcib_irq: | ||
67 | li a0, 3 | ||
68 | move a1, sp | ||
69 | j do_IRQ | ||
70 | |||
71 | ll_duart_irq: | ||
72 | li a0, 4 | ||
73 | move a1, sp | ||
74 | j do_IRQ | ||
75 | |||
76 | ll_smp_irq: | ||
77 | li a0, 5 | ||
78 | move a1, sp | ||
79 | #ifdef CONFIG_SMP | ||
80 | j titan_mailbox_irq | ||
81 | #else | ||
82 | j do_IRQ | ||
83 | #endif | ||
84 | |||
85 | ll_ht_irq: | ||
86 | li a0, 6 | ||
87 | move a1, sp | ||
88 | j ll_ht_smp_irq_handler | ||
89 | |||
90 | ll_timer_irq: | ||
91 | li a0, 7 | ||
92 | move a1, sp | ||
93 | j do_IRQ | ||
diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c index f4e2897d9bf7..a1f524fc4c10 100644 --- a/arch/mips/pmc-sierra/yosemite/irq.c +++ b/arch/mips/pmc-sierra/yosemite/irq.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * Copyright (C) 2003 PMC-Sierra Inc. | 2 | * Copyright (C) 2003 PMC-Sierra Inc. |
3 | * Author: Manish Lachwani (lachwani@pmc-sierra.com) | 3 | * Author: Manish Lachwani (lachwani@pmc-sierra.com) |
4 | * | 4 | * |
5 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | ||
6 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
7 | * Free Software Foundation; either version 2 of the License, or (at your | 9 | * Free Software Foundation; either version 2 of the License, or (at your |
@@ -55,7 +57,6 @@ | |||
55 | #define HYPERTRANSPORT_INTC 0x7a /* INTC# */ | 57 | #define HYPERTRANSPORT_INTC 0x7a /* INTC# */ |
56 | #define HYPERTRANSPORT_INTD 0x7b /* INTD# */ | 58 | #define HYPERTRANSPORT_INTD 0x7b /* INTD# */ |
57 | 59 | ||
58 | extern asmlinkage void titan_handle_int(void); | ||
59 | extern void jaguar_mailbox_irq(struct pt_regs *); | 60 | extern void jaguar_mailbox_irq(struct pt_regs *); |
60 | 61 | ||
61 | /* | 62 | /* |
@@ -125,6 +126,35 @@ asmlinkage void do_extended_irq(struct pt_regs *regs) | |||
125 | 126 | ||
126 | } | 127 | } |
127 | 128 | ||
129 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
130 | { | ||
131 | unsigned int cause = read_c0_cause(); | ||
132 | unsigned int status = read_c0_status(); | ||
133 | unsigned int pending = cause & status; | ||
134 | |||
135 | if (pending & STATUSF_IP7) { | ||
136 | do_IRQ(7, regs); | ||
137 | } else if (pending & STATUSF_IP2) { | ||
138 | #ifdef CONFIG_HYPERTRANSPORT | ||
139 | ll_ht_smp_irq_handler(2, regs); | ||
140 | #else | ||
141 | do_IRQ(2, regs); | ||
142 | #endif | ||
143 | } else if (pending & STATUSF_IP3) { | ||
144 | do_IRQ(3, regs); | ||
145 | } else if (pending & STATUSF_IP4) { | ||
146 | do_IRQ(4, regs); | ||
147 | } else if (pending & STATUSF_IP5) { | ||
148 | #ifdef CONFIG_SMP | ||
149 | titan_mailbox_irq(regs); | ||
150 | #else | ||
151 | do_IRQ(5, regs); | ||
152 | #endif | ||
153 | } else if (pending & STATUSF_IP6) { | ||
154 | do_IRQ(4, regs); | ||
155 | } | ||
156 | } | ||
157 | |||
128 | #ifdef CONFIG_KGDB | 158 | #ifdef CONFIG_KGDB |
129 | extern void init_second_port(void); | 159 | extern void init_second_port(void); |
130 | #endif | 160 | #endif |
@@ -136,7 +166,6 @@ void __init arch_init_irq(void) | |||
136 | { | 166 | { |
137 | clear_c0_status(ST0_IM); | 167 | clear_c0_status(ST0_IM); |
138 | 168 | ||
139 | set_except_vector(0, titan_handle_int); | ||
140 | mips_cpu_irq_init(0); | 169 | mips_cpu_irq_init(0); |
141 | rm7k_cpu_irq_init(8); | 170 | rm7k_cpu_irq_init(8); |
142 | rm9k_cpu_irq_init(12); | 171 | rm9k_cpu_irq_init(12); |
diff --git a/arch/mips/qemu/Makefile b/arch/mips/qemu/Makefile index 6a8e8bcef552..730f459f3e99 100644 --- a/arch/mips/qemu/Makefile +++ b/arch/mips/qemu/Makefile | |||
@@ -2,6 +2,6 @@ | |||
2 | # Makefile for Qemu specific kernel interface routines under Linux. | 2 | # Makefile for Qemu specific kernel interface routines under Linux. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y = q-firmware.o q-int.o q-irq.o q-mem.o q-setup.o | 5 | obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o |
6 | 6 | ||
7 | obj-$(CONFIG_SMP) += q-smp.o | 7 | obj-$(CONFIG_SMP) += q-smp.o |
diff --git a/arch/mips/qemu/q-int.S b/arch/mips/qemu/q-int.S deleted file mode 100644 index 6e3dfe5eb14b..000000000000 --- a/arch/mips/qemu/q-int.S +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* | ||
2 | * Qemu interrupt handler code. | ||
3 | * | ||
4 | * Copyright (C) 2005 by Ralf Baechle | ||
5 | */ | ||
6 | #include <asm/asm.h> | ||
7 | #include <asm/regdef.h> | ||
8 | #include <asm/stackframe.h> | ||
9 | |||
10 | .align 5 | ||
11 | NESTED(qemu_handle_int, PT_SIZE, sp) | ||
12 | SAVE_ALL | ||
13 | CLI | ||
14 | move a0, sp | ||
15 | PTR_LA ra, ret_from_irq | ||
16 | j do_qemu_int | ||
17 | END(qemu_handle_int) | ||
diff --git a/arch/mips/qemu/q-irq.c b/arch/mips/qemu/q-irq.c index 2c4e0704ff10..3352374c4c7d 100644 --- a/arch/mips/qemu/q-irq.c +++ b/arch/mips/qemu/q-irq.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | extern asmlinkage void qemu_handle_int(void); | 10 | extern asmlinkage void qemu_handle_int(void); |
11 | 11 | ||
12 | asmlinkage void do_qemu_int(struct pt_regs *regs) | 12 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
13 | { | 13 | { |
14 | unsigned int pending = read_c0_status() & read_c0_cause(); | 14 | unsigned int pending = read_c0_status() & read_c0_cause(); |
15 | 15 | ||
@@ -29,7 +29,6 @@ asmlinkage void do_qemu_int(struct pt_regs *regs) | |||
29 | 29 | ||
30 | void __init arch_init_irq(void) | 30 | void __init arch_init_irq(void) |
31 | { | 31 | { |
32 | set_except_vector(0, qemu_handle_int); | ||
33 | mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */ | 32 | mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */ |
34 | 33 | ||
35 | init_i8259_irqs(); | 34 | init_i8259_irqs(); |
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile index eb0820fe50bd..6aa4c0cd169c 100644 --- a/arch/mips/sgi-ip22/Makefile +++ b/arch/mips/sgi-ip22/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \ | 6 | obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ |
7 | ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o | 7 | ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o |
8 | 8 | ||
9 | obj-$(CONFIG_EISA) += ip22-eisa.o | 9 | obj-$(CONFIG_EISA) += ip22-eisa.o |
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index d16fb43b1a93..fc6a7e2b189c 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c | |||
@@ -37,7 +37,6 @@ static char lc1msk_to_irqnr[256]; | |||
37 | static char lc2msk_to_irqnr[256]; | 37 | static char lc2msk_to_irqnr[256]; |
38 | static char lc3msk_to_irqnr[256]; | 38 | static char lc3msk_to_irqnr[256]; |
39 | 39 | ||
40 | extern asmlinkage void indyIRQ(void); | ||
41 | extern int ip22_eisa_init(void); | 40 | extern int ip22_eisa_init(void); |
42 | 41 | ||
43 | static void enable_local0_irq(unsigned int irq) | 42 | static void enable_local0_irq(unsigned int irq) |
@@ -224,7 +223,7 @@ static struct hw_interrupt_type ip22_local3_irq_type = { | |||
224 | .end = end_local3_irq, | 223 | .end = end_local3_irq, |
225 | }; | 224 | }; |
226 | 225 | ||
227 | void indy_local0_irqdispatch(struct pt_regs *regs) | 226 | static void indy_local0_irqdispatch(struct pt_regs *regs) |
228 | { | 227 | { |
229 | u8 mask = sgint->istat0 & sgint->imask0; | 228 | u8 mask = sgint->istat0 & sgint->imask0; |
230 | u8 mask2; | 229 | u8 mask2; |
@@ -242,7 +241,7 @@ void indy_local0_irqdispatch(struct pt_regs *regs) | |||
242 | return; | 241 | return; |
243 | } | 242 | } |
244 | 243 | ||
245 | void indy_local1_irqdispatch(struct pt_regs *regs) | 244 | static void indy_local1_irqdispatch(struct pt_regs *regs) |
246 | { | 245 | { |
247 | u8 mask = sgint->istat1 & sgint->imask1; | 246 | u8 mask = sgint->istat1 & sgint->imask1; |
248 | u8 mask2; | 247 | u8 mask2; |
@@ -262,7 +261,7 @@ void indy_local1_irqdispatch(struct pt_regs *regs) | |||
262 | 261 | ||
263 | extern void ip22_be_interrupt(int irq, struct pt_regs *regs); | 262 | extern void ip22_be_interrupt(int irq, struct pt_regs *regs); |
264 | 263 | ||
265 | void indy_buserror_irq(struct pt_regs *regs) | 264 | static void indy_buserror_irq(struct pt_regs *regs) |
266 | { | 265 | { |
267 | int irq = SGI_BUSERR_IRQ; | 266 | int irq = SGI_BUSERR_IRQ; |
268 | 267 | ||
@@ -307,6 +306,56 @@ static struct irqaction map1_cascade = { | |||
307 | #define SGI_INTERRUPTS SGINT_LOCAL3 | 306 | #define SGI_INTERRUPTS SGINT_LOCAL3 |
308 | #endif | 307 | #endif |
309 | 308 | ||
309 | extern void indy_r4k_timer_interrupt(struct pt_regs *regs); | ||
310 | extern void indy_8254timer_irq(struct pt_regs *regs); | ||
311 | |||
312 | /* | ||
313 | * IRQs on the INDY look basically (barring software IRQs which we don't use | ||
314 | * at all) like: | ||
315 | * | ||
316 | * MIPS IRQ Source | ||
317 | * -------- ------ | ||
318 | * 0 Software (ignored) | ||
319 | * 1 Software (ignored) | ||
320 | * 2 Local IRQ level zero | ||
321 | * 3 Local IRQ level one | ||
322 | * 4 8254 Timer zero | ||
323 | * 5 8254 Timer one | ||
324 | * 6 Bus Error | ||
325 | * 7 R4k timer (what we use) | ||
326 | * | ||
327 | * We handle the IRQ according to _our_ priority which is: | ||
328 | * | ||
329 | * Highest ---- R4k Timer | ||
330 | * Local IRQ zero | ||
331 | * Local IRQ one | ||
332 | * Bus Error | ||
333 | * 8254 Timer zero | ||
334 | * Lowest ---- 8254 Timer one | ||
335 | * | ||
336 | * then we just return, if multiple IRQs are pending then we will just take | ||
337 | * another exception, big deal. | ||
338 | */ | ||
339 | |||
340 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
341 | { | ||
342 | unsigned int pending = read_c0_cause(); | ||
343 | |||
344 | /* | ||
345 | * First we check for r4k counter/timer IRQ. | ||
346 | */ | ||
347 | if (pending & CAUSEF_IP7) | ||
348 | indy_r4k_timer_interrupt(regs); | ||
349 | else if (pending & CAUSEF_IP2) | ||
350 | indy_local0_irqdispatch(regs); | ||
351 | else if (pending & CAUSEF_IP3) | ||
352 | indy_local1_irqdispatch(regs); | ||
353 | else if (pending & CAUSEF_IP6) | ||
354 | indy_buserror_irq(regs); | ||
355 | else if (pending & (CAUSEF_IP4 | CAUSEF_IP5)) | ||
356 | indy_8254timer_irq(regs); | ||
357 | } | ||
358 | |||
310 | extern void mips_cpu_irq_init(unsigned int irq_base); | 359 | extern void mips_cpu_irq_init(unsigned int irq_base); |
311 | 360 | ||
312 | void __init arch_init_irq(void) | 361 | void __init arch_init_irq(void) |
@@ -369,8 +418,6 @@ void __init arch_init_irq(void) | |||
369 | sgint->cmeimask0 = 0; | 418 | sgint->cmeimask0 = 0; |
370 | sgint->cmeimask1 = 0; | 419 | sgint->cmeimask1 = 0; |
371 | 420 | ||
372 | set_except_vector(0, indyIRQ); | ||
373 | |||
374 | /* init CPU irqs */ | 421 | /* init CPU irqs */ |
375 | mips_cpu_irq_init(SGINT_CPU); | 422 | mips_cpu_irq_init(SGINT_CPU); |
376 | 423 | ||
diff --git a/arch/mips/sgi-ip22/ip22-irq.S b/arch/mips/sgi-ip22/ip22-irq.S deleted file mode 100644 index 6ccbd9e1d967..000000000000 --- a/arch/mips/sgi-ip22/ip22-irq.S +++ /dev/null | |||
@@ -1,118 +0,0 @@ | |||
1 | /* | ||
2 | * ip22-irq.S: Interrupt exception dispatch code for FullHouse and | ||
3 | * Guiness. | ||
4 | * | ||
5 | * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) | ||
6 | */ | ||
7 | |||
8 | #include <asm/asm.h> | ||
9 | #include <asm/mipsregs.h> | ||
10 | #include <asm/regdef.h> | ||
11 | #include <asm/stackframe.h> | ||
12 | |||
13 | /* A lot of complication here is taken away because: | ||
14 | * | ||
15 | * 1) We handle one interrupt and return, sitting in a loop and moving across | ||
16 | * all the pending IRQ bits in the cause register is _NOT_ the answer, the | ||
17 | * common case is one pending IRQ so optimize in that direction. | ||
18 | * | ||
19 | * 2) We need not check against bits in the status register IRQ mask, that | ||
20 | * would make this routine slow as hell. | ||
21 | * | ||
22 | * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in | ||
23 | * between like BSD spl() brain-damage. | ||
24 | * | ||
25 | * Furthermore, the IRQs on the INDY look basically (barring software IRQs | ||
26 | * which we don't use at all) like: | ||
27 | * | ||
28 | * MIPS IRQ Source | ||
29 | * -------- ------ | ||
30 | * 0 Software (ignored) | ||
31 | * 1 Software (ignored) | ||
32 | * 2 Local IRQ level zero | ||
33 | * 3 Local IRQ level one | ||
34 | * 4 8254 Timer zero | ||
35 | * 5 8254 Timer one | ||
36 | * 6 Bus Error | ||
37 | * 7 R4k timer (what we use) | ||
38 | * | ||
39 | * We handle the IRQ according to _our_ priority which is: | ||
40 | * | ||
41 | * Highest ---- R4k Timer | ||
42 | * Local IRQ zero | ||
43 | * Local IRQ one | ||
44 | * Bus Error | ||
45 | * 8254 Timer zero | ||
46 | * Lowest ---- 8254 Timer one | ||
47 | * | ||
48 | * then we just return, if multiple IRQs are pending then we will just take | ||
49 | * another exception, big deal. | ||
50 | */ | ||
51 | |||
52 | .text | ||
53 | .set noreorder | ||
54 | .set noat | ||
55 | .align 5 | ||
56 | NESTED(indyIRQ, PT_SIZE, sp) | ||
57 | SAVE_ALL | ||
58 | CLI | ||
59 | .set at | ||
60 | mfc0 s0, CP0_CAUSE # get irq mask | ||
61 | |||
62 | /* First we check for r4k counter/timer IRQ. */ | ||
63 | andi a0, s0, CAUSEF_IP7 | ||
64 | beq a0, zero, 1f | ||
65 | andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero | ||
66 | |||
67 | /* Wheee, a timer interrupt. */ | ||
68 | jal indy_r4k_timer_interrupt | ||
69 | move a0, sp # delay slot | ||
70 | j ret_from_irq | ||
71 | nop # delay slot | ||
72 | |||
73 | 1: | ||
74 | beq a0, zero, 1f | ||
75 | andi a0, s0, CAUSEF_IP3 # delay slot, check local level one | ||
76 | |||
77 | /* Wheee, local level zero interrupt. */ | ||
78 | jal indy_local0_irqdispatch | ||
79 | move a0, sp # delay slot | ||
80 | |||
81 | j ret_from_irq | ||
82 | nop # delay slot | ||
83 | |||
84 | 1: | ||
85 | beq a0, zero, 1f | ||
86 | andi a0, s0, CAUSEF_IP6 # delay slot, check bus error | ||
87 | |||
88 | /* Wheee, local level one interrupt. */ | ||
89 | jal indy_local1_irqdispatch | ||
90 | move a0, sp # delay slot | ||
91 | j ret_from_irq | ||
92 | nop # delay slot | ||
93 | |||
94 | 1: | ||
95 | beq a0, zero, 1f | ||
96 | andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) # delay slot | ||
97 | |||
98 | /* Wheee, an asynchronous bus error... */ | ||
99 | jal indy_buserror_irq | ||
100 | move a0, sp # delay slot | ||
101 | j ret_from_irq | ||
102 | nop # delay slot | ||
103 | |||
104 | 1: | ||
105 | /* Here by mistake? It is possible, that by the time we take | ||
106 | * the exception the IRQ pin goes low, so just leave if this | ||
107 | * is the case. | ||
108 | */ | ||
109 | beq a0, zero, 1f | ||
110 | nop # delay slot | ||
111 | |||
112 | /* Must be one of the 8254 timers... */ | ||
113 | jal indy_8254timer_irq | ||
114 | move a0, sp # delay slot | ||
115 | 1: | ||
116 | j ret_from_irq | ||
117 | nop # delay slot | ||
118 | END(indyIRQ) | ||
diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile index 4ba340780c35..686ba14e2882 100644 --- a/arch/mips/sgi-ip27/Makefile +++ b/arch/mips/sgi-ip27/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the IP27 specific kernel interface routines under Linux. | 2 | # Makefile for the IP27 specific kernel interface routines under Linux. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \ | 5 | obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o \ |
6 | ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \ | 6 | ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \ |
7 | ip27-timer.o ip27-hubio.o ip27-xtalk.o | 7 | ip27-timer.o ip27-hubio.o ip27-xtalk.o |
8 | 8 | ||
diff --git a/arch/mips/sgi-ip27/TODO b/arch/mips/sgi-ip27/TODO index 32106131b0d0..19f1512c8f2e 100644 --- a/arch/mips/sgi-ip27/TODO +++ b/arch/mips/sgi-ip27/TODO | |||
@@ -9,10 +9,6 @@ ip27-init.c:find_lbaord_real. DONE | |||
9 | in irix? | 9 | in irix? |
10 | 6. Investigate why things do not work without the setup_test() call | 10 | 6. Investigate why things do not work without the setup_test() call |
11 | being invoked on all nodes in ip27-memory.c. | 11 | being invoked on all nodes in ip27-memory.c. |
12 | 7. Too many CLIs in the locore handlers : | ||
13 | For the low level handlers set up by set_except_vector(), | ||
14 | __tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror, | ||
15 | investigate whether the code should do CLI, STI or KMODE. | ||
16 | 8. Too many do_page_faults invoked - investigate. | 12 | 8. Too many do_page_faults invoked - investigate. |
17 | 9. start_thread must turn off UX64 ... and define tlb_refill_debug. | 13 | 9. start_thread must turn off UX64 ... and define tlb_refill_debug. |
18 | 10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable | 14 | 10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable |
diff --git a/arch/mips/sgi-ip27/ip27-irq-glue.S b/arch/mips/sgi-ip27/ip27-irq-glue.S deleted file mode 100644 index c304df715e0a..000000000000 --- a/arch/mips/sgi-ip27/ip27-irq-glue.S +++ /dev/null | |||
@@ -1,45 +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) 1999 Ralf Baechle | ||
7 | * Copyright (C) 1999 Silicon Graphics, Inc. | ||
8 | */ | ||
9 | #include <asm/asm.h> | ||
10 | #include <asm/mipsregs.h> | ||
11 | #include <asm/regdef.h> | ||
12 | #include <asm/stackframe.h> | ||
13 | |||
14 | .text | ||
15 | .align 5 | ||
16 | NESTED(ip27_irq, PT_SIZE, sp) | ||
17 | SAVE_ALL | ||
18 | CLI | ||
19 | |||
20 | mfc0 s0, CP0_CAUSE | ||
21 | mfc0 t0, CP0_STATUS | ||
22 | and s0, t0 | ||
23 | move a0, sp | ||
24 | PTR_LA ra, ret_from_irq | ||
25 | |||
26 | /* First check for RT interrupt. */ | ||
27 | andi t0, s0, CAUSEF_IP4 | ||
28 | bnez t0, ip4 | ||
29 | andi t0, s0, CAUSEF_IP2 | ||
30 | bnez t0, ip2 | ||
31 | andi t0, s0, CAUSEF_IP3 | ||
32 | bnez t0, ip3 | ||
33 | andi t0, s0, CAUSEF_IP5 | ||
34 | bnez t0, ip5 | ||
35 | andi t0, s0, CAUSEF_IP6 | ||
36 | bnez t0, ip6 | ||
37 | j ra | ||
38 | |||
39 | ip2: j ip27_do_irq_mask0 # PI_INT_PEND_0 or CC_PEND_{A|B} | ||
40 | ip3: j ip27_do_irq_mask1 # PI_INT_PEND_1 | ||
41 | ip4: j ip27_rt_timer_interrupt | ||
42 | ip5: j ip27_prof_timer | ||
43 | ip6: j ip27_hub_error | ||
44 | |||
45 | END(ip27_irq) | ||
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 2854ac4c9be1..2e643d2f51cb 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c | |||
@@ -130,7 +130,7 @@ static int ms1bit(unsigned long x) | |||
130 | * Kanoj 05.13.00 | 130 | * Kanoj 05.13.00 |
131 | */ | 131 | */ |
132 | 132 | ||
133 | void ip27_do_irq_mask0(struct pt_regs *regs) | 133 | static void ip27_do_irq_mask0(struct pt_regs *regs) |
134 | { | 134 | { |
135 | int irq, swlevel; | 135 | int irq, swlevel; |
136 | hubreg_t pend0, mask0; | 136 | hubreg_t pend0, mask0; |
@@ -171,7 +171,7 @@ void ip27_do_irq_mask0(struct pt_regs *regs) | |||
171 | LOCAL_HUB_L(PI_INT_PEND0); | 171 | LOCAL_HUB_L(PI_INT_PEND0); |
172 | } | 172 | } |
173 | 173 | ||
174 | void ip27_do_irq_mask1(struct pt_regs *regs) | 174 | static void ip27_do_irq_mask1(struct pt_regs *regs) |
175 | { | 175 | { |
176 | int irq, swlevel; | 176 | int irq, swlevel; |
177 | hubreg_t pend1, mask1; | 177 | hubreg_t pend1, mask1; |
@@ -196,12 +196,12 @@ void ip27_do_irq_mask1(struct pt_regs *regs) | |||
196 | LOCAL_HUB_L(PI_INT_PEND1); | 196 | LOCAL_HUB_L(PI_INT_PEND1); |
197 | } | 197 | } |
198 | 198 | ||
199 | void ip27_prof_timer(struct pt_regs *regs) | 199 | static void ip27_prof_timer(struct pt_regs *regs) |
200 | { | 200 | { |
201 | panic("CPU %d got a profiling interrupt", smp_processor_id()); | 201 | panic("CPU %d got a profiling interrupt", smp_processor_id()); |
202 | } | 202 | } |
203 | 203 | ||
204 | void ip27_hub_error(struct pt_regs *regs) | 204 | static void ip27_hub_error(struct pt_regs *regs) |
205 | { | 205 | { |
206 | panic("CPU %d got a hub error interrupt", smp_processor_id()); | 206 | panic("CPU %d got a hub error interrupt", smp_processor_id()); |
207 | } | 207 | } |
@@ -421,9 +421,26 @@ int __devinit request_bridge_irq(struct bridge_controller *bc) | |||
421 | return irq; | 421 | return irq; |
422 | } | 422 | } |
423 | 423 | ||
424 | extern void ip27_rt_timer_interrupt(struct pt_regs *regs); | ||
425 | |||
426 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
427 | { | ||
428 | unsigned long pending = read_c0_cause() & read_c0_status(); | ||
429 | |||
430 | if (pending & CAUSEF_IP4) | ||
431 | ip27_rt_timer_interrupt(regs); | ||
432 | else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */ | ||
433 | ip27_do_irq_mask0(regs); | ||
434 | else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */ | ||
435 | ip27_do_irq_mask1(regs); | ||
436 | else if (pending & CAUSEF_IP5) | ||
437 | ip27_prof_timer(regs); | ||
438 | else if (pending & CAUSEF_IP6) | ||
439 | ip27_hub_error(regs); | ||
440 | } | ||
441 | |||
424 | void __init arch_init_irq(void) | 442 | void __init arch_init_irq(void) |
425 | { | 443 | { |
426 | set_except_vector(0, ip27_irq); | ||
427 | } | 444 | } |
428 | 445 | ||
429 | void install_ipi(void) | 446 | void install_ipi(void) |
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile index 470898f4afe1..530bf848c3d0 100644 --- a/arch/mips/sgi-ip32/Makefile +++ b/arch/mips/sgi-ip32/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \ | 6 | obj-y += ip32-berr.o ip32-irq.o ip32-setup.o ip32-reset.o \ |
7 | crime.o ip32-memory.o | 7 | crime.o ip32-memory.o |
8 | 8 | ||
9 | EXTRA_AFLAGS := $(CFLAGS) | 9 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/sgi-ip32/ip32-irq-glue.S b/arch/mips/sgi-ip32/ip32-irq-glue.S deleted file mode 100644 index 200924e1c4f5..000000000000 --- a/arch/mips/sgi-ip32/ip32-irq-glue.S +++ /dev/null | |||
@@ -1,86 +0,0 @@ | |||
1 | /* | ||
2 | * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2000 Harald Koerfgen | ||
9 | * Copyright (C) 2001 Keith M Wesolowski | ||
10 | */ | ||
11 | #include <asm/asm.h> | ||
12 | #include <asm/regdef.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/stackframe.h> | ||
15 | #include <asm/addrspace.h> | ||
16 | |||
17 | .text | ||
18 | .set noreorder | ||
19 | .set noat | ||
20 | .align 5 | ||
21 | NESTED(ip32_handle_int, PT_SIZE, ra) | ||
22 | .set noat | ||
23 | SAVE_ALL | ||
24 | CLI # TEST: interrupts should be off | ||
25 | .set at | ||
26 | .set noreorder | ||
27 | |||
28 | mfc0 s0,CP0_CAUSE | ||
29 | |||
30 | andi t1, s0, IE_IRQ0 | ||
31 | bnez t1, handle_irq0 | ||
32 | andi t1, s0, IE_IRQ1 | ||
33 | bnez t1, handle_irq1 | ||
34 | andi t1, s0, IE_IRQ2 | ||
35 | bnez t1, handle_irq2 | ||
36 | andi t1, s0, IE_IRQ3 | ||
37 | bnez t1, handle_irq3 | ||
38 | andi t1, s0, IE_IRQ4 | ||
39 | bnez t1, handle_irq4 | ||
40 | andi t1, s0, IE_IRQ5 | ||
41 | bnez t1, handle_irq5 | ||
42 | nop | ||
43 | |||
44 | /* Either someone has triggered the "software interrupts" | ||
45 | * or we lost an interrupt somehow. Ignore it. | ||
46 | */ | ||
47 | j ret_from_irq | ||
48 | nop | ||
49 | |||
50 | handle_irq0: | ||
51 | jal ip32_irq0 | ||
52 | move a0, sp | ||
53 | j ret_from_irq | ||
54 | nop | ||
55 | |||
56 | handle_irq1: | ||
57 | jal ip32_irq1 | ||
58 | move a0, sp | ||
59 | j ret_from_irq | ||
60 | nop | ||
61 | |||
62 | handle_irq2: | ||
63 | jal ip32_irq2 | ||
64 | move a0, sp | ||
65 | j ret_from_irq | ||
66 | nop | ||
67 | |||
68 | handle_irq3: | ||
69 | jal ip32_irq3 | ||
70 | move a0, sp | ||
71 | j ret_from_irq | ||
72 | nop | ||
73 | |||
74 | handle_irq4: | ||
75 | jal ip32_irq4 | ||
76 | move a0, sp | ||
77 | j ret_from_irq | ||
78 | nop | ||
79 | |||
80 | handle_irq5: | ||
81 | jal ip32_irq5 | ||
82 | move a0, sp | ||
83 | j ret_from_irq | ||
84 | nop | ||
85 | |||
86 | END(ip32_handle_int) | ||
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 2eb22d692ed9..22a6df94b4a1 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c | |||
@@ -130,8 +130,6 @@ struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, | |||
130 | struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, | 130 | struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, |
131 | CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; | 131 | CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; |
132 | 132 | ||
133 | extern void ip32_handle_int(void); | ||
134 | |||
135 | /* | 133 | /* |
136 | * For interrupts wired from a single device to the CPU. Only the clock | 134 | * For interrupts wired from a single device to the CPU. Only the clock |
137 | * uses this it seems, which is IRQ 0 and IP7. | 135 | * uses this it seems, which is IRQ 0 and IP7. |
@@ -503,7 +501,7 @@ static void ip32_unknown_interrupt(struct pt_regs *regs) | |||
503 | 501 | ||
504 | /* CRIME 1.1 appears to deliver all interrupts to this one pin. */ | 502 | /* CRIME 1.1 appears to deliver all interrupts to this one pin. */ |
505 | /* change this to loop over all edge-triggered irqs, exception masked out ones */ | 503 | /* change this to loop over all edge-triggered irqs, exception masked out ones */ |
506 | void ip32_irq0(struct pt_regs *regs) | 504 | static void ip32_irq0(struct pt_regs *regs) |
507 | { | 505 | { |
508 | uint64_t crime_int; | 506 | uint64_t crime_int; |
509 | int irq = 0; | 507 | int irq = 0; |
@@ -520,31 +518,49 @@ void ip32_irq0(struct pt_regs *regs) | |||
520 | do_IRQ(irq, regs); | 518 | do_IRQ(irq, regs); |
521 | } | 519 | } |
522 | 520 | ||
523 | void ip32_irq1(struct pt_regs *regs) | 521 | static void ip32_irq1(struct pt_regs *regs) |
524 | { | 522 | { |
525 | ip32_unknown_interrupt(regs); | 523 | ip32_unknown_interrupt(regs); |
526 | } | 524 | } |
527 | 525 | ||
528 | void ip32_irq2(struct pt_regs *regs) | 526 | static void ip32_irq2(struct pt_regs *regs) |
529 | { | 527 | { |
530 | ip32_unknown_interrupt(regs); | 528 | ip32_unknown_interrupt(regs); |
531 | } | 529 | } |
532 | 530 | ||
533 | void ip32_irq3(struct pt_regs *regs) | 531 | static void ip32_irq3(struct pt_regs *regs) |
534 | { | 532 | { |
535 | ip32_unknown_interrupt(regs); | 533 | ip32_unknown_interrupt(regs); |
536 | } | 534 | } |
537 | 535 | ||
538 | void ip32_irq4(struct pt_regs *regs) | 536 | static void ip32_irq4(struct pt_regs *regs) |
539 | { | 537 | { |
540 | ip32_unknown_interrupt(regs); | 538 | ip32_unknown_interrupt(regs); |
541 | } | 539 | } |
542 | 540 | ||
543 | void ip32_irq5(struct pt_regs *regs) | 541 | static void ip32_irq5(struct pt_regs *regs) |
544 | { | 542 | { |
545 | ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs); | 543 | ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs); |
546 | } | 544 | } |
547 | 545 | ||
546 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
547 | { | ||
548 | unsigned int pending = read_c0_cause(); | ||
549 | |||
550 | if (likely(pending & IE_IRQ0)) | ||
551 | ip32_irq0(regs); | ||
552 | else if (unlikely(pending & IE_IRQ1)) | ||
553 | ip32_irq1(regs); | ||
554 | else if (unlikely(pending & IE_IRQ2)) | ||
555 | ip32_irq2(regs); | ||
556 | else if (unlikely(pending & IE_IRQ3)) | ||
557 | ip32_irq3(regs); | ||
558 | else if (unlikely(pending & IE_IRQ4)) | ||
559 | ip32_irq4(regs); | ||
560 | else if (likely(pending & IE_IRQ5)) | ||
561 | ip32_irq5(regs); | ||
562 | } | ||
563 | |||
548 | void __init arch_init_irq(void) | 564 | void __init arch_init_irq(void) |
549 | { | 565 | { |
550 | unsigned int irq; | 566 | unsigned int irq; |
@@ -556,7 +572,6 @@ void __init arch_init_irq(void) | |||
556 | crime->soft_int = 0; | 572 | crime->soft_int = 0; |
557 | mace->perif.ctrl.istat = 0; | 573 | mace->perif.ctrl.istat = 0; |
558 | mace->perif.ctrl.imask = 0; | 574 | mace->perif.ctrl.imask = 0; |
559 | set_except_vector(0, ip32_handle_int); | ||
560 | 575 | ||
561 | for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { | 576 | for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { |
562 | hw_irq_controller *controller; | 577 | hw_irq_controller *controller; |
diff --git a/arch/mips/sibyte/bcm1480/Makefile b/arch/mips/sibyte/bcm1480/Makefile index 538d5a51ae94..7b36ff3873b7 100644 --- a/arch/mips/sibyte/bcm1480/Makefile +++ b/arch/mips/sibyte/bcm1480/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y := setup.o irq.o irq_handler.o time.o | 1 | obj-y := setup.o irq.o time.o |
2 | 2 | ||
3 | obj-$(CONFIG_SMP) += smp.o | 3 | obj-$(CONFIG_SMP) += smp.o |
4 | 4 | ||
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 9cf7d713b13c..e61760b14d99 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c | |||
@@ -187,9 +187,6 @@ static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask) | |||
187 | #endif | 187 | #endif |
188 | 188 | ||
189 | 189 | ||
190 | /* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */ | ||
191 | extern void bcm1480_irq_handler(void); | ||
192 | |||
193 | /*****************************************************************************/ | 190 | /*****************************************************************************/ |
194 | 191 | ||
195 | static unsigned int startup_bcm1480_irq(unsigned int irq) | 192 | static unsigned int startup_bcm1480_irq(unsigned int irq) |
@@ -422,7 +419,6 @@ void __init arch_init_irq(void) | |||
422 | #endif | 419 | #endif |
423 | /* Enable necessary IPs, disable the rest */ | 420 | /* Enable necessary IPs, disable the rest */ |
424 | change_c0_status(ST0_IM, imask); | 421 | change_c0_status(ST0_IM, imask); |
425 | set_except_vector(0, bcm1480_irq_handler); | ||
426 | 422 | ||
427 | #ifdef CONFIG_KGDB | 423 | #ifdef CONFIG_KGDB |
428 | if (kgdb_flag) { | 424 | if (kgdb_flag) { |
@@ -473,3 +469,76 @@ void bcm1480_kgdb_interrupt(struct pt_regs *regs) | |||
473 | } | 469 | } |
474 | 470 | ||
475 | #endif /* CONFIG_KGDB */ | 471 | #endif /* CONFIG_KGDB */ |
472 | |||
473 | static inline int dclz(unsigned long long x) | ||
474 | { | ||
475 | int lz; | ||
476 | |||
477 | __asm__ ( | ||
478 | " .set push \n" | ||
479 | " .set mips64 \n" | ||
480 | " dclz %0, %1 \n" | ||
481 | " .set pop \n" | ||
482 | : "=r" (lz) | ||
483 | : "r" (x)); | ||
484 | |||
485 | return lz; | ||
486 | } | ||
487 | |||
488 | extern void bcm1480_timer_interrupt(struct pt_regs *regs); | ||
489 | extern void bcm1480_mailbox_interrupt(struct pt_regs *regs); | ||
490 | extern void bcm1480_kgdb_interrupt(struct pt_regs *regs); | ||
491 | |||
492 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
493 | { | ||
494 | unsigned int pending; | ||
495 | |||
496 | #ifdef CONFIG_SIBYTE_BCM1480_PROF | ||
497 | /* Set compare to count to silence count/compare timer interrupts */ | ||
498 | write_c0_compare(read_c0_count()); | ||
499 | #endif | ||
500 | |||
501 | pending = read_c0_cause(); | ||
502 | |||
503 | #ifdef CONFIG_SIBYTE_BCM1480_PROF | ||
504 | if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */ | ||
505 | sbprof_cpu_intr(exception_epc(regs)); | ||
506 | #endif | ||
507 | |||
508 | if (pending & CAUSEF_IP4) | ||
509 | bcm1480_timer_interrupt(regs); | ||
510 | |||
511 | #ifdef CONFIG_SMP | ||
512 | if (pending & CAUSEF_IP3) | ||
513 | bcm1480_mailbox_interrupt(regs); | ||
514 | #endif | ||
515 | |||
516 | #ifdef CONFIG_KGDB | ||
517 | if (pending & CAUSEF_IP6) | ||
518 | bcm1480_kgdb_interrupt(regs); /* KGDB (uart 1) */ | ||
519 | #endif | ||
520 | |||
521 | if (pending & CAUSEF_IP2) { | ||
522 | unsigned long long mask_h, mask_l; | ||
523 | unsigned long base; | ||
524 | |||
525 | /* | ||
526 | * Default...we've hit an IP[2] interrupt, which means we've | ||
527 | * got to check the 1480 interrupt registers to figure out what | ||
528 | * to do. Need to detect which CPU we're on, now that | ||
529 | * smp_affinity is supported. | ||
530 | */ | ||
531 | base = A_BCM1480_IMR_MAPPER(smp_processor_id()); | ||
532 | mask_h = __raw_readq( | ||
533 | IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H)); | ||
534 | mask_l = __raw_readq( | ||
535 | IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L)); | ||
536 | |||
537 | if (!mask_h) { | ||
538 | if (mask_h ^ 1) | ||
539 | do_IRQ(63 - dclz(mask_h), regs); | ||
540 | else | ||
541 | do_IRQ(127 - dclz(mask_l), regs); | ||
542 | } | ||
543 | } | ||
544 | } | ||
diff --git a/arch/mips/sibyte/bcm1480/irq_handler.S b/arch/mips/sibyte/bcm1480/irq_handler.S deleted file mode 100644 index 408db88d050f..000000000000 --- a/arch/mips/sibyte/bcm1480/irq_handler.S +++ /dev/null | |||
@@ -1,165 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * bcm1480_irq_handler() is the routine that is actually called when an | ||
21 | * interrupt occurs. It is installed as the exception vector handler in | ||
22 | * init_IRQ() in arch/mips/sibyte/bcm1480/irq.c | ||
23 | * | ||
24 | * In the handle we figure out which interrupts need handling, and use that | ||
25 | * to call the dispatcher, which will take care of actually calling | ||
26 | * registered handlers | ||
27 | * | ||
28 | * Note that we take care of all raised interrupts in one go at the handler. | ||
29 | * This is more BSDish than the Indy code, and also, IMHO, more sane. | ||
30 | */ | ||
31 | #include <linux/config.h> | ||
32 | |||
33 | #include <asm/addrspace.h> | ||
34 | #include <asm/asm.h> | ||
35 | #include <asm/mipsregs.h> | ||
36 | #include <asm/regdef.h> | ||
37 | #include <asm/stackframe.h> | ||
38 | #include <asm/sibyte/sb1250_defs.h> | ||
39 | #include <asm/sibyte/bcm1480_regs.h> | ||
40 | #include <asm/sibyte/bcm1480_int.h> | ||
41 | |||
42 | /* | ||
43 | * What a pain. We have to be really careful saving the upper 32 bits of any | ||
44 | * register across function calls if we don't want them trashed--since were | ||
45 | * running in -o32, the calling routing never saves the full 64 bits of a | ||
46 | * register across a function call. Being the interrupt handler, we're | ||
47 | * guaranteed that interrupts are disabled during this code so we don't have | ||
48 | * to worry about random interrupts blasting the high 32 bits. | ||
49 | */ | ||
50 | |||
51 | .text | ||
52 | .set push | ||
53 | .set noreorder | ||
54 | .set noat | ||
55 | .set mips64 | ||
56 | #.set mips4 | ||
57 | .align 5 | ||
58 | NESTED(bcm1480_irq_handler, PT_SIZE, sp) | ||
59 | SAVE_ALL | ||
60 | CLI | ||
61 | |||
62 | #ifdef CONFIG_SIBYTE_BCM1480_PROF | ||
63 | /* Set compare to count to silence count/compare timer interrupts */ | ||
64 | mfc0 t1, CP0_COUNT | ||
65 | mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */ | ||
66 | #endif | ||
67 | /* Read cause */ | ||
68 | mfc0 s0, CP0_CAUSE | ||
69 | |||
70 | #ifdef CONFIG_SIBYTE_BCM1480_PROF | ||
71 | /* Cpu performance counter interrupt is routed to IP[7] */ | ||
72 | andi t1, s0, CAUSEF_IP7 | ||
73 | beqz t1, 0f | ||
74 | srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */ | ||
75 | and t1, t1, 0x4 /* mask to get just BD bit */ | ||
76 | #ifdef CONFIG_MIPS64 | ||
77 | dmfc0 a0, CP0_EPC | ||
78 | daddu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ | ||
79 | #else | ||
80 | mfc0 a0, CP0_EPC | ||
81 | addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ | ||
82 | #endif | ||
83 | jal sbprof_cpu_intr | ||
84 | nop | ||
85 | j ret_from_irq | ||
86 | nop | ||
87 | 0: | ||
88 | #endif | ||
89 | |||
90 | /* Timer interrupt is routed to IP[4] */ | ||
91 | andi t1, s0, CAUSEF_IP4 | ||
92 | beqz t1, 1f | ||
93 | nop | ||
94 | jal bcm1480_timer_interrupt | ||
95 | move a0, sp /* Pass the registers along */ | ||
96 | j ret_from_irq | ||
97 | nop /* delay slot */ | ||
98 | 1: | ||
99 | |||
100 | #ifdef CONFIG_SMP | ||
101 | /* Mailbox interrupt is routed to IP[3] */ | ||
102 | andi t1, s0, CAUSEF_IP3 | ||
103 | beqz t1, 2f | ||
104 | nop | ||
105 | jal bcm1480_mailbox_interrupt | ||
106 | move a0, sp | ||
107 | j ret_from_irq | ||
108 | nop /* delay slot */ | ||
109 | 2: | ||
110 | #endif | ||
111 | |||
112 | #ifdef CONFIG_KGDB | ||
113 | /* KGDB (uart 1) interrupt is routed to IP[6] */ | ||
114 | andi t1, s0, CAUSEF_IP6 | ||
115 | beqz t1, 3f | ||
116 | nop /* delay slot */ | ||
117 | jal bcm1480_kgdb_interrupt | ||
118 | move a0, sp | ||
119 | j ret_from_irq | ||
120 | nop /* delay slot */ | ||
121 | 3: | ||
122 | #endif | ||
123 | |||
124 | and t1, s0, CAUSEF_IP2 | ||
125 | beqz t1, 9f | ||
126 | nop | ||
127 | |||
128 | /* | ||
129 | * Default...we've hit an IP[2] interrupt, which means we've got | ||
130 | * to check the 1480 interrupt registers to figure out what to do | ||
131 | * Need to detect which CPU we're on, now that smp_affinity is | ||
132 | * supported. | ||
133 | */ | ||
134 | PTR_LA v0, CKSEG1 + A_BCM1480_IMR_CPU0_BASE | ||
135 | #ifdef CONFIG_SMP | ||
136 | lw t1, TI_CPU($28) | ||
137 | sll t1, t1, BCM1480_IMR_REGISTER_SPACING_SHIFT | ||
138 | addu v0, v0, t1 | ||
139 | #endif | ||
140 | |||
141 | /* Read IP[2] status (get both high and low halves of status) */ | ||
142 | ld s0, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H(v0) | ||
143 | ld s1, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L(v0) | ||
144 | |||
145 | move s2, zero /* intr number */ | ||
146 | li s3, 64 | ||
147 | |||
148 | beqz s0, 9f /* No interrupts. Return. */ | ||
149 | move a1, sp | ||
150 | |||
151 | xori s4, s0, 1 /* if s0 (_H) == 1, it's a low intr, so... */ | ||
152 | movz s2, s3, s4 /* start the intr number at 64, and */ | ||
153 | movz s0, s1, s4 /* look at the low status value. */ | ||
154 | |||
155 | dclz s1, s0 /* Find the next interrupt. */ | ||
156 | dsubu a0, zero, s1 | ||
157 | daddiu a0, a0, 63 | ||
158 | jal do_IRQ | ||
159 | daddu a0, a0, s2 | ||
160 | |||
161 | 9: j ret_from_irq | ||
162 | nop | ||
163 | |||
164 | .set pop | ||
165 | END(bcm1480_irq_handler) | ||
diff --git a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile index a8af84697588..a2fdbd62f8ac 100644 --- a/arch/mips/sibyte/sb1250/Makefile +++ b/arch/mips/sibyte/sb1250/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y := setup.o irq.o irq_handler.o time.o | 1 | obj-y := setup.o irq.o time.o |
2 | 2 | ||
3 | obj-$(CONFIG_SMP) += smp.o | 3 | obj-$(CONFIG_SMP) += smp.o |
4 | obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o | 4 | obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o |
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index 589537bfcc3d..0f6e54db4888 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c | |||
@@ -163,10 +163,6 @@ static void sb1250_set_affinity(unsigned int irq, cpumask_t mask) | |||
163 | } | 163 | } |
164 | #endif | 164 | #endif |
165 | 165 | ||
166 | |||
167 | /* Defined in arch/mips/sibyte/sb1250/irq_handler.S */ | ||
168 | extern void sb1250_irq_handler(void); | ||
169 | |||
170 | /*****************************************************************************/ | 166 | /*****************************************************************************/ |
171 | 167 | ||
172 | static unsigned int startup_sb1250_irq(unsigned int irq) | 168 | static unsigned int startup_sb1250_irq(unsigned int irq) |
@@ -379,7 +375,6 @@ void __init arch_init_irq(void) | |||
379 | #endif | 375 | #endif |
380 | /* Enable necessary IPs, disable the rest */ | 376 | /* Enable necessary IPs, disable the rest */ |
381 | change_c0_status(ST0_IM, imask); | 377 | change_c0_status(ST0_IM, imask); |
382 | set_except_vector(0, sb1250_irq_handler); | ||
383 | 378 | ||
384 | #ifdef CONFIG_KGDB | 379 | #ifdef CONFIG_KGDB |
385 | if (kgdb_flag) { | 380 | if (kgdb_flag) { |
@@ -409,7 +404,7 @@ void __init arch_init_irq(void) | |||
409 | #define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) | 404 | #define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) |
410 | #define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) | 405 | #define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) |
411 | 406 | ||
412 | void sb1250_kgdb_interrupt(struct pt_regs *regs) | 407 | static void sb1250_kgdb_interrupt(struct pt_regs *regs) |
413 | { | 408 | { |
414 | /* | 409 | /* |
415 | * Clear break-change status (allow some time for the remote | 410 | * Clear break-change status (allow some time for the remote |
@@ -424,3 +419,74 @@ void sb1250_kgdb_interrupt(struct pt_regs *regs) | |||
424 | } | 419 | } |
425 | 420 | ||
426 | #endif /* CONFIG_KGDB */ | 421 | #endif /* CONFIG_KGDB */ |
422 | |||
423 | static inline int dclz(unsigned long long x) | ||
424 | { | ||
425 | int lz; | ||
426 | |||
427 | __asm__ ( | ||
428 | " .set push \n" | ||
429 | " .set mips64 \n" | ||
430 | " dclz %0, %1 \n" | ||
431 | " .set pop \n" | ||
432 | : "=r" (lz) | ||
433 | : "r" (x)); | ||
434 | |||
435 | return lz; | ||
436 | } | ||
437 | |||
438 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
439 | { | ||
440 | unsigned int pending; | ||
441 | |||
442 | #ifdef CONFIG_SIBYTE_SB1250_PROF | ||
443 | /* Set compare to count to silence count/compare timer interrupts */ | ||
444 | write_c0_count(read_c0_count()); | ||
445 | #endif | ||
446 | |||
447 | /* | ||
448 | * What a pain. We have to be really careful saving the upper 32 bits | ||
449 | * of any * register across function calls if we don't want them | ||
450 | * trashed--since were running in -o32, the calling routing never saves | ||
451 | * the full 64 bits of a register across a function call. Being the | ||
452 | * interrupt handler, we're guaranteed that interrupts are disabled | ||
453 | * during this code so we don't have to worry about random interrupts | ||
454 | * blasting the high 32 bits. | ||
455 | */ | ||
456 | |||
457 | pending = read_c0_cause(); | ||
458 | |||
459 | #ifdef CONFIG_SIBYTE_SB1250_PROF | ||
460 | if (pending & CAUSEF_IP7) { /* Cpu performance counter interrupt */ | ||
461 | sbprof_cpu_intr(exception_epc(regs)); | ||
462 | } | ||
463 | #endif | ||
464 | |||
465 | if (pending & CAUSEF_IP4) | ||
466 | sb1250_timer_interrupt(regs); | ||
467 | |||
468 | #ifdef CONFIG_SMP | ||
469 | if (pending & CAUSEF_IP3) | ||
470 | sb1250_mailbox_interrupt(regs); | ||
471 | #endif | ||
472 | |||
473 | #ifdef CONFIG_KGDB | ||
474 | if (pending & CAUSEF_IP6) /* KGDB (uart 1) */ | ||
475 | sb1250_kgdb_interrupt(regs); | ||
476 | #endif | ||
477 | |||
478 | if (pending & CAUSEF_IP2) { | ||
479 | unsigned long long mask; | ||
480 | |||
481 | /* | ||
482 | * Default...we've hit an IP[2] interrupt, which means we've | ||
483 | * got to check the 1250 interrupt registers to figure out what | ||
484 | * to do. Need to detect which CPU we're on, now that | ||
485 | ~ smp_affinity is supported. | ||
486 | */ | ||
487 | mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(), | ||
488 | R_IMR_INTERRUPT_STATUS_BASE))); | ||
489 | if (mask) | ||
490 | do_IRQ(63 - dclz(mask), regs); | ||
491 | } | ||
492 | } | ||
diff --git a/arch/mips/sibyte/sb1250/irq_handler.S b/arch/mips/sibyte/sb1250/irq_handler.S deleted file mode 100644 index 60edc8fb302b..000000000000 --- a/arch/mips/sibyte/sb1250/irq_handler.S +++ /dev/null | |||
@@ -1,147 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * sb1250_handle_int() is the routine that is actually called when an interrupt | ||
21 | * occurs. It is installed as the exception vector handler in arch_init_irq() | ||
22 | * in arch/mips/sibyte/sb1250/irq.c | ||
23 | * | ||
24 | * In the handle we figure out which interrupts need handling, and use that to | ||
25 | * call the dispatcher, which will take care of actually calling registered | ||
26 | * handlers | ||
27 | * | ||
28 | * Note that we take care of all raised interrupts in one go at the handler. | ||
29 | * This is more BSDish than the Indy code, and also, IMHO, more sane. | ||
30 | */ | ||
31 | #include <linux/config.h> | ||
32 | |||
33 | #include <asm/addrspace.h> | ||
34 | #include <asm/asm.h> | ||
35 | #include <asm/mipsregs.h> | ||
36 | #include <asm/regdef.h> | ||
37 | #include <asm/stackframe.h> | ||
38 | #include <asm/sibyte/sb1250_defs.h> | ||
39 | #include <asm/sibyte/sb1250_regs.h> | ||
40 | #include <asm/sibyte/sb1250_int.h> | ||
41 | |||
42 | /* | ||
43 | * What a pain. We have to be really careful saving the upper 32 bits of any | ||
44 | * register across function calls if we don't want them trashed--since were | ||
45 | * running in -o32, the calling routing never saves the full 64 bits of a | ||
46 | * register across a function call. Being the interrupt handler, we're | ||
47 | * guaranteed that interrupts are disabled during this code so we don't have | ||
48 | * to worry about random interrupts blasting the high 32 bits. | ||
49 | */ | ||
50 | |||
51 | .text | ||
52 | .set push | ||
53 | .set noreorder | ||
54 | .set noat | ||
55 | .set mips64 | ||
56 | .align 5 | ||
57 | NESTED(sb1250_irq_handler, PT_SIZE, sp) | ||
58 | SAVE_ALL | ||
59 | CLI | ||
60 | |||
61 | #ifdef CONFIG_SIBYTE_SB1250_PROF | ||
62 | /* Set compare to count to silence count/compare timer interrupts */ | ||
63 | mfc0 t1, CP0_COUNT | ||
64 | mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */ | ||
65 | #endif | ||
66 | /* Read cause */ | ||
67 | mfc0 s0, CP0_CAUSE | ||
68 | |||
69 | #ifdef CONFIG_SIBYTE_SB1250_PROF | ||
70 | /* Cpu performance counter interrupt is routed to IP[7] */ | ||
71 | andi t1, s0, CAUSEF_IP7 | ||
72 | beqz t1, 0f | ||
73 | srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */ | ||
74 | and t1, t1, 0x4 /* mask to get just BD bit */ | ||
75 | mfc0 a0, CP0_EPC | ||
76 | jal sbprof_cpu_intr | ||
77 | addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ | ||
78 | j ret_from_irq | ||
79 | nop | ||
80 | 0: | ||
81 | #endif | ||
82 | |||
83 | /* Timer interrupt is routed to IP[4] */ | ||
84 | andi t1, s0, CAUSEF_IP4 | ||
85 | beqz t1, 1f | ||
86 | nop | ||
87 | jal sb1250_timer_interrupt | ||
88 | move a0, sp /* Pass the registers along */ | ||
89 | j ret_from_irq | ||
90 | nop # delay slot | ||
91 | 1: | ||
92 | |||
93 | #ifdef CONFIG_SMP | ||
94 | /* Mailbox interrupt is routed to IP[3] */ | ||
95 | andi t1, s0, CAUSEF_IP3 | ||
96 | beqz t1, 2f | ||
97 | nop | ||
98 | jal sb1250_mailbox_interrupt | ||
99 | move a0, sp | ||
100 | j ret_from_irq | ||
101 | nop # delay slot | ||
102 | 2: | ||
103 | #endif | ||
104 | |||
105 | #ifdef CONFIG_KGDB | ||
106 | /* KGDB (uart 1) interrupt is routed to IP[6] */ | ||
107 | andi t1, s0, CAUSEF_IP6 | ||
108 | beqz t1, 1f | ||
109 | nop # delay slot | ||
110 | jal sb1250_kgdb_interrupt | ||
111 | move a0, sp | ||
112 | j ret_from_irq | ||
113 | nop # delay slot | ||
114 | 1: | ||
115 | #endif | ||
116 | |||
117 | and t1, s0, CAUSEF_IP2 | ||
118 | beqz t1, 4f | ||
119 | nop | ||
120 | |||
121 | /* | ||
122 | * Default...we've hit an IP[2] interrupt, which means we've got to | ||
123 | * check the 1250 interrupt registers to figure out what to do | ||
124 | * Need to detect which CPU we're on, now that smp_affinity is supported. | ||
125 | */ | ||
126 | PTR_LA v0, CKSEG1 + A_IMR_CPU0_BASE | ||
127 | #ifdef CONFIG_SMP | ||
128 | lw t1, TI_CPU($28) | ||
129 | sll t1, IMR_REGISTER_SPACING_SHIFT | ||
130 | addu v0, t1 | ||
131 | #endif | ||
132 | ld s0, R_IMR_INTERRUPT_STATUS_BASE(v0) /* read IP[2] status */ | ||
133 | |||
134 | beqz s0, 4f /* No interrupts. Return */ | ||
135 | move a1, sp | ||
136 | |||
137 | 3: dclz s1, s0 /* Find the next interrupt */ | ||
138 | dsubu a0, zero, s1 | ||
139 | daddiu a0, a0, 63 | ||
140 | jal do_IRQ | ||
141 | nop | ||
142 | |||
143 | 4: j ret_from_irq | ||
144 | nop | ||
145 | |||
146 | .set pop | ||
147 | END(sb1250_irq_handler) | ||
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile index 1e5676e4be86..9c7eaa5fb210 100644 --- a/arch/mips/sni/Makefile +++ b/arch/mips/sni/Makefile | |||
@@ -2,6 +2,6 @@ | |||
2 | # Makefile for the SNI specific part of the kernel | 2 | # Makefile for the SNI specific part of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += int-handler.o irq.o pcimt_scache.o reset.o setup.o | 5 | obj-y += irq.o pcimt_scache.o reset.o setup.o |
6 | 6 | ||
7 | EXTRA_AFLAGS := $(CFLAGS) | 7 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S deleted file mode 100644 index 2cdc09f55f18..000000000000 --- a/arch/mips/sni/int-handler.S +++ /dev/null | |||
@@ -1,106 +0,0 @@ | |||
1 | /* | ||
2 | * SNI RM200 PCI specific interrupt handler code. | ||
3 | * | ||
4 | * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000, 01 by Ralf Baechle | ||
5 | */ | ||
6 | #include <asm/asm.h> | ||
7 | #include <asm/mipsregs.h> | ||
8 | #include <asm/regdef.h> | ||
9 | #include <asm/sni.h> | ||
10 | #include <asm/stackframe.h> | ||
11 | |||
12 | /* | ||
13 | * The PCI ASIC has the nasty property that it may delay writes if it is busy. | ||
14 | * As a consequence from writes that have not graduated when we exit from the | ||
15 | * interrupt handler we might catch a spurious interrupt. To avoid this we | ||
16 | * force the PCI ASIC to graduate all writes by executing a read from the | ||
17 | * PCI bus. | ||
18 | */ | ||
19 | .set noreorder | ||
20 | .set noat | ||
21 | .align 5 | ||
22 | NESTED(sni_rm200_pci_handle_int, PT_SIZE, sp) | ||
23 | SAVE_ALL | ||
24 | CLI | ||
25 | .set at | ||
26 | |||
27 | /* Blinken light ... */ | ||
28 | lb t0, led_cache | ||
29 | addiu t0, 1 | ||
30 | sb t0, led_cache | ||
31 | sb t0, PCIMT_CSLED # write only register | ||
32 | .data | ||
33 | led_cache: .byte 0 | ||
34 | .text | ||
35 | |||
36 | mfc0 t0, CP0_STATUS | ||
37 | mfc0 t1, CP0_CAUSE | ||
38 | and t0, t1 | ||
39 | |||
40 | andi t1, t0, 0x0800 # hardware interrupt 1 | ||
41 | bnez t1, _hwint1 | ||
42 | andi t1, t0, 0x4000 # hardware interrupt 4 | ||
43 | bnez t1, _hwint4 | ||
44 | andi t1, t0, 0x2000 # hardware interrupt 3 | ||
45 | bnez t1, _hwint3 | ||
46 | andi t1, t0, 0x1000 # hardware interrupt 2 | ||
47 | bnez t1, _hwint2 | ||
48 | andi t1, t0, 0x8000 # hardware interrupt 5 | ||
49 | bnez t1, _hwint5 | ||
50 | andi t1, t0, 0x0400 # hardware interrupt 0 | ||
51 | bnez t1, _hwint0 | ||
52 | nop | ||
53 | |||
54 | j restore_all # spurious interrupt | ||
55 | nop | ||
56 | |||
57 | ############################################################################## | ||
58 | |||
59 | /* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug | ||
60 | button interrupts. */ | ||
61 | _hwint0: jal pciasic_hwint0 | ||
62 | move a0, sp | ||
63 | j ret_from_irq | ||
64 | nop | ||
65 | |||
66 | /* | ||
67 | * hwint 1 deals with EISA and SCSI interrupts | ||
68 | */ | ||
69 | _hwint1: jal pciasic_hwint1 | ||
70 | move a0, sp | ||
71 | j ret_from_irq | ||
72 | nop | ||
73 | |||
74 | |||
75 | /* | ||
76 | * This interrupt was used for the com1 console on the first prototypes; | ||
77 | * it's unsed otherwise | ||
78 | */ | ||
79 | _hwint2: jal pciasic_hwint2 | ||
80 | move a0, sp | ||
81 | j ret_from_irq | ||
82 | nop | ||
83 | |||
84 | /* | ||
85 | * hwint 3 are the PCI interrupts A - D | ||
86 | */ | ||
87 | _hwint3: jal pciasic_hwint3 | ||
88 | move a0, sp | ||
89 | j ret_from_irq | ||
90 | nop | ||
91 | |||
92 | /* | ||
93 | * hwint 4 is used for only the onboard PCnet 32. | ||
94 | */ | ||
95 | _hwint4: jal pciasic_hwint4 | ||
96 | move a0, sp | ||
97 | j ret_from_irq | ||
98 | nop | ||
99 | |||
100 | /* hwint5 is the r4k count / compare interrupt */ | ||
101 | _hwint5: jal pciasic_hwint5 | ||
102 | move a0, sp | ||
103 | j ret_from_irq | ||
104 | nop | ||
105 | |||
106 | END(sni_rm200_pci_handle_int) | ||
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c index 952038aa4b90..7365b4853ddb 100644 --- a/arch/mips/sni/irq.c +++ b/arch/mips/sni/irq.c | |||
@@ -19,8 +19,6 @@ | |||
19 | 19 | ||
20 | DEFINE_SPINLOCK(pciasic_lock); | 20 | DEFINE_SPINLOCK(pciasic_lock); |
21 | 21 | ||
22 | extern asmlinkage void sni_rm200_pci_handle_int(void); | ||
23 | |||
24 | static void enable_pciasic_irq(unsigned int irq) | 22 | static void enable_pciasic_irq(unsigned int irq) |
25 | { | 23 | { |
26 | unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); | 24 | unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); |
@@ -71,20 +69,20 @@ static struct hw_interrupt_type pciasic_irq_type = { | |||
71 | * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug | 69 | * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug |
72 | * button interrupts. Later ... | 70 | * button interrupts. Later ... |
73 | */ | 71 | */ |
74 | void pciasic_hwint0(struct pt_regs *regs) | 72 | static void pciasic_hwint0(struct pt_regs *regs) |
75 | { | 73 | { |
76 | panic("Received int0 but no handler yet ..."); | 74 | panic("Received int0 but no handler yet ..."); |
77 | } | 75 | } |
78 | 76 | ||
79 | /* This interrupt was used for the com1 console on the first prototypes. */ | 77 | /* This interrupt was used for the com1 console on the first prototypes. */ |
80 | void pciasic_hwint2(struct pt_regs *regs) | 78 | static void pciasic_hwint2(struct pt_regs *regs) |
81 | { | 79 | { |
82 | /* I think this shouldn't happen on production machines. */ | 80 | /* I think this shouldn't happen on production machines. */ |
83 | panic("hwint2 and no handler yet"); | 81 | panic("hwint2 and no handler yet"); |
84 | } | 82 | } |
85 | 83 | ||
86 | /* hwint5 is the r4k count / compare interrupt */ | 84 | /* hwint5 is the r4k count / compare interrupt */ |
87 | void pciasic_hwint5(struct pt_regs *regs) | 85 | static void pciasic_hwint5(struct pt_regs *regs) |
88 | { | 86 | { |
89 | panic("hwint5 and no handler yet"); | 87 | panic("hwint5 and no handler yet"); |
90 | } | 88 | } |
@@ -105,7 +103,7 @@ static unsigned int ls1bit8(unsigned int x) | |||
105 | * | 103 | * |
106 | * The EISA_INT bit in CSITPEND is high active, all others are low active. | 104 | * The EISA_INT bit in CSITPEND is high active, all others are low active. |
107 | */ | 105 | */ |
108 | void pciasic_hwint1(struct pt_regs *regs) | 106 | static void pciasic_hwint1(struct pt_regs *regs) |
109 | { | 107 | { |
110 | u8 pend = *(volatile char *)PCIMT_CSITPEND; | 108 | u8 pend = *(volatile char *)PCIMT_CSITPEND; |
111 | unsigned long flags; | 109 | unsigned long flags; |
@@ -135,7 +133,7 @@ void pciasic_hwint1(struct pt_regs *regs) | |||
135 | /* | 133 | /* |
136 | * hwint 3 should deal with the PCI A - D interrupts, | 134 | * hwint 3 should deal with the PCI A - D interrupts, |
137 | */ | 135 | */ |
138 | void pciasic_hwint3(struct pt_regs *regs) | 136 | static void pciasic_hwint3(struct pt_regs *regs) |
139 | { | 137 | { |
140 | u8 pend = *(volatile char *)PCIMT_CSITPEND; | 138 | u8 pend = *(volatile char *)PCIMT_CSITPEND; |
141 | int irq; | 139 | int irq; |
@@ -150,13 +148,34 @@ void pciasic_hwint3(struct pt_regs *regs) | |||
150 | /* | 148 | /* |
151 | * hwint 4 is used for only the onboard PCnet 32. | 149 | * hwint 4 is used for only the onboard PCnet 32. |
152 | */ | 150 | */ |
153 | void pciasic_hwint4(struct pt_regs *regs) | 151 | static void pciasic_hwint4(struct pt_regs *regs) |
154 | { | 152 | { |
155 | clear_c0_status(IE_IRQ4); | 153 | clear_c0_status(IE_IRQ4); |
156 | do_IRQ(PCIMT_IRQ_ETHERNET, regs); | 154 | do_IRQ(PCIMT_IRQ_ETHERNET, regs); |
157 | set_c0_status(IE_IRQ4); | 155 | set_c0_status(IE_IRQ4); |
158 | } | 156 | } |
159 | 157 | ||
158 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
159 | { | ||
160 | unsigned int pending = read_c0_status() & read_c0_cause(); | ||
161 | static unsigned char led_cache; | ||
162 | |||
163 | *(volatile unsigned char *) PCIMT_CSLED = ++led_cache; | ||
164 | |||
165 | if (pending & 0x0800) | ||
166 | pciasic_hwint1(regs); | ||
167 | else if (pending & 0x4000) | ||
168 | pciasic_hwint4(regs); | ||
169 | else if (pending & 0x2000) | ||
170 | pciasic_hwint3(regs); | ||
171 | else if (pending & 0x1000) | ||
172 | pciasic_hwint2(regs); | ||
173 | else if (pending & 0x8000) | ||
174 | pciasic_hwint5(regs); | ||
175 | else if (pending & 0x0400) | ||
176 | pciasic_hwint0(regs); | ||
177 | } | ||
178 | |||
160 | void __init init_pciasic(void) | 179 | void __init init_pciasic(void) |
161 | { | 180 | { |
162 | unsigned long flags; | 181 | unsigned long flags; |
@@ -176,8 +195,6 @@ void __init arch_init_irq(void) | |||
176 | { | 195 | { |
177 | int i; | 196 | int i; |
178 | 197 | ||
179 | set_except_vector(0, sni_rm200_pci_handle_int); | ||
180 | |||
181 | init_i8259_irqs(); /* Integrated i8259 */ | 198 | init_i8259_irqs(); /* Integrated i8259 */ |
182 | init_pciasic(); | 199 | init_pciasic(); |
183 | 200 | ||
diff --git a/arch/mips/tx4927/common/Makefile b/arch/mips/tx4927/common/Makefile index 8fa126b296e1..9cb9535ebacb 100644 --- a/arch/mips/tx4927/common/Makefile +++ b/arch/mips/tx4927/common/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | # unless it's something special (ie not a .c file). | 6 | # unless it's something special (ie not a .c file). |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o tx4927_irq_handler.o | 9 | obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o |
10 | 10 | ||
11 | obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o | 11 | obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o |
12 | obj-$(CONFIG_KGDB) += tx4927_dbgio.o | 12 | obj-$(CONFIG_KGDB) += tx4927_dbgio.o |
diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 5ab2e2b76018..8ca68015cf40 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c | |||
@@ -525,8 +525,6 @@ static void tx4927_irq_pic_end(unsigned int irq) | |||
525 | */ | 525 | */ |
526 | void __init tx4927_irq_init(void) | 526 | void __init tx4927_irq_init(void) |
527 | { | 527 | { |
528 | extern asmlinkage void tx4927_irq_handler(void); | ||
529 | |||
530 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); | 528 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); |
531 | 529 | ||
532 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); | 530 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); |
@@ -535,16 +533,12 @@ void __init tx4927_irq_init(void) | |||
535 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); | 533 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); |
536 | tx4927_irq_pic_init(); | 534 | tx4927_irq_pic_init(); |
537 | 535 | ||
538 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, | ||
539 | "=Calling set_except_vector(tx4927_irq_handler)\n"); | ||
540 | set_except_vector(0, tx4927_irq_handler); | ||
541 | |||
542 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); | 536 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); |
543 | 537 | ||
544 | return; | 538 | return; |
545 | } | 539 | } |
546 | 540 | ||
547 | int tx4927_irq_nested(void) | 541 | static int tx4927_irq_nested(void) |
548 | { | 542 | { |
549 | int sw_irq = 0; | 543 | int sw_irq = 0; |
550 | u32 level2; | 544 | u32 level2; |
@@ -582,3 +576,25 @@ int tx4927_irq_nested(void) | |||
582 | 576 | ||
583 | return (sw_irq); | 577 | return (sw_irq); |
584 | } | 578 | } |
579 | |||
580 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
581 | { | ||
582 | unsigned int pending = read_c0_status() & read_c0_cause(); | ||
583 | |||
584 | if (pending & STATUSF_IP7) /* cpu timer */ | ||
585 | do_IRQ(TX4927_IRQ_CPU_TIMER, regs); | ||
586 | else if (pending & STATUSF_IP2) { /* tx4927 pic */ | ||
587 | unsigned int irq = tx4927_irq_nested(); | ||
588 | |||
589 | if (unlikely(irq == 0)) { | ||
590 | spurious_interrupt(regs); | ||
591 | return; | ||
592 | } | ||
593 | do_IRQ(irq, regs); | ||
594 | } else if (pending & STATUSF_IP0) /* user line 0 */ | ||
595 | do_IRQ(TX4927_IRQ_USER0, regs); | ||
596 | else if (pending & STATUSF_IP1) /* user line 1 */ | ||
597 | do_IRQ(TX4927_IRQ_USER1, regs); | ||
598 | else | ||
599 | spurious_interrupt(regs); | ||
600 | } | ||
diff --git a/arch/mips/tx4927/common/tx4927_irq_handler.S b/arch/mips/tx4927/common/tx4927_irq_handler.S deleted file mode 100644 index dd3ceda9d712..000000000000 --- a/arch/mips/tx4927/common/tx4927_irq_handler.S +++ /dev/null | |||
@@ -1,103 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/mips/tx4927/common/tx4927_irq_handler.S | ||
3 | * | ||
4 | * Primary interrupt handler for tx4927 based systems | ||
5 | * | ||
6 | * Author: MontaVista Software, Inc. | ||
7 | * Author: jsun@mvista.com or jsun@junsun.net | ||
8 | * source@mvista.com | ||
9 | * | ||
10 | * Copyright 2001-2002 MontaVista Software Inc. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License as published by the | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
22 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | ||
23 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | ||
25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
26 | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License along | ||
29 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
30 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
31 | */ | ||
32 | #include <asm/asm.h> | ||
33 | #include <asm/mipsregs.h> | ||
34 | #include <asm/addrspace.h> | ||
35 | #include <asm/regdef.h> | ||
36 | #include <asm/stackframe.h> | ||
37 | #include <asm/tx4927/tx4927.h> | ||
38 | |||
39 | .align 5 | ||
40 | NESTED(tx4927_irq_handler, PT_SIZE, sp) | ||
41 | SAVE_ALL | ||
42 | CLI | ||
43 | .set at | ||
44 | |||
45 | mfc0 t0, CP0_CAUSE | ||
46 | mfc0 t1, CP0_STATUS | ||
47 | and t0, t1 | ||
48 | |||
49 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
50 | bnez t1, ll_ip7 | ||
51 | |||
52 | /* IP6..IP3 multiplexed -- do not use */ | ||
53 | |||
54 | andi t1, t0, STATUSF_IP2 /* tx4927 pic */ | ||
55 | bnez t1, ll_ip2 | ||
56 | |||
57 | andi t1, t0, STATUSF_IP0 /* user line 0 */ | ||
58 | bnez t1, ll_ip0 | ||
59 | |||
60 | andi t1, t0, STATUSF_IP1 /* user line 1 */ | ||
61 | bnez t1, ll_ip1 | ||
62 | |||
63 | .set reorder | ||
64 | |||
65 | /* wrong alarm or masked ... */ | ||
66 | j spurious_interrupt | ||
67 | nop | ||
68 | END(tx4927_irq_handler) | ||
69 | |||
70 | .align 5 | ||
71 | |||
72 | |||
73 | ll_ip7: | ||
74 | li a0, TX4927_IRQ_CPU_TIMER | ||
75 | move a1, sp | ||
76 | jal do_IRQ | ||
77 | j ret_from_irq | ||
78 | |||
79 | ll_ip2: | ||
80 | jal tx4927_irq_nested | ||
81 | nop | ||
82 | beqz v0, goto_spurious_interrupt | ||
83 | nop | ||
84 | move a0, v0 | ||
85 | move a1, sp | ||
86 | jal do_IRQ | ||
87 | j ret_from_irq | ||
88 | |||
89 | goto_spurious_interrupt: | ||
90 | j spurious_interrupt | ||
91 | nop | ||
92 | |||
93 | ll_ip1: | ||
94 | li a0, TX4927_IRQ_USER1 | ||
95 | move a1, sp | ||
96 | jal do_IRQ | ||
97 | j ret_from_irq | ||
98 | |||
99 | ll_ip0: | ||
100 | li a0, TX4927_IRQ_USER0 | ||
101 | move a1, sp | ||
102 | jal do_IRQ | ||
103 | j ret_from_irq | ||
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile index 74c95c5bcdbf..2033ae77f632 100644 --- a/arch/mips/tx4938/common/Makefile +++ b/arch/mips/tx4938/common/Makefile | |||
@@ -6,6 +6,6 @@ | |||
6 | # unless it's something special (ie not a .c file). | 6 | # unless it's something special (ie not a .c file). |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o | 9 | obj-y += prom.o setup.o irq.o rtc_rx5c348.o |
10 | obj-$(CONFIG_KGDB) += dbgio.o | 10 | obj-$(CONFIG_KGDB) += dbgio.o |
11 | 11 | ||
diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c index 4f90d7faf634..873805178d8e 100644 --- a/arch/mips/tx4938/common/irq.c +++ b/arch/mips/tx4938/common/irq.c | |||
@@ -392,11 +392,8 @@ tx4938_irq_pic_end(unsigned int irq) | |||
392 | void __init | 392 | void __init |
393 | tx4938_irq_init(void) | 393 | tx4938_irq_init(void) |
394 | { | 394 | { |
395 | extern asmlinkage void tx4938_irq_handler(void); | ||
396 | |||
397 | tx4938_irq_cp0_init(); | 395 | tx4938_irq_cp0_init(); |
398 | tx4938_irq_pic_init(); | 396 | tx4938_irq_pic_init(); |
399 | set_except_vector(0, tx4938_irq_handler); | ||
400 | 397 | ||
401 | return; | 398 | return; |
402 | } | 399 | } |
@@ -422,3 +419,21 @@ tx4938_irq_nested(void) | |||
422 | wbflush(); | 419 | wbflush(); |
423 | return (sw_irq); | 420 | return (sw_irq); |
424 | } | 421 | } |
422 | |||
423 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
424 | { | ||
425 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
426 | |||
427 | if (pending & STATUSF_IP7) | ||
428 | do_IRQ(TX4938_IRQ_CPU_TIMER, regs); | ||
429 | else if (pending & STATUSF_IP2) { | ||
430 | int irq = tx4938_irq_nested(); | ||
431 | if (irq) | ||
432 | do_IRQ(irq, regs); | ||
433 | else | ||
434 | spurious_interrupt(regs); | ||
435 | } else if (pending & STATUSF_IP1) | ||
436 | do_IRQ(TX4938_IRQ_USER1, regs); | ||
437 | else if (pending & STATUSF_IP0) | ||
438 | do_IRQ(TX4938_IRQ_USER0, regs); | ||
439 | } | ||
diff --git a/arch/mips/tx4938/common/irq_handler.S b/arch/mips/tx4938/common/irq_handler.S deleted file mode 100644 index 1b2f72bac42d..000000000000 --- a/arch/mips/tx4938/common/irq_handler.S +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/mips/tx4938/common/handler.S | ||
3 | * | ||
4 | * Primary interrupt handler for tx4938 based systems | ||
5 | * Copyright (C) 2000-2001 Toshiba Corporation | ||
6 | * | ||
7 | * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the | ||
8 | * terms of the GNU General Public License version 2. This program is | ||
9 | * licensed "as is" without any warranty of any kind, whether express | ||
10 | * or implied. | ||
11 | * | ||
12 | * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) | ||
13 | */ | ||
14 | #include <asm/asm.h> | ||
15 | #include <asm/mipsregs.h> | ||
16 | #include <asm/addrspace.h> | ||
17 | #include <asm/regdef.h> | ||
18 | #include <asm/stackframe.h> | ||
19 | #include <asm/tx4938/rbtx4938.h> | ||
20 | |||
21 | |||
22 | .align 5 | ||
23 | NESTED(tx4938_irq_handler, PT_SIZE, sp) | ||
24 | SAVE_ALL | ||
25 | CLI | ||
26 | .set at | ||
27 | |||
28 | mfc0 t0, CP0_CAUSE | ||
29 | mfc0 t1, CP0_STATUS | ||
30 | and t0, t1 | ||
31 | |||
32 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
33 | bnez t1, ll_ip7 | ||
34 | |||
35 | /* IP6..IP3 multiplexed -- do not use */ | ||
36 | |||
37 | andi t1, t0, STATUSF_IP2 /* tx4938 pic */ | ||
38 | bnez t1, ll_ip2 | ||
39 | |||
40 | andi t1, t0, STATUSF_IP1 /* user line 1 */ | ||
41 | bnez t1, ll_ip1 | ||
42 | |||
43 | andi t1, t0, STATUSF_IP0 /* user line 0 */ | ||
44 | bnez t1, ll_ip0 | ||
45 | |||
46 | .set reorder | ||
47 | |||
48 | nop | ||
49 | END(tx4938_irq_handler) | ||
50 | |||
51 | .align 5 | ||
52 | |||
53 | |||
54 | ll_ip7: | ||
55 | li a0, TX4938_IRQ_CPU_TIMER | ||
56 | move a1, sp | ||
57 | jal do_IRQ | ||
58 | j ret_from_irq | ||
59 | |||
60 | |||
61 | ll_ip2: | ||
62 | jal tx4938_irq_nested | ||
63 | nop | ||
64 | beqz v0, goto_spurious_interrupt | ||
65 | nop | ||
66 | move a0, v0 | ||
67 | move a1, sp | ||
68 | jal do_IRQ | ||
69 | j ret_from_irq | ||
70 | |||
71 | goto_spurious_interrupt: | ||
72 | j ret_from_irq | ||
73 | |||
74 | ll_ip1: | ||
75 | li a0, TX4938_IRQ_USER1 | ||
76 | move a1, sp | ||
77 | jal do_IRQ | ||
78 | j ret_from_irq | ||
79 | |||
80 | ll_ip0: | ||
81 | li a0, TX4938_IRQ_USER0 | ||
82 | move a1, sp | ||
83 | jal do_IRQ | ||
84 | j ret_from_irq | ||
diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig index a7add16c9aa4..055a2cdfc841 100644 --- a/arch/mips/vr41xx/Kconfig +++ b/arch/mips/vr41xx/Kconfig | |||
@@ -4,6 +4,8 @@ config CASIO_E55 | |||
4 | select DMA_NONCOHERENT | 4 | select DMA_NONCOHERENT |
5 | select IRQ_CPU | 5 | select IRQ_CPU |
6 | select ISA | 6 | select ISA |
7 | select SYS_HAS_CPU_VR41XX | ||
8 | select SYS_SUPPORTS_32BIT_KERNEL | ||
7 | select SYS_SUPPORTS_LITTLE_ENDIAN | 9 | select SYS_SUPPORTS_LITTLE_ENDIAN |
8 | 10 | ||
9 | config IBM_WORKPAD | 11 | config IBM_WORKPAD |
@@ -12,6 +14,8 @@ config IBM_WORKPAD | |||
12 | select DMA_NONCOHERENT | 14 | select DMA_NONCOHERENT |
13 | select IRQ_CPU | 15 | select IRQ_CPU |
14 | select ISA | 16 | select ISA |
17 | select SYS_HAS_CPU_VR41XX | ||
18 | select SYS_SUPPORTS_32BIT_KERNEL | ||
15 | select SYS_SUPPORTS_LITTLE_ENDIAN | 19 | select SYS_SUPPORTS_LITTLE_ENDIAN |
16 | 20 | ||
17 | config NEC_CMBVR4133 | 21 | config NEC_CMBVR4133 |
@@ -21,6 +25,9 @@ config NEC_CMBVR4133 | |||
21 | select DMA_NONCOHERENT | 25 | select DMA_NONCOHERENT |
22 | select IRQ_CPU | 26 | select IRQ_CPU |
23 | select HW_HAS_PCI | 27 | select HW_HAS_PCI |
28 | select SYS_HAS_CPU_VR41XX | ||
29 | select SYS_SUPPORTS_32BIT_KERNEL | ||
30 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
24 | 31 | ||
25 | config ROCKHOPPER | 32 | config ROCKHOPPER |
26 | bool "Support for Rockhopper baseboard" | 33 | bool "Support for Rockhopper baseboard" |
@@ -34,6 +41,8 @@ config TANBAC_TB022X | |||
34 | select DMA_NONCOHERENT | 41 | select DMA_NONCOHERENT |
35 | select HW_HAS_PCI | 42 | select HW_HAS_PCI |
36 | select IRQ_CPU | 43 | select IRQ_CPU |
44 | select SYS_HAS_CPU_VR41XX | ||
45 | select SYS_SUPPORTS_32BIT_KERNEL | ||
37 | select SYS_SUPPORTS_LITTLE_ENDIAN | 46 | select SYS_SUPPORTS_LITTLE_ENDIAN |
38 | help | 47 | help |
39 | The TANBAC VR4131 multichip module(TB0225) and | 48 | The TANBAC VR4131 multichip module(TB0225) and |
@@ -65,6 +74,8 @@ config VICTOR_MPC30X | |||
65 | select DMA_NONCOHERENT | 74 | select DMA_NONCOHERENT |
66 | select HW_HAS_PCI | 75 | select HW_HAS_PCI |
67 | select IRQ_CPU | 76 | select IRQ_CPU |
77 | select SYS_HAS_CPU_VR41XX | ||
78 | select SYS_SUPPORTS_32BIT_KERNEL | ||
68 | select SYS_SUPPORTS_LITTLE_ENDIAN | 79 | select SYS_SUPPORTS_LITTLE_ENDIAN |
69 | 80 | ||
70 | config ZAO_CAPCELLA | 81 | config ZAO_CAPCELLA |
@@ -73,6 +84,8 @@ config ZAO_CAPCELLA | |||
73 | select DMA_NONCOHERENT | 84 | select DMA_NONCOHERENT |
74 | select HW_HAS_PCI | 85 | select HW_HAS_PCI |
75 | select IRQ_CPU | 86 | select IRQ_CPU |
87 | select SYS_HAS_CPU_VR41XX | ||
88 | select SYS_SUPPORTS_32BIT_KERNEL | ||
76 | select SYS_SUPPORTS_LITTLE_ENDIAN | 89 | select SYS_SUPPORTS_LITTLE_ENDIAN |
77 | 90 | ||
78 | config PCI_VR41XX | 91 | config PCI_VR41XX |
diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile index 9096302a7ecc..aa373974c80f 100644 --- a/arch/mips/vr41xx/common/Makefile +++ b/arch/mips/vr41xx/common/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for common code of the NEC VR4100 series. | 2 | # Makefile for common code of the NEC VR4100 series. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += bcu.o cmu.o icu.o init.o int-handler.o irq.o pmu.o type.o | 5 | obj-y += bcu.o cmu.o icu.o init.o irq.o pmu.o type.o |
6 | obj-$(CONFIG_VRC4173) += vrc4173.o | 6 | obj-$(CONFIG_VRC4173) += vrc4173.o |
7 | 7 | ||
8 | EXTRA_AFLAGS := $(CFLAGS) | 8 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/vr41xx/common/int-handler.S b/arch/mips/vr41xx/common/int-handler.S deleted file mode 100644 index 2b6043f16d09..000000000000 --- a/arch/mips/vr41xx/common/int-handler.S +++ /dev/null | |||
@@ -1,114 +0,0 @@ | |||
1 | /* | ||
2 | * FILE NAME | ||
3 | * arch/mips/vr41xx/common/int-handler.S | ||
4 | * | ||
5 | * BRIEF MODULE DESCRIPTION | ||
6 | * Interrupt dispatcher for the NEC VR4100 series. | ||
7 | * | ||
8 | * Author: Yoichi Yuasa | ||
9 | * yyuasa@mvista.com or source@mvista.com | ||
10 | * | ||
11 | * Copyright 2001 MontaVista Software Inc. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License as published by the | ||
15 | * Free Software Foundation; either version 2 of the License, or (at your | ||
16 | * option) any later version. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
23 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | ||
24 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | ||
26 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
27 | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | * | ||
29 | * You should have received a copy of the GNU General Public License along | ||
30 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
31 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
32 | */ | ||
33 | /* | ||
34 | * Changes: | ||
35 | * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> | ||
36 | * - New creation, NEC VR4100 series are supported. | ||
37 | * | ||
38 | * Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | ||
39 | * - Coped with INTASSIGN of NEC VR4133. | ||
40 | */ | ||
41 | #include <asm/asm.h> | ||
42 | #include <asm/regdef.h> | ||
43 | #include <asm/mipsregs.h> | ||
44 | #include <asm/stackframe.h> | ||
45 | |||
46 | .text | ||
47 | .set noreorder | ||
48 | |||
49 | .align 5 | ||
50 | NESTED(vr41xx_handle_interrupt, PT_SIZE, ra) | ||
51 | .set noat | ||
52 | SAVE_ALL | ||
53 | CLI | ||
54 | .set at | ||
55 | .set noreorder | ||
56 | |||
57 | /* | ||
58 | * Get the pending interrupts | ||
59 | */ | ||
60 | mfc0 t0, CP0_CAUSE | ||
61 | mfc0 t1, CP0_STATUS | ||
62 | andi t0, 0xff00 | ||
63 | and t0, t0, t1 | ||
64 | |||
65 | andi t1, t0, CAUSEF_IP7 # MIPS timer interrupt | ||
66 | bnez t1, handle_irq | ||
67 | li a0, 7 | ||
68 | |||
69 | andi t1, t0, 0x7800 # check for Int1-4 | ||
70 | beqz t1, 1f | ||
71 | |||
72 | andi t1, t0, CAUSEF_IP3 # check for Int1 | ||
73 | bnez t1, handle_int | ||
74 | li a0, 3 | ||
75 | |||
76 | andi t1, t0, CAUSEF_IP4 # check for Int2 | ||
77 | bnez t1, handle_int | ||
78 | li a0, 4 | ||
79 | |||
80 | andi t1, t0, CAUSEF_IP5 # check for Int3 | ||
81 | bnez t1, handle_int | ||
82 | li a0, 5 | ||
83 | |||
84 | andi t1, t0, CAUSEF_IP6 # check for Int4 | ||
85 | bnez t1, handle_int | ||
86 | li a0, 6 | ||
87 | |||
88 | 1: | ||
89 | andi t1, t0, CAUSEF_IP2 # check for Int0 | ||
90 | bnez t1, handle_int | ||
91 | li a0, 2 | ||
92 | |||
93 | andi t1, t0, CAUSEF_IP0 # check for IP0 | ||
94 | bnez t1, handle_irq | ||
95 | li a0, 0 | ||
96 | |||
97 | andi t1, t0, CAUSEF_IP1 # check for IP1 | ||
98 | bnez t1, handle_irq | ||
99 | li a0, 1 | ||
100 | |||
101 | j spurious_interrupt | ||
102 | nop | ||
103 | |||
104 | handle_int: | ||
105 | jal irq_dispatch | ||
106 | move a1, sp | ||
107 | j ret_from_irq | ||
108 | nop | ||
109 | |||
110 | handle_irq: | ||
111 | jal do_IRQ | ||
112 | move a1, sp | ||
113 | j ret_from_irq | ||
114 | END(vr41xx_handle_interrupt) | ||
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c index 61aa264275ff..86796bb63c3c 100644 --- a/arch/mips/vr41xx/common/irq.c +++ b/arch/mips/vr41xx/common/irq.c | |||
@@ -59,7 +59,7 @@ int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *) | |||
59 | 59 | ||
60 | EXPORT_SYMBOL_GPL(cascade_irq); | 60 | EXPORT_SYMBOL_GPL(cascade_irq); |
61 | 61 | ||
62 | asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs) | 62 | static void irq_dispatch(unsigned int irq, struct pt_regs *regs) |
63 | { | 63 | { |
64 | irq_cascade_t *cascade; | 64 | irq_cascade_t *cascade; |
65 | irq_desc_t *desc; | 65 | irq_desc_t *desc; |
@@ -84,11 +84,32 @@ asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs) | |||
84 | do_IRQ(irq, regs); | 84 | do_IRQ(irq, regs); |
85 | } | 85 | } |
86 | 86 | ||
87 | extern asmlinkage void vr41xx_handle_interrupt(void); | 87 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
88 | { | ||
89 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
90 | |||
91 | if (pending & CAUSEF_IP7) | ||
92 | do_IRQ(7, regs); | ||
93 | else if (pending & 0x7800) { | ||
94 | if (pending & CAUSEF_IP3) | ||
95 | irq_dispatch(3, regs); | ||
96 | else if (pending & CAUSEF_IP4) | ||
97 | irq_dispatch(4, regs); | ||
98 | else if (pending & CAUSEF_IP5) | ||
99 | irq_dispatch(5, regs); | ||
100 | else if (pending & CAUSEF_IP6) | ||
101 | irq_dispatch(6, regs); | ||
102 | } else if (pending & CAUSEF_IP2) | ||
103 | irq_dispatch(2, regs); | ||
104 | else if (pending & CAUSEF_IP0) | ||
105 | do_IRQ(0, regs); | ||
106 | else if (pending & CAUSEF_IP1) | ||
107 | do_IRQ(1, regs); | ||
108 | else | ||
109 | spurious_interrupt(regs); | ||
110 | } | ||
88 | 111 | ||
89 | void __init arch_init_irq(void) | 112 | void __init arch_init_irq(void) |
90 | { | 113 | { |
91 | mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); | 114 | mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); |
92 | |||
93 | set_except_vector(0, vr41xx_handle_interrupt); | ||
94 | } | 115 | } |
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 2fdf21989dc2..19f911c5dd58 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -177,6 +177,11 @@ config ARCH_DISCONTIGMEM_DEFAULT | |||
177 | def_bool y | 177 | def_bool y |
178 | depends on ARCH_DISCONTIGMEM_ENABLE | 178 | depends on ARCH_DISCONTIGMEM_ENABLE |
179 | 179 | ||
180 | config NODES_SHIFT | ||
181 | int | ||
182 | default "3" | ||
183 | depends on NEED_MULTIPLE_NODES | ||
184 | |||
180 | source "kernel/Kconfig.preempt" | 185 | source "kernel/Kconfig.preempt" |
181 | source "kernel/Kconfig.hz" | 186 | source "kernel/Kconfig.hz" |
182 | source "mm/Kconfig" | 187 | source "mm/Kconfig" |
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 47ca5c0a323b..fc107add627c 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c | |||
@@ -31,7 +31,6 @@ | |||
31 | 31 | ||
32 | #include <linux/string.h> | 32 | #include <linux/string.h> |
33 | EXPORT_SYMBOL(memset); | 33 | EXPORT_SYMBOL(memset); |
34 | EXPORT_SYMBOL(strpbrk); | ||
35 | 34 | ||
36 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
37 | EXPORT_SYMBOL(__xchg8); | 36 | EXPORT_SYMBOL(__xchg8); |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2cdc35ce8045..6729c98b66f9 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -366,6 +366,7 @@ config PPC_PMAC64 | |||
366 | select U3_DART | 366 | select U3_DART |
367 | select MPIC_BROKEN_U3 | 367 | select MPIC_BROKEN_U3 |
368 | select GENERIC_TBSYNC | 368 | select GENERIC_TBSYNC |
369 | select PPC_970_NAP | ||
369 | default y | 370 | default y |
370 | 371 | ||
371 | config PPC_PREP | 372 | config PPC_PREP |
@@ -383,6 +384,7 @@ config PPC_MAPLE | |||
383 | select MPIC_BROKEN_U3 | 384 | select MPIC_BROKEN_U3 |
384 | select GENERIC_TBSYNC | 385 | select GENERIC_TBSYNC |
385 | select PPC_UDBG_16550 | 386 | select PPC_UDBG_16550 |
387 | select PPC_970_NAP | ||
386 | default n | 388 | default n |
387 | help | 389 | help |
388 | This option enables support for the Maple 970FX Evaluation Board. | 390 | This option enables support for the Maple 970FX Evaluation Board. |
@@ -457,6 +459,10 @@ config PPC_MPC106 | |||
457 | bool | 459 | bool |
458 | default n | 460 | default n |
459 | 461 | ||
462 | config PPC_970_NAP | ||
463 | bool | ||
464 | default n | ||
465 | |||
460 | source "drivers/cpufreq/Kconfig" | 466 | source "drivers/cpufreq/Kconfig" |
461 | 467 | ||
462 | config CPU_FREQ_PMAC | 468 | config CPU_FREQ_PMAC |
@@ -649,6 +655,11 @@ config NUMA | |||
649 | depends on PPC64 | 655 | depends on PPC64 |
650 | default y if SMP && PPC_PSERIES | 656 | default y if SMP && PPC_PSERIES |
651 | 657 | ||
658 | config NODES_SHIFT | ||
659 | int | ||
660 | default "4" | ||
661 | depends on NEED_MULTIPLE_NODES | ||
662 | |||
652 | config ARCH_SELECT_MEMORY_MODEL | 663 | config ARCH_SELECT_MEMORY_MODEL |
653 | def_bool y | 664 | def_bool y |
654 | depends on PPC64 | 665 | depends on PPC64 |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 6ec84d37a337..ed5b26aa8be3 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -104,6 +104,10 @@ ifndef CONFIG_FSL_BOOKE | |||
104 | CFLAGS += -mstring | 104 | CFLAGS += -mstring |
105 | endif | 105 | endif |
106 | 106 | ||
107 | ifeq ($(CONFIG_6xx),y) | ||
108 | CFLAGS += -mcpu=powerpc | ||
109 | endif | ||
110 | |||
107 | cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge | 111 | cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge |
108 | cpu-as-$(CONFIG_4xx) += -Wa,-m405 | 112 | cpu-as-$(CONFIG_4xx) += -Wa,-m405 |
109 | cpu-as-$(CONFIG_6xx) += -Wa,-maltivec | 113 | cpu-as-$(CONFIG_6xx) += -Wa,-maltivec |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 0cc0995b81b0..803858e86160 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -20,7 +20,7 @@ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ | |||
20 | firmware.o sysfs.o | 20 | firmware.o sysfs.o |
21 | obj-$(CONFIG_PPC64) += vdso64/ | 21 | obj-$(CONFIG_PPC64) += vdso64/ |
22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
23 | obj-$(CONFIG_POWER4) += idle_power4.o | 23 | obj-$(CONFIG_PPC_970_NAP) += idle_power4.o |
24 | obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o | 24 | obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o |
25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o | 25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o |
26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | 26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 54b48f330051..8f85c5e8a55a 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -91,6 +91,7 @@ int main(void) | |||
91 | #endif /* CONFIG_PPC64 */ | 91 | #endif /* CONFIG_PPC64 */ |
92 | 92 | ||
93 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); | 93 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); |
94 | DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); | ||
94 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); | 95 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); |
95 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); | 96 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); |
96 | #ifdef CONFIG_PPC32 | 97 | #ifdef CONFIG_PPC32 |
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index b3a979467225..8866fd26c6b9 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
@@ -128,37 +128,36 @@ transfer_to_handler: | |||
128 | stw r12,4(r11) | 128 | stw r12,4(r11) |
129 | #endif | 129 | #endif |
130 | b 3f | 130 | b 3f |
131 | |||
131 | 2: /* if from kernel, check interrupted DOZE/NAP mode and | 132 | 2: /* if from kernel, check interrupted DOZE/NAP mode and |
132 | * check for stack overflow | 133 | * check for stack overflow |
133 | */ | 134 | */ |
135 | lwz r9,THREAD_INFO-THREAD(r12) | ||
136 | cmplw r1,r9 /* if r1 <= current->thread_info */ | ||
137 | ble- stack_ovf /* then the kernel stack overflowed */ | ||
138 | 5: | ||
134 | #ifdef CONFIG_6xx | 139 | #ifdef CONFIG_6xx |
135 | mfspr r11,SPRN_HID0 | 140 | tophys(r9,r9) /* check local flags */ |
136 | mtcr r11 | 141 | lwz r12,TI_LOCAL_FLAGS(r9) |
137 | BEGIN_FTR_SECTION | 142 | mtcrf 0x01,r12 |
138 | bt- 8,4f /* Check DOZE */ | 143 | bt- 31-TLF_NAPPING,4f |
139 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
140 | BEGIN_FTR_SECTION | ||
141 | bt- 9,4f /* Check NAP */ | ||
142 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
143 | #endif /* CONFIG_6xx */ | 144 | #endif /* CONFIG_6xx */ |
144 | .globl transfer_to_handler_cont | 145 | .globl transfer_to_handler_cont |
145 | transfer_to_handler_cont: | 146 | transfer_to_handler_cont: |
146 | lwz r11,THREAD_INFO-THREAD(r12) | ||
147 | cmplw r1,r11 /* if r1 <= current->thread_info */ | ||
148 | ble- stack_ovf /* then the kernel stack overflowed */ | ||
149 | 3: | 147 | 3: |
150 | mflr r9 | 148 | mflr r9 |
151 | lwz r11,0(r9) /* virtual address of handler */ | 149 | lwz r11,0(r9) /* virtual address of handler */ |
152 | lwz r9,4(r9) /* where to go when done */ | 150 | lwz r9,4(r9) /* where to go when done */ |
153 | FIX_SRR1(r10,r12) | ||
154 | mtspr SPRN_SRR0,r11 | 151 | mtspr SPRN_SRR0,r11 |
155 | mtspr SPRN_SRR1,r10 | 152 | mtspr SPRN_SRR1,r10 |
156 | mtlr r9 | 153 | mtlr r9 |
157 | SYNC | 154 | SYNC |
158 | RFI /* jump to handler, enable MMU */ | 155 | RFI /* jump to handler, enable MMU */ |
159 | 156 | ||
160 | #ifdef CONFIG_6xx | 157 | #ifdef CONFIG_6xx |
161 | 4: b power_save_6xx_restore | 158 | 4: rlwinm r12,r12,0,~_TLF_NAPPING |
159 | stw r12,TI_LOCAL_FLAGS(r9) | ||
160 | b power_save_6xx_restore | ||
162 | #endif | 161 | #endif |
163 | 162 | ||
164 | /* | 163 | /* |
@@ -167,10 +166,10 @@ transfer_to_handler_cont: | |||
167 | */ | 166 | */ |
168 | stack_ovf: | 167 | stack_ovf: |
169 | /* sometimes we use a statically-allocated stack, which is OK. */ | 168 | /* sometimes we use a statically-allocated stack, which is OK. */ |
170 | lis r11,_end@h | 169 | lis r12,_end@h |
171 | ori r11,r11,_end@l | 170 | ori r12,r12,_end@l |
172 | cmplw r1,r11 | 171 | cmplw r1,r12 |
173 | ble 3b /* r1 <= &_end is OK */ | 172 | ble 5b /* r1 <= &_end is OK */ |
174 | SAVE_NVGPRS(r11) | 173 | SAVE_NVGPRS(r11) |
175 | addi r3,r1,STACK_FRAME_OVERHEAD | 174 | addi r3,r1,STACK_FRAME_OVERHEAD |
176 | lis r1,init_thread_union@ha | 175 | lis r1,init_thread_union@ha |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index a5ae04a57c78..b7d140430a41 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -376,11 +376,28 @@ label##_common: \ | |||
376 | bl hdlr; \ | 376 | bl hdlr; \ |
377 | b .ret_from_except | 377 | b .ret_from_except |
378 | 378 | ||
379 | /* | ||
380 | * Like STD_EXCEPTION_COMMON, but for exceptions that can occur | ||
381 | * in the idle task and therefore need the special idle handling. | ||
382 | */ | ||
383 | #define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr) \ | ||
384 | .align 7; \ | ||
385 | .globl label##_common; \ | ||
386 | label##_common: \ | ||
387 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ | ||
388 | FINISH_NAP; \ | ||
389 | DISABLE_INTS; \ | ||
390 | bl .save_nvgprs; \ | ||
391 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | ||
392 | bl hdlr; \ | ||
393 | b .ret_from_except | ||
394 | |||
379 | #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ | 395 | #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ |
380 | .align 7; \ | 396 | .align 7; \ |
381 | .globl label##_common; \ | 397 | .globl label##_common; \ |
382 | label##_common: \ | 398 | label##_common: \ |
383 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ | 399 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ |
400 | FINISH_NAP; \ | ||
384 | DISABLE_INTS; \ | 401 | DISABLE_INTS; \ |
385 | bl .ppc64_runlatch_on; \ | 402 | bl .ppc64_runlatch_on; \ |
386 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 403 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
@@ -388,6 +405,25 @@ label##_common: \ | |||
388 | b .ret_from_except_lite | 405 | b .ret_from_except_lite |
389 | 406 | ||
390 | /* | 407 | /* |
408 | * When the idle code in power4_idle puts the CPU into NAP mode, | ||
409 | * it has to do so in a loop, and relies on the external interrupt | ||
410 | * and decrementer interrupt entry code to get it out of the loop. | ||
411 | * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags | ||
412 | * to signal that it is in the loop and needs help to get out. | ||
413 | */ | ||
414 | #ifdef CONFIG_PPC_970_NAP | ||
415 | #define FINISH_NAP \ | ||
416 | BEGIN_FTR_SECTION \ | ||
417 | clrrdi r11,r1,THREAD_SHIFT; \ | ||
418 | ld r9,TI_LOCAL_FLAGS(r11); \ | ||
419 | andi. r10,r9,_TLF_NAPPING; \ | ||
420 | bnel power4_fixup_nap; \ | ||
421 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
422 | #else | ||
423 | #define FINISH_NAP | ||
424 | #endif | ||
425 | |||
426 | /* | ||
391 | * Start of pSeries system interrupt routines | 427 | * Start of pSeries system interrupt routines |
392 | */ | 428 | */ |
393 | . = 0x100 | 429 | . = 0x100 |
@@ -772,6 +808,7 @@ hardware_interrupt_iSeries_masked: | |||
772 | .globl machine_check_common | 808 | .globl machine_check_common |
773 | machine_check_common: | 809 | machine_check_common: |
774 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) | 810 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) |
811 | FINISH_NAP | ||
775 | DISABLE_INTS | 812 | DISABLE_INTS |
776 | bl .save_nvgprs | 813 | bl .save_nvgprs |
777 | addi r3,r1,STACK_FRAME_OVERHEAD | 814 | addi r3,r1,STACK_FRAME_OVERHEAD |
@@ -783,7 +820,7 @@ machine_check_common: | |||
783 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) | 820 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) |
784 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) | 821 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) |
785 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) | 822 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) |
786 | STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception) | 823 | STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception) |
787 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) | 824 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) |
788 | #ifdef CONFIG_ALTIVEC | 825 | #ifdef CONFIG_ALTIVEC |
789 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) | 826 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) |
@@ -1034,6 +1071,7 @@ unrecov_slb: | |||
1034 | .globl hardware_interrupt_entry | 1071 | .globl hardware_interrupt_entry |
1035 | hardware_interrupt_common: | 1072 | hardware_interrupt_common: |
1036 | EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) | 1073 | EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) |
1074 | FINISH_NAP | ||
1037 | hardware_interrupt_entry: | 1075 | hardware_interrupt_entry: |
1038 | DISABLE_INTS | 1076 | DISABLE_INTS |
1039 | bl .ppc64_runlatch_on | 1077 | bl .ppc64_runlatch_on |
@@ -1041,6 +1079,15 @@ hardware_interrupt_entry: | |||
1041 | bl .do_IRQ | 1079 | bl .do_IRQ |
1042 | b .ret_from_except_lite | 1080 | b .ret_from_except_lite |
1043 | 1081 | ||
1082 | #ifdef CONFIG_PPC_970_NAP | ||
1083 | power4_fixup_nap: | ||
1084 | andc r9,r9,r10 | ||
1085 | std r9,TI_LOCAL_FLAGS(r11) | ||
1086 | ld r10,_LINK(r1) /* make idle task do the */ | ||
1087 | std r10,_NIP(r1) /* equivalent of a blr */ | ||
1088 | blr | ||
1089 | #endif | ||
1090 | |||
1044 | .align 7 | 1091 | .align 7 |
1045 | .globl alignment_common | 1092 | .globl alignment_common |
1046 | alignment_common: | 1093 | alignment_common: |
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index e9f321d74d85..d491052c8e0c 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c | |||
@@ -50,9 +50,9 @@ void cpu_idle(void) | |||
50 | 50 | ||
51 | set_thread_flag(TIF_POLLING_NRFLAG); | 51 | set_thread_flag(TIF_POLLING_NRFLAG); |
52 | while (1) { | 52 | while (1) { |
53 | ppc64_runlatch_off(); | ||
54 | |||
55 | while (!need_resched() && !cpu_should_die()) { | 53 | while (!need_resched() && !cpu_should_die()) { |
54 | ppc64_runlatch_off(); | ||
55 | |||
56 | if (ppc_md.power_save) { | 56 | if (ppc_md.power_save) { |
57 | clear_thread_flag(TIF_POLLING_NRFLAG); | 57 | clear_thread_flag(TIF_POLLING_NRFLAG); |
58 | /* | 58 | /* |
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S index 12a4efbaa08f..b45fa0e37212 100644 --- a/arch/powerpc/kernel/idle_6xx.S +++ b/arch/powerpc/kernel/idle_6xx.S | |||
@@ -22,8 +22,6 @@ | |||
22 | #include <asm/ppc_asm.h> | 22 | #include <asm/ppc_asm.h> |
23 | #include <asm/asm-offsets.h> | 23 | #include <asm/asm-offsets.h> |
24 | 24 | ||
25 | #undef DEBUG | ||
26 | |||
27 | .text | 25 | .text |
28 | 26 | ||
29 | /* | 27 | /* |
@@ -109,12 +107,6 @@ BEGIN_FTR_SECTION | |||
109 | dcbf 0,r4 | 107 | dcbf 0,r4 |
110 | dcbf 0,r4 | 108 | dcbf 0,r4 |
111 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) | 109 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) |
112 | #ifdef DEBUG | ||
113 | lis r6,nap_enter_count@ha | ||
114 | lwz r4,nap_enter_count@l(r6) | ||
115 | addi r4,r4,1 | ||
116 | stw r4,nap_enter_count@l(r6) | ||
117 | #endif | ||
118 | 2: | 110 | 2: |
119 | BEGIN_FTR_SECTION | 111 | BEGIN_FTR_SECTION |
120 | /* Go to low speed mode on some 750FX */ | 112 | /* Go to low speed mode on some 750FX */ |
@@ -144,48 +136,42 @@ BEGIN_FTR_SECTION | |||
144 | DSSALL | 136 | DSSALL |
145 | sync | 137 | sync |
146 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 138 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
139 | rlwinm r9,r1,0,0,31-THREAD_SHIFT /* current thread_info */ | ||
140 | lwz r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ | ||
141 | ori r8,r8,_TLF_NAPPING /* so when we take an exception */ | ||
142 | stw r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ | ||
147 | mfmsr r7 | 143 | mfmsr r7 |
148 | ori r7,r7,MSR_EE | 144 | ori r7,r7,MSR_EE |
149 | oris r7,r7,MSR_POW@h | 145 | oris r7,r7,MSR_POW@h |
150 | sync | 146 | 1: sync |
151 | isync | ||
152 | mtmsr r7 | 147 | mtmsr r7 |
153 | isync | 148 | isync |
154 | sync | 149 | b 1b |
155 | blr | 150 | |
156 | |||
157 | /* | 151 | /* |
158 | * Return from NAP/DOZE mode, restore some CPU specific registers, | 152 | * Return from NAP/DOZE mode, restore some CPU specific registers, |
159 | * we are called with DR/IR still off and r2 containing physical | 153 | * we are called with DR/IR still off and r2 containing physical |
160 | * address of current. | 154 | * address of current. R11 points to the exception frame (physical |
155 | * address). We have to preserve r10. | ||
161 | */ | 156 | */ |
162 | _GLOBAL(power_save_6xx_restore) | 157 | _GLOBAL(power_save_6xx_restore) |
163 | mfspr r11,SPRN_HID0 | 158 | lwz r9,_LINK(r11) /* interrupted in ppc6xx_idle: */ |
164 | rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */ | 159 | stw r9,_NIP(r11) /* make it do a blr */ |
165 | cror 4*cr1+eq,4*cr0+eq,4*cr0+eq | ||
166 | BEGIN_FTR_SECTION | ||
167 | rlwinm r11,r11,0,9,7 /* Clear DOZE */ | ||
168 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
169 | mtspr SPRN_HID0, r11 | ||
170 | 160 | ||
171 | #ifdef DEBUG | 161 | #ifdef CONFIG_SMP |
172 | beq cr1,1f | 162 | mfspr r12,SPRN_SPRG3 |
173 | lis r11,(nap_return_count-KERNELBASE)@ha | 163 | lwz r11,TI_CPU(r12) /* get cpu number * 4 */ |
174 | lwz r9,nap_return_count@l(r11) | ||
175 | addi r9,r9,1 | ||
176 | stw r9,nap_return_count@l(r11) | ||
177 | 1: | ||
178 | #endif | ||
179 | |||
180 | rlwinm r9,r1,0,0,18 | ||
181 | tophys(r9,r9) | ||
182 | lwz r11,TI_CPU(r9) | ||
183 | slwi r11,r11,2 | 164 | slwi r11,r11,2 |
165 | #else | ||
166 | li r11,0 | ||
167 | #endif | ||
184 | /* Todo make sure all these are in the same page | 168 | /* Todo make sure all these are in the same page |
185 | * and load r22 (@ha part + CPU offset) only once | 169 | * and load r11 (@ha part + CPU offset) only once |
186 | */ | 170 | */ |
187 | BEGIN_FTR_SECTION | 171 | BEGIN_FTR_SECTION |
188 | beq cr1,1f | 172 | mfspr r9,SPRN_HID0 |
173 | andis. r9,r9,HID0_NAP@h | ||
174 | beq 1f | ||
189 | addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha | 175 | addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha |
190 | lwz r9,nap_save_msscr0@l(r9) | 176 | lwz r9,nap_save_msscr0@l(r9) |
191 | mtspr SPRN_MSSCR0, r9 | 177 | mtspr SPRN_MSSCR0, r9 |
@@ -210,10 +196,3 @@ _GLOBAL(nap_save_hid1) | |||
210 | 196 | ||
211 | _GLOBAL(powersave_lowspeed) | 197 | _GLOBAL(powersave_lowspeed) |
212 | .long 0 | 198 | .long 0 |
213 | |||
214 | #ifdef DEBUG | ||
215 | _GLOBAL(nap_enter_count) | ||
216 | .space 4 | ||
217 | _GLOBAL(nap_return_count) | ||
218 | .space 4 | ||
219 | #endif | ||
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index 6dad1c02496e..d85c7c938eed 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S | |||
@@ -35,12 +35,16 @@ BEGIN_FTR_SECTION | |||
35 | DSSALL | 35 | DSSALL |
36 | sync | 36 | sync |
37 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 37 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
38 | clrrdi r9,r1,THREAD_SHIFT /* current thread_info */ | ||
39 | ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ | ||
40 | ori r8,r8,_TLF_NAPPING /* so when we take an exception */ | ||
41 | std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ | ||
38 | mfmsr r7 | 42 | mfmsr r7 |
39 | ori r7,r7,MSR_EE | 43 | ori r7,r7,MSR_EE |
40 | oris r7,r7,MSR_POW@h | 44 | oris r7,r7,MSR_POW@h |
41 | sync | 45 | 1: sync |
42 | isync | 46 | isync |
43 | mtmsrd r7 | 47 | mtmsrd r7 |
44 | isync | 48 | isync |
45 | sync | 49 | b 1b |
46 | blr | 50 | |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index bb5c9501234c..57d560c68897 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -272,18 +272,26 @@ unsigned int virt_irq_to_real_map[NR_IRQS]; | |||
272 | * Don't use virtual irqs 0, 1, 2 for devices. | 272 | * Don't use virtual irqs 0, 1, 2 for devices. |
273 | * The pcnet32 driver considers interrupt numbers < 2 to be invalid, | 273 | * The pcnet32 driver considers interrupt numbers < 2 to be invalid, |
274 | * and 2 is the XICS IPI interrupt. | 274 | * and 2 is the XICS IPI interrupt. |
275 | * We limit virtual irqs to 17 less than NR_IRQS so that when we | 275 | * We limit virtual irqs to __irq_offet_value less than virt_irq_max so |
276 | * offset them by 16 (to reserve the first 16 for ISA interrupts) | 276 | * that when we offset them we don't end up with an interrupt |
277 | * we don't end up with an interrupt number >= NR_IRQS. | 277 | * number >= virt_irq_max. |
278 | */ | 278 | */ |
279 | #define MIN_VIRT_IRQ 3 | 279 | #define MIN_VIRT_IRQ 3 |
280 | #define MAX_VIRT_IRQ (NR_IRQS - NUM_ISA_INTERRUPTS - 1) | 280 | |
281 | #define NR_VIRT_IRQS (MAX_VIRT_IRQ - MIN_VIRT_IRQ + 1) | 281 | unsigned int virt_irq_max; |
282 | static unsigned int max_virt_irq; | ||
283 | static unsigned int nr_virt_irqs; | ||
282 | 284 | ||
283 | void | 285 | void |
284 | virt_irq_init(void) | 286 | virt_irq_init(void) |
285 | { | 287 | { |
286 | int i; | 288 | int i; |
289 | |||
290 | if ((virt_irq_max == 0) || (virt_irq_max > (NR_IRQS - 1))) | ||
291 | virt_irq_max = NR_IRQS - 1; | ||
292 | max_virt_irq = virt_irq_max - __irq_offset_value; | ||
293 | nr_virt_irqs = max_virt_irq - MIN_VIRT_IRQ + 1; | ||
294 | |||
287 | for (i = 0; i < NR_IRQS; i++) | 295 | for (i = 0; i < NR_IRQS; i++) |
288 | virt_irq_to_real_map[i] = UNDEFINED_IRQ; | 296 | virt_irq_to_real_map[i] = UNDEFINED_IRQ; |
289 | } | 297 | } |
@@ -308,17 +316,17 @@ int virt_irq_create_mapping(unsigned int real_irq) | |||
308 | return real_irq; | 316 | return real_irq; |
309 | } | 317 | } |
310 | 318 | ||
311 | /* map to a number between MIN_VIRT_IRQ and MAX_VIRT_IRQ */ | 319 | /* map to a number between MIN_VIRT_IRQ and max_virt_irq */ |
312 | virq = real_irq; | 320 | virq = real_irq; |
313 | if (virq > MAX_VIRT_IRQ) | 321 | if (virq > max_virt_irq) |
314 | virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ; | 322 | virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ; |
315 | 323 | ||
316 | /* search for this number or a free slot */ | 324 | /* search for this number or a free slot */ |
317 | first_virq = virq; | 325 | first_virq = virq; |
318 | while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) { | 326 | while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) { |
319 | if (virt_irq_to_real_map[virq] == real_irq) | 327 | if (virt_irq_to_real_map[virq] == real_irq) |
320 | return virq; | 328 | return virq; |
321 | if (++virq > MAX_VIRT_IRQ) | 329 | if (++virq > max_virt_irq) |
322 | virq = MIN_VIRT_IRQ; | 330 | virq = MIN_VIRT_IRQ; |
323 | if (virq == first_virq) | 331 | if (virq == first_virq) |
324 | goto nospace; /* oops, no free slots */ | 332 | goto nospace; /* oops, no free slots */ |
@@ -330,8 +338,8 @@ int virt_irq_create_mapping(unsigned int real_irq) | |||
330 | nospace: | 338 | nospace: |
331 | if (!warned) { | 339 | if (!warned) { |
332 | printk(KERN_CRIT "Interrupt table is full\n"); | 340 | printk(KERN_CRIT "Interrupt table is full\n"); |
333 | printk(KERN_CRIT "Increase NR_IRQS (currently %d) " | 341 | printk(KERN_CRIT "Increase virt_irq_max (currently %d) " |
334 | "in your kernel sources and rebuild.\n", NR_IRQS); | 342 | "in your kernel sources and rebuild.\n", virt_irq_max); |
335 | warned = 1; | 343 | warned = 1; |
336 | } | 344 | } |
337 | return NO_IRQ; | 345 | return NO_IRQ; |
@@ -349,8 +357,8 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) | |||
349 | 357 | ||
350 | virq = real_irq; | 358 | virq = real_irq; |
351 | 359 | ||
352 | if (virq > MAX_VIRT_IRQ) | 360 | if (virq > max_virt_irq) |
353 | virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ; | 361 | virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ; |
354 | 362 | ||
355 | first_virq = virq; | 363 | first_virq = virq; |
356 | 364 | ||
@@ -360,7 +368,7 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) | |||
360 | 368 | ||
361 | virq++; | 369 | virq++; |
362 | 370 | ||
363 | if (virq >= MAX_VIRT_IRQ) | 371 | if (virq >= max_virt_irq) |
364 | virq = 0; | 372 | virq = 0; |
365 | 373 | ||
366 | } while (first_virq != virq); | 374 | } while (first_virq != virq); |
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index ad7a90212204..856ef1a832b9 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c | |||
@@ -88,7 +88,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) | |||
88 | mutex_unlock(&kprobe_mutex); | 88 | mutex_unlock(&kprobe_mutex); |
89 | } | 89 | } |
90 | 90 | ||
91 | static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 91 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) |
92 | { | 92 | { |
93 | kprobe_opcode_t insn = *p->ainsn.insn; | 93 | kprobe_opcode_t insn = *p->ainsn.insn; |
94 | 94 | ||
@@ -101,21 +101,21 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | |||
101 | regs->nip = (unsigned long)p->ainsn.insn; | 101 | regs->nip = (unsigned long)p->ainsn.insn; |
102 | } | 102 | } |
103 | 103 | ||
104 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 104 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
105 | { | 105 | { |
106 | kcb->prev_kprobe.kp = kprobe_running(); | 106 | kcb->prev_kprobe.kp = kprobe_running(); |
107 | kcb->prev_kprobe.status = kcb->kprobe_status; | 107 | kcb->prev_kprobe.status = kcb->kprobe_status; |
108 | kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr; | 108 | kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr; |
109 | } | 109 | } |
110 | 110 | ||
111 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 111 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
112 | { | 112 | { |
113 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | 113 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
114 | kcb->kprobe_status = kcb->prev_kprobe.status; | 114 | kcb->kprobe_status = kcb->prev_kprobe.status; |
115 | kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr; | 115 | kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr; |
116 | } | 116 | } |
117 | 117 | ||
118 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | 118 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
119 | struct kprobe_ctlblk *kcb) | 119 | struct kprobe_ctlblk *kcb) |
120 | { | 120 | { |
121 | __get_cpu_var(current_kprobe) = p; | 121 | __get_cpu_var(current_kprobe) = p; |
@@ -141,7 +141,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, | |||
141 | } | 141 | } |
142 | } | 142 | } |
143 | 143 | ||
144 | static inline int kprobe_handler(struct pt_regs *regs) | 144 | static int __kprobes kprobe_handler(struct pt_regs *regs) |
145 | { | 145 | { |
146 | struct kprobe *p; | 146 | struct kprobe *p; |
147 | int ret = 0; | 147 | int ret = 0; |
@@ -334,7 +334,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) | |||
334 | regs->nip = (unsigned long)p->addr + 4; | 334 | regs->nip = (unsigned long)p->addr + 4; |
335 | } | 335 | } |
336 | 336 | ||
337 | static inline int post_kprobe_handler(struct pt_regs *regs) | 337 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) |
338 | { | 338 | { |
339 | struct kprobe *cur = kprobe_running(); | 339 | struct kprobe *cur = kprobe_running(); |
340 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 340 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -370,7 +370,7 @@ out: | |||
370 | return 1; | 370 | return 1; |
371 | } | 371 | } |
372 | 372 | ||
373 | static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 373 | static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
374 | { | 374 | { |
375 | struct kprobe *cur = kprobe_running(); | 375 | struct kprobe *cur = kprobe_running(); |
376 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 376 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index d66c5e77fcff..7e4d54821a07 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -1528,12 +1528,11 @@ static int __init prom_find_machine_type(void) | |||
1528 | * non-IBM designs ! | 1528 | * non-IBM designs ! |
1529 | * - it has /rtas | 1529 | * - it has /rtas |
1530 | */ | 1530 | */ |
1531 | len = prom_getprop(_prom->root, "model", | 1531 | len = prom_getprop(_prom->root, "device_type", |
1532 | compat, sizeof(compat)-1); | 1532 | compat, sizeof(compat)-1); |
1533 | if (len <= 0) | 1533 | if (len <= 0) |
1534 | return PLATFORM_GENERIC; | 1534 | return PLATFORM_GENERIC; |
1535 | compat[len] = 0; | 1535 | if (strncmp(compat, RELOC("chrp"), 4)) |
1536 | if (strcmp(compat, "chrp")) | ||
1537 | return PLATFORM_GENERIC; | 1536 | return PLATFORM_GENERIC; |
1538 | 1537 | ||
1539 | /* Default to pSeries. We need to know if we are running LPAR */ | 1538 | /* Default to pSeries. We need to know if we are running LPAR */ |
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 456286cf1d14..9c9ad1fa9cce 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c | |||
@@ -258,11 +258,11 @@ static int __init proc_rtas_init(void) | |||
258 | struct proc_dir_entry *entry; | 258 | struct proc_dir_entry *entry; |
259 | 259 | ||
260 | if (!machine_is(pseries)) | 260 | if (!machine_is(pseries)) |
261 | return 1; | 261 | return -ENODEV; |
262 | 262 | ||
263 | rtas_node = of_find_node_by_name(NULL, "rtas"); | 263 | rtas_node = of_find_node_by_name(NULL, "rtas"); |
264 | if (rtas_node == NULL) | 264 | if (rtas_node == NULL) |
265 | return 1; | 265 | return -ENODEV; |
266 | 266 | ||
267 | entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL); | 267 | entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL); |
268 | if (entry) | 268 | if (entry) |
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index 1424eab450ee..a14c96403840 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S | |||
@@ -323,3 +323,4 @@ COMPAT_SYS(pselect6) | |||
323 | COMPAT_SYS(ppoll) | 323 | COMPAT_SYS(ppoll) |
324 | SYSCALL(unshare) | 324 | SYSCALL(unshare) |
325 | SYSCALL(splice) | 325 | SYSCALL(splice) |
326 | SYSCALL(tee) | ||
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 97898d5d34e5..1726bfe38ee0 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c | |||
@@ -1297,7 +1297,7 @@ static inline void setup_decr(struct spu_state *csa, struct spu *spu) | |||
1297 | cycles_t resume_time = get_cycles(); | 1297 | cycles_t resume_time = get_cycles(); |
1298 | cycles_t delta_time = resume_time - csa->suspend_time; | 1298 | cycles_t delta_time = resume_time - csa->suspend_time; |
1299 | 1299 | ||
1300 | csa->lscsa->decr.slot[0] = delta_time; | 1300 | csa->lscsa->decr.slot[0] -= delta_time; |
1301 | } | 1301 | } |
1302 | } | 1302 | } |
1303 | 1303 | ||
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h index 63f0aee4c158..996c28744e96 100644 --- a/arch/powerpc/platforms/chrp/chrp.h +++ b/arch/powerpc/platforms/chrp/chrp.h | |||
@@ -9,3 +9,4 @@ extern long chrp_time_init(void); | |||
9 | 9 | ||
10 | extern void chrp_find_bridges(void); | 10 | extern void chrp_find_bridges(void); |
11 | extern void chrp_event_scan(unsigned long); | 11 | extern void chrp_event_scan(unsigned long); |
12 | extern void chrp_pcibios_fixup(void); | ||
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 8ef279ad36ad..ac224876ce59 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <asm/grackle.h> | 23 | #include <asm/grackle.h> |
24 | #include <asm/rtas.h> | 24 | #include <asm/rtas.h> |
25 | 25 | ||
26 | #include "chrp.h" | ||
27 | |||
26 | /* LongTrail */ | 28 | /* LongTrail */ |
27 | void __iomem *gg2_pci_config_base; | 29 | void __iomem *gg2_pci_config_base; |
28 | 30 | ||
@@ -314,6 +316,6 @@ chrp_find_bridges(void) | |||
314 | } | 316 | } |
315 | 317 | ||
316 | /* Do not fixup interrupts from OF tree on pegasos */ | 318 | /* Do not fixup interrupts from OF tree on pegasos */ |
317 | if (is_pegasos == 0) | 319 | if (is_pegasos) |
318 | ppc_md.pcibios_fixup = chrp_pcibios_fixup; | 320 | ppc_md.pcibios_fixup = NULL; |
319 | } | 321 | } |
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 23a201718704..18d89f38796b 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
@@ -440,8 +440,6 @@ void __init chrp_init_IRQ(void) | |||
440 | 440 | ||
441 | if (_chrp_type == _CHRP_Pegasos) | 441 | if (_chrp_type == _CHRP_Pegasos) |
442 | ppc_md.get_irq = i8259_irq; | 442 | ppc_md.get_irq = i8259_irq; |
443 | else | ||
444 | ppc_md.get_irq = mpic_get_irq; | ||
445 | 443 | ||
446 | #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) | 444 | #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) |
447 | /* see if there is a keyboard in the device tree | 445 | /* see if there is a keyboard in the device tree |
@@ -528,26 +526,24 @@ static int __init chrp_probe(void) | |||
528 | /* Assume we have an 8259... */ | 526 | /* Assume we have an 8259... */ |
529 | __irq_offset_value = NUM_ISA_INTERRUPTS; | 527 | __irq_offset_value = NUM_ISA_INTERRUPTS; |
530 | 528 | ||
531 | ppc_md.setup_arch = chrp_setup_arch; | 529 | return 1; |
532 | ppc_md.show_cpuinfo = chrp_show_cpuinfo; | ||
533 | |||
534 | ppc_md.init_IRQ = chrp_init_IRQ; | ||
535 | ppc_md.init = chrp_init2; | ||
536 | |||
537 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | ||
538 | |||
539 | ppc_md.restart = rtas_restart; | ||
540 | ppc_md.power_off = rtas_power_off; | ||
541 | ppc_md.halt = rtas_halt; | ||
542 | |||
543 | ppc_md.time_init = chrp_time_init; | ||
544 | ppc_md.calibrate_decr = generic_calibrate_decr; | ||
545 | |||
546 | /* this may get overridden with rtas routines later... */ | ||
547 | ppc_md.set_rtc_time = chrp_set_rtc_time; | ||
548 | ppc_md.get_rtc_time = chrp_get_rtc_time; | ||
549 | |||
550 | #ifdef CONFIG_SMP | ||
551 | smp_ops = &chrp_smp_ops; | ||
552 | #endif /* CONFIG_SMP */ | ||
553 | } | 530 | } |
531 | |||
532 | define_machine(chrp) { | ||
533 | .name = "CHRP", | ||
534 | .probe = chrp_probe, | ||
535 | .setup_arch = chrp_setup_arch, | ||
536 | .init = chrp_init2, | ||
537 | .show_cpuinfo = chrp_show_cpuinfo, | ||
538 | .init_IRQ = chrp_init_IRQ, | ||
539 | .get_irq = mpic_get_irq, | ||
540 | .pcibios_fixup = chrp_pcibios_fixup, | ||
541 | .restart = rtas_restart, | ||
542 | .power_off = rtas_power_off, | ||
543 | .halt = rtas_halt, | ||
544 | .time_init = chrp_time_init, | ||
545 | .set_rtc_time = chrp_set_rtc_time, | ||
546 | .get_rtc_time = chrp_get_rtc_time, | ||
547 | .calibrate_decr = generic_calibrate_decr, | ||
548 | .phys_mem_access_prot = pci_phys_mem_access_prot, | ||
549 | }; | ||
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 6ce8a404ba6b..a6fd9bedb074 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <asm/iseries/hv_lp_event.h> | 54 | #include <asm/iseries/hv_lp_event.h> |
55 | #include <asm/iseries/lpar_map.h> | 55 | #include <asm/iseries/lpar_map.h> |
56 | #include <asm/udbg.h> | 56 | #include <asm/udbg.h> |
57 | #include <asm/irq.h> | ||
57 | 58 | ||
58 | #include "naca.h" | 59 | #include "naca.h" |
59 | #include "setup.h" | 60 | #include "setup.h" |
@@ -684,6 +685,12 @@ static int __init iseries_probe(void) | |||
684 | powerpc_firmware_features |= FW_FEATURE_ISERIES; | 685 | powerpc_firmware_features |= FW_FEATURE_ISERIES; |
685 | powerpc_firmware_features |= FW_FEATURE_LPAR; | 686 | powerpc_firmware_features |= FW_FEATURE_LPAR; |
686 | 687 | ||
688 | /* | ||
689 | * The Hypervisor only allows us up to 256 interrupt | ||
690 | * sources (the irq number is passed in a u8). | ||
691 | */ | ||
692 | virt_irq_max = 255; | ||
693 | |||
687 | return 1; | 694 | return 1; |
688 | } | 695 | } |
689 | 696 | ||
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 780fb27a0099..32eaddfa5470 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -957,8 +957,10 @@ static void eeh_remove_device(struct pci_dev *dev) | |||
957 | pci_addr_cache_remove_device(dev); | 957 | pci_addr_cache_remove_device(dev); |
958 | 958 | ||
959 | dn = pci_device_to_OF_node(dev); | 959 | dn = pci_device_to_OF_node(dev); |
960 | PCI_DN(dn)->pcidev = NULL; | 960 | if (PCI_DN(dn)->pcidev) { |
961 | pci_dev_put (dev); | 961 | PCI_DN(dn)->pcidev = NULL; |
962 | pci_dev_put (dev); | ||
963 | } | ||
962 | } | 964 | } |
963 | 965 | ||
964 | void eeh_remove_bus_device(struct pci_dev *dev) | 966 | void eeh_remove_bus_device(struct pci_dev *dev) |
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c index fcc4d561a236..e0000ce769e5 100644 --- a/arch/powerpc/platforms/pseries/rtasd.c +++ b/arch/powerpc/platforms/pseries/rtasd.c | |||
@@ -488,7 +488,7 @@ static int __init rtas_init(void) | |||
488 | /* No RTAS */ | 488 | /* No RTAS */ |
489 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { | 489 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { |
490 | printk(KERN_INFO "rtasd: no event-scan on system\n"); | 490 | printk(KERN_INFO "rtasd: no event-scan on system\n"); |
491 | return 1; | 491 | return -ENODEV; |
492 | } | 492 | } |
493 | 493 | ||
494 | entry = create_proc_entry("ppc64/rtas/error_log", S_IRUSR, NULL); | 494 | entry = create_proc_entry("ppc64/rtas/error_log", S_IRUSR, NULL); |
diff --git a/arch/ppc/boot/lib/Makefile b/arch/ppc/boot/lib/Makefile index d4077e69086f..80c84d562fa4 100644 --- a/arch/ppc/boot/lib/Makefile +++ b/arch/ppc/boot/lib/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | CFLAGS_kbd.o := -Idrivers/char | 5 | CFLAGS_kbd.o := -Idrivers/char |
6 | CFLAGS_vreset.o := -I$(srctree)/arch/ppc/boot/include | 6 | CFLAGS_vreset.o := -Iarch/ppc/boot/include |
7 | 7 | ||
8 | zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c | 8 | zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c |
9 | 9 | ||
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c index 60c724e11584..7662c4e6e7d6 100644 --- a/arch/ppc/syslib/ppc_sys.c +++ b/arch/ppc/syslib/ppc_sys.c | |||
@@ -156,12 +156,13 @@ void platform_notify_map(const struct platform_notify_dev_map *map, | |||
156 | while (map->bus_id != NULL) { | 156 | while (map->bus_id != NULL) { |
157 | idx = -1; | 157 | idx = -1; |
158 | s = strrchr(dev->bus_id, '.'); | 158 | s = strrchr(dev->bus_id, '.'); |
159 | if (s != NULL) | 159 | if (s != NULL) { |
160 | idx = (int)simple_strtol(s + 1, NULL, 10); | 160 | idx = (int)simple_strtol(s + 1, NULL, 10); |
161 | else | 161 | len = s - dev->bus_id; |
162 | } else { | ||
162 | s = dev->bus_id; | 163 | s = dev->bus_id; |
163 | 164 | len = strlen(dev->bus_id); | |
164 | len = s - dev->bus_id; | 165 | } |
165 | 166 | ||
166 | if (!strncmp(dev->bus_id, map->bus_id, len)) { | 167 | if (!strncmp(dev->bus_id, map->bus_id, len)) { |
167 | pdev = container_of(dev, struct platform_device, dev); | 168 | pdev = container_of(dev, struct platform_device, dev); |
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 6c6b197898d0..7bb16fb97d4f 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
@@ -67,7 +67,6 @@ cflags-$(CONFIG_WARN_STACK) += -mwarn-framesize=$(CONFIG_WARN_STACK_SIZE) | |||
67 | endif | 67 | endif |
68 | 68 | ||
69 | CFLAGS += -mbackchain -msoft-float $(cflags-y) | 69 | CFLAGS += -mbackchain -msoft-float $(cflags-y) |
70 | CFLAGS += $(call cc-option,-finline-limit=10000) | ||
71 | CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare | 70 | CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare |
72 | AFLAGS += $(aflags-y) | 71 | AFLAGS += $(aflags-y) |
73 | 72 | ||
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index f8d0cd540a06..f4dfc10026d2 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -1,10 +1,11 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16-rc2 | 3 | # Linux kernel version: 2.6.17-rc1 |
4 | # Wed Feb 8 10:44:39 2006 | 4 | # Mon Apr 3 14:34:15 2006 |
5 | # | 5 | # |
6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
8 | CONFIG_GENERIC_HWEIGHT=y | ||
8 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 9 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
9 | CONFIG_S390=y | 10 | CONFIG_S390=y |
10 | 11 | ||
@@ -30,8 +31,8 @@ CONFIG_AUDIT=y | |||
30 | CONFIG_IKCONFIG=y | 31 | CONFIG_IKCONFIG=y |
31 | CONFIG_IKCONFIG_PROC=y | 32 | CONFIG_IKCONFIG_PROC=y |
32 | # CONFIG_CPUSETS is not set | 33 | # CONFIG_CPUSETS is not set |
34 | # CONFIG_RELAY is not set | ||
33 | CONFIG_INITRAMFS_SOURCE="" | 35 | CONFIG_INITRAMFS_SOURCE="" |
34 | CONFIG_UID16=y | ||
35 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 36 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
36 | # CONFIG_EMBEDDED is not set | 37 | # CONFIG_EMBEDDED is not set |
37 | CONFIG_KALLSYMS=y | 38 | CONFIG_KALLSYMS=y |
@@ -45,10 +46,6 @@ CONFIG_BASE_FULL=y | |||
45 | CONFIG_FUTEX=y | 46 | CONFIG_FUTEX=y |
46 | CONFIG_EPOLL=y | 47 | CONFIG_EPOLL=y |
47 | CONFIG_SHMEM=y | 48 | CONFIG_SHMEM=y |
48 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
49 | CONFIG_CC_ALIGN_LABELS=0 | ||
50 | CONFIG_CC_ALIGN_LOOPS=0 | ||
51 | CONFIG_CC_ALIGN_JUMPS=0 | ||
52 | CONFIG_SLAB=y | 49 | CONFIG_SLAB=y |
53 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
54 | CONFIG_BASE_SMALL=0 | 51 | CONFIG_BASE_SMALL=0 |
@@ -60,7 +57,6 @@ CONFIG_BASE_SMALL=0 | |||
60 | CONFIG_MODULES=y | 57 | CONFIG_MODULES=y |
61 | CONFIG_MODULE_UNLOAD=y | 58 | CONFIG_MODULE_UNLOAD=y |
62 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 59 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
63 | CONFIG_OBSOLETE_MODPARM=y | ||
64 | CONFIG_MODVERSIONS=y | 60 | CONFIG_MODVERSIONS=y |
65 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 61 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
66 | CONFIG_KMOD=y | 62 | CONFIG_KMOD=y |
@@ -69,7 +65,7 @@ CONFIG_STOP_MACHINE=y | |||
69 | # | 65 | # |
70 | # Block layer | 66 | # Block layer |
71 | # | 67 | # |
72 | # CONFIG_LBD is not set | 68 | # CONFIG_BLK_DEV_IO_TRACE is not set |
73 | 69 | ||
74 | # | 70 | # |
75 | # IO Schedulers | 71 | # IO Schedulers |
@@ -91,17 +87,20 @@ CONFIG_DEFAULT_IOSCHED="deadline" | |||
91 | # | 87 | # |
92 | # Processor type and features | 88 | # Processor type and features |
93 | # | 89 | # |
94 | # CONFIG_64BIT is not set | 90 | CONFIG_64BIT=y |
95 | CONFIG_SMP=y | 91 | CONFIG_SMP=y |
96 | CONFIG_NR_CPUS=32 | 92 | CONFIG_NR_CPUS=32 |
97 | CONFIG_HOTPLUG_CPU=y | 93 | CONFIG_HOTPLUG_CPU=y |
98 | CONFIG_MATHEMU=y | 94 | CONFIG_DEFAULT_MIGRATION_COST=1000000 |
95 | CONFIG_COMPAT=y | ||
96 | CONFIG_SYSVIPC_COMPAT=y | ||
97 | CONFIG_BINFMT_ELF32=y | ||
99 | 98 | ||
100 | # | 99 | # |
101 | # Code generation options | 100 | # Code generation options |
102 | # | 101 | # |
103 | CONFIG_MARCH_G5=y | 102 | # CONFIG_MARCH_G5 is not set |
104 | # CONFIG_MARCH_Z900 is not set | 103 | CONFIG_MARCH_Z900=y |
105 | # CONFIG_MARCH_Z990 is not set | 104 | # CONFIG_MARCH_Z990 is not set |
106 | CONFIG_PACK_STACK=y | 105 | CONFIG_PACK_STACK=y |
107 | # CONFIG_SMALL_STACK is not set | 106 | # CONFIG_SMALL_STACK is not set |
@@ -143,7 +142,7 @@ CONFIG_VIRT_CPU_ACCOUNTING=y | |||
143 | # CONFIG_APPLDATA_BASE is not set | 142 | # CONFIG_APPLDATA_BASE is not set |
144 | CONFIG_NO_IDLE_HZ=y | 143 | CONFIG_NO_IDLE_HZ=y |
145 | CONFIG_NO_IDLE_HZ_INIT=y | 144 | CONFIG_NO_IDLE_HZ_INIT=y |
146 | # CONFIG_KEXEC is not set | 145 | CONFIG_KEXEC=y |
147 | 146 | ||
148 | # | 147 | # |
149 | # Networking | 148 | # Networking |
@@ -173,6 +172,7 @@ CONFIG_IP_FIB_HASH=y | |||
173 | # CONFIG_INET_AH is not set | 172 | # CONFIG_INET_AH is not set |
174 | # CONFIG_INET_ESP is not set | 173 | # CONFIG_INET_ESP is not set |
175 | # CONFIG_INET_IPCOMP is not set | 174 | # CONFIG_INET_IPCOMP is not set |
175 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
176 | # CONFIG_INET_TUNNEL is not set | 176 | # CONFIG_INET_TUNNEL is not set |
177 | CONFIG_INET_DIAG=y | 177 | CONFIG_INET_DIAG=y |
178 | CONFIG_INET_TCP_DIAG=y | 178 | CONFIG_INET_TCP_DIAG=y |
@@ -180,9 +180,11 @@ CONFIG_INET_TCP_DIAG=y | |||
180 | CONFIG_TCP_CONG_BIC=y | 180 | CONFIG_TCP_CONG_BIC=y |
181 | CONFIG_IPV6=y | 181 | CONFIG_IPV6=y |
182 | # CONFIG_IPV6_PRIVACY is not set | 182 | # CONFIG_IPV6_PRIVACY is not set |
183 | # CONFIG_IPV6_ROUTER_PREF is not set | ||
183 | # CONFIG_INET6_AH is not set | 184 | # CONFIG_INET6_AH is not set |
184 | # CONFIG_INET6_ESP is not set | 185 | # CONFIG_INET6_ESP is not set |
185 | # CONFIG_INET6_IPCOMP is not set | 186 | # CONFIG_INET6_IPCOMP is not set |
187 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
186 | # CONFIG_INET6_TUNNEL is not set | 188 | # CONFIG_INET6_TUNNEL is not set |
187 | # CONFIG_IPV6_TUNNEL is not set | 189 | # CONFIG_IPV6_TUNNEL is not set |
188 | # CONFIG_NETFILTER is not set | 190 | # CONFIG_NETFILTER is not set |
@@ -276,6 +278,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y | |||
276 | # CONFIG_DEBUG_DRIVER is not set | 278 | # CONFIG_DEBUG_DRIVER is not set |
277 | 279 | ||
278 | # | 280 | # |
281 | # Connector - unified userspace <-> kernelspace linker | ||
282 | # | ||
283 | # CONFIG_CONNECTOR is not set | ||
284 | |||
285 | # | ||
279 | # SCSI device support | 286 | # SCSI device support |
280 | # | 287 | # |
281 | # CONFIG_RAID_ATTRS is not set | 288 | # CONFIG_RAID_ATTRS is not set |
@@ -340,8 +347,7 @@ CONFIG_DASD_PROFILE=y | |||
340 | CONFIG_DASD_ECKD=y | 347 | CONFIG_DASD_ECKD=y |
341 | CONFIG_DASD_FBA=y | 348 | CONFIG_DASD_FBA=y |
342 | CONFIG_DASD_DIAG=y | 349 | CONFIG_DASD_DIAG=y |
343 | CONFIG_DASD_EER=m | 350 | CONFIG_DASD_EER=y |
344 | # CONFIG_DASD_CMB is not set | ||
345 | # CONFIG_ATA_OVER_ETH is not set | 351 | # CONFIG_ATA_OVER_ETH is not set |
346 | 352 | ||
347 | # | 353 | # |
@@ -354,6 +360,7 @@ CONFIG_MD_RAID0=m | |||
354 | CONFIG_MD_RAID1=m | 360 | CONFIG_MD_RAID1=m |
355 | # CONFIG_MD_RAID10 is not set | 361 | # CONFIG_MD_RAID10 is not set |
356 | CONFIG_MD_RAID5=m | 362 | CONFIG_MD_RAID5=m |
363 | # CONFIG_MD_RAID5_RESHAPE is not set | ||
357 | # CONFIG_MD_RAID6 is not set | 364 | # CONFIG_MD_RAID6 is not set |
358 | CONFIG_MD_MULTIPATH=m | 365 | CONFIG_MD_MULTIPATH=m |
359 | # CONFIG_MD_FAULTY is not set | 366 | # CONFIG_MD_FAULTY is not set |
@@ -404,6 +411,7 @@ CONFIG_S390_TAPE_BLOCK=y | |||
404 | # S/390 tape hardware support | 411 | # S/390 tape hardware support |
405 | # | 412 | # |
406 | CONFIG_S390_TAPE_34XX=m | 413 | CONFIG_S390_TAPE_34XX=m |
414 | # CONFIG_S390_TAPE_3590 is not set | ||
407 | # CONFIG_VMLOGRDR is not set | 415 | # CONFIG_VMLOGRDR is not set |
408 | # CONFIG_VMCP is not set | 416 | # CONFIG_VMCP is not set |
409 | # CONFIG_MONREADER is not set | 417 | # CONFIG_MONREADER is not set |
@@ -529,7 +537,6 @@ CONFIG_SYSFS=y | |||
529 | CONFIG_TMPFS=y | 537 | CONFIG_TMPFS=y |
530 | # CONFIG_HUGETLB_PAGE is not set | 538 | # CONFIG_HUGETLB_PAGE is not set |
531 | CONFIG_RAMFS=y | 539 | CONFIG_RAMFS=y |
532 | # CONFIG_RELAYFS_FS is not set | ||
533 | # CONFIG_CONFIGFS_FS is not set | 540 | # CONFIG_CONFIGFS_FS is not set |
534 | 541 | ||
535 | # | 542 | # |
@@ -619,14 +626,15 @@ CONFIG_LOG_BUF_SHIFT=17 | |||
619 | # CONFIG_DETECT_SOFTLOCKUP is not set | 626 | # CONFIG_DETECT_SOFTLOCKUP is not set |
620 | # CONFIG_SCHEDSTATS is not set | 627 | # CONFIG_SCHEDSTATS is not set |
621 | # CONFIG_DEBUG_SLAB is not set | 628 | # CONFIG_DEBUG_SLAB is not set |
622 | # CONFIG_DEBUG_PREEMPT is not set | 629 | CONFIG_DEBUG_PREEMPT=y |
623 | CONFIG_DEBUG_MUTEXES=y | 630 | CONFIG_DEBUG_MUTEXES=y |
624 | # CONFIG_DEBUG_SPINLOCK is not set | 631 | CONFIG_DEBUG_SPINLOCK=y |
625 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 632 | CONFIG_DEBUG_SPINLOCK_SLEEP=y |
626 | # CONFIG_DEBUG_KOBJECT is not set | 633 | # CONFIG_DEBUG_KOBJECT is not set |
627 | # CONFIG_DEBUG_INFO is not set | 634 | # CONFIG_DEBUG_INFO is not set |
628 | CONFIG_DEBUG_FS=y | 635 | CONFIG_DEBUG_FS=y |
629 | # CONFIG_DEBUG_VM is not set | 636 | # CONFIG_DEBUG_VM is not set |
637 | # CONFIG_UNWIND_INFO is not set | ||
630 | CONFIG_FORCED_INLINING=y | 638 | CONFIG_FORCED_INLINING=y |
631 | # CONFIG_RCU_TORTURE_TEST is not set | 639 | # CONFIG_RCU_TORTURE_TEST is not set |
632 | 640 | ||
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 58583f459471..2bcecf422573 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -527,6 +527,11 @@ config CPU_HAS_SR_RB | |||
527 | See <file:Documentation/sh/register-banks.txt> for further | 527 | See <file:Documentation/sh/register-banks.txt> for further |
528 | information on SR.RB and register banking in the kernel in general. | 528 | information on SR.RB and register banking in the kernel in general. |
529 | 529 | ||
530 | config NODES_SHIFT | ||
531 | int | ||
532 | default "1" | ||
533 | depends on NEED_MULTIPLE_NODES | ||
534 | |||
530 | endmenu | 535 | endmenu |
531 | 536 | ||
532 | menu "Boot options" | 537 | menu "Boot options" |
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index 1cf94a618be3..d5d032533a8b 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c | |||
@@ -37,7 +37,6 @@ EXPORT_SYMBOL(disable_irq_nosync); | |||
37 | EXPORT_SYMBOL(irq_desc); | 37 | EXPORT_SYMBOL(irq_desc); |
38 | EXPORT_SYMBOL(no_irq_type); | 38 | EXPORT_SYMBOL(no_irq_type); |
39 | 39 | ||
40 | EXPORT_SYMBOL(strpbrk); | ||
41 | EXPORT_SYMBOL(strstr); | 40 | EXPORT_SYMBOL(strstr); |
42 | EXPORT_SYMBOL(strlen); | 41 | EXPORT_SYMBOL(strlen); |
43 | EXPORT_SYMBOL(strnlen); | 42 | EXPORT_SYMBOL(strnlen); |
diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c index de29c45f23a7..6f3a1c946339 100644 --- a/arch/sh64/kernel/sh_ksyms.c +++ b/arch/sh64/kernel/sh_ksyms.c | |||
@@ -41,7 +41,6 @@ EXPORT_SYMBOL(kernel_thread); | |||
41 | /* Networking helper routines. */ | 41 | /* Networking helper routines. */ |
42 | EXPORT_SYMBOL(csum_partial_copy); | 42 | EXPORT_SYMBOL(csum_partial_copy); |
43 | 43 | ||
44 | EXPORT_SYMBOL(strpbrk); | ||
45 | EXPORT_SYMBOL(strstr); | 44 | EXPORT_SYMBOL(strstr); |
46 | 45 | ||
47 | #ifdef CONFIG_VT | 46 | #ifdef CONFIG_VT |
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 2be812115197..a93f5da6855d 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c | |||
@@ -244,7 +244,7 @@ int setup_profiling_timer(unsigned int multiplier) | |||
244 | return -EINVAL; | 244 | return -EINVAL; |
245 | 245 | ||
246 | spin_lock_irqsave(&prof_setup_lock, flags); | 246 | spin_lock_irqsave(&prof_setup_lock, flags); |
247 | for_each_cpu(i) { | 247 | for_each_possible_cpu(i) { |
248 | load_profile_irq(i, lvl14_resolution / multiplier); | 248 | load_profile_irq(i, lvl14_resolution / multiplier); |
249 | prof_multiplier(i) = multiplier; | 249 | prof_multiplier(i) = multiplier; |
250 | } | 250 | } |
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 2c21d7907635..ec1c9687d679 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c | |||
@@ -263,7 +263,6 @@ EXPORT_SYMBOL(strcmp); | |||
263 | EXPORT_SYMBOL(strncmp); | 263 | EXPORT_SYMBOL(strncmp); |
264 | EXPORT_SYMBOL(strchr); | 264 | EXPORT_SYMBOL(strchr); |
265 | EXPORT_SYMBOL(strrchr); | 265 | EXPORT_SYMBOL(strrchr); |
266 | EXPORT_SYMBOL(strpbrk); | ||
267 | EXPORT_SYMBOL(strstr); | 266 | EXPORT_SYMBOL(strstr); |
268 | EXPORT_SYMBOL(page_kernel); | 267 | EXPORT_SYMBOL(page_kernel); |
269 | 268 | ||
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index fbbec5e761c6..db8faa75f94d 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S | |||
@@ -75,7 +75,7 @@ sys_call_table: | |||
75 | /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy | 75 | /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy |
76 | /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink | 76 | /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink |
77 | /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid | 77 | /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid |
78 | /*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat | 78 | /*280*/ .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat |
79 | /*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 | 79 | /*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 |
80 | /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat | 80 | /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat |
81 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare | 81 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare |
diff --git a/arch/sparc/math-emu/Makefile b/arch/sparc/math-emu/Makefile index f84a9a6162be..8136987977f4 100644 --- a/arch/sparc/math-emu/Makefile +++ b/arch/sparc/math-emu/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | obj-y := math.o | 5 | obj-y := math.o |
6 | 6 | ||
7 | EXTRA_AFLAGS := -ansi | 7 | EXTRA_AFLAGS := -ansi |
8 | EXTRA_CFLAGS = -I. -I$(TOPDIR)/include/math-emu -w | 8 | EXTRA_CFLAGS = -I. -Iinclude/math-emu -w |
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index d1e2fc566486..43a66f5407f4 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
@@ -187,13 +187,16 @@ config HUGETLB_PAGE_SIZE_512K | |||
187 | bool "512K" | 187 | bool "512K" |
188 | 188 | ||
189 | config HUGETLB_PAGE_SIZE_64K | 189 | config HUGETLB_PAGE_SIZE_64K |
190 | depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB && !SPARC64_PAGE_SIZE_64K | 190 | depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB && !SPARC64_PAGE_SIZE_64KB |
191 | bool "64K" | 191 | bool "64K" |
192 | 192 | ||
193 | endchoice | 193 | endchoice |
194 | 194 | ||
195 | endmenu | 195 | endmenu |
196 | 196 | ||
197 | config ARCH_SELECT_MEMORY_MODEL | ||
198 | def_bool y | ||
199 | |||
197 | config ARCH_SPARSEMEM_ENABLE | 200 | config ARCH_SPARSEMEM_ENABLE |
198 | def_bool y | 201 | def_bool y |
199 | 202 | ||
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 30389085a359..1317380fa937 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16 | 3 | # Linux kernel version: 2.6.16 |
4 | # Fri Mar 31 01:40:57 2006 | 4 | # Sun Apr 2 19:31:04 2006 |
5 | # | 5 | # |
6 | CONFIG_SPARC=y | 6 | CONFIG_SPARC=y |
7 | CONFIG_SPARC64=y | 7 | CONFIG_SPARC64=y |
@@ -838,7 +838,6 @@ CONFIG_FB_TILEBLITTING=y | |||
838 | # CONFIG_FB_NVIDIA is not set | 838 | # CONFIG_FB_NVIDIA is not set |
839 | # CONFIG_FB_RIVA is not set | 839 | # CONFIG_FB_RIVA is not set |
840 | # CONFIG_FB_MATROX is not set | 840 | # CONFIG_FB_MATROX is not set |
841 | # CONFIG_FB_RADEON_OLD is not set | ||
842 | CONFIG_FB_RADEON=y | 841 | CONFIG_FB_RADEON=y |
843 | CONFIG_FB_RADEON_I2C=y | 842 | CONFIG_FB_RADEON_I2C=y |
844 | # CONFIG_FB_RADEON_DEBUG is not set | 843 | # CONFIG_FB_RADEON_DEBUG is not set |
@@ -924,6 +923,7 @@ CONFIG_SND_MTPAV=m | |||
924 | # PCI devices | 923 | # PCI devices |
925 | # | 924 | # |
926 | # CONFIG_SND_AD1889 is not set | 925 | # CONFIG_SND_AD1889 is not set |
926 | # CONFIG_SND_ALS300 is not set | ||
927 | CONFIG_SND_ALI5451=m | 927 | CONFIG_SND_ALI5451=m |
928 | # CONFIG_SND_ATIIXP is not set | 928 | # CONFIG_SND_ATIIXP is not set |
929 | # CONFIG_SND_ATIIXP_MODEM is not set | 929 | # CONFIG_SND_ATIIXP_MODEM is not set |
@@ -955,6 +955,7 @@ CONFIG_SND_ALI5451=m | |||
955 | # CONFIG_SND_MIXART is not set | 955 | # CONFIG_SND_MIXART is not set |
956 | # CONFIG_SND_NM256 is not set | 956 | # CONFIG_SND_NM256 is not set |
957 | # CONFIG_SND_PCXHR is not set | 957 | # CONFIG_SND_PCXHR is not set |
958 | # CONFIG_SND_RIPTIDE is not set | ||
958 | # CONFIG_SND_RME32 is not set | 959 | # CONFIG_SND_RME32 is not set |
959 | # CONFIG_SND_RME96 is not set | 960 | # CONFIG_SND_RME96 is not set |
960 | # CONFIG_SND_RME9652 is not set | 961 | # CONFIG_SND_RME9652 is not set |
@@ -1109,6 +1110,11 @@ CONFIG_USB_HIDDEV=y | |||
1109 | # CONFIG_MMC is not set | 1110 | # CONFIG_MMC is not set |
1110 | 1111 | ||
1111 | # | 1112 | # |
1113 | # LED devices | ||
1114 | # | ||
1115 | # CONFIG_NEW_LEDS is not set | ||
1116 | |||
1117 | # | ||
1112 | # InfiniBand support | 1118 | # InfiniBand support |
1113 | # | 1119 | # |
1114 | # CONFIG_INFINIBAND is not set | 1120 | # CONFIG_INFINIBAND is not set |
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index ffc7309e9f22..2e1c824c1cc9 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c | |||
@@ -63,7 +63,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) | |||
63 | flushi(p->addr); | 63 | flushi(p->addr); |
64 | } | 64 | } |
65 | 65 | ||
66 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 66 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
67 | { | 67 | { |
68 | kcb->prev_kprobe.kp = kprobe_running(); | 68 | kcb->prev_kprobe.kp = kprobe_running(); |
69 | kcb->prev_kprobe.status = kcb->kprobe_status; | 69 | kcb->prev_kprobe.status = kcb->kprobe_status; |
@@ -71,7 +71,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
71 | kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil; | 71 | kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil; |
72 | } | 72 | } |
73 | 73 | ||
74 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 74 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
75 | { | 75 | { |
76 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | 76 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
77 | kcb->kprobe_status = kcb->prev_kprobe.status; | 77 | kcb->kprobe_status = kcb->prev_kprobe.status; |
@@ -79,7 +79,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
79 | kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil; | 79 | kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil; |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | 82 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
83 | struct kprobe_ctlblk *kcb) | 83 | struct kprobe_ctlblk *kcb) |
84 | { | 84 | { |
85 | __get_cpu_var(current_kprobe) = p; | 85 | __get_cpu_var(current_kprobe) = p; |
@@ -87,7 +87,7 @@ static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | |||
87 | kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL); | 87 | kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL); |
88 | } | 88 | } |
89 | 89 | ||
90 | static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs, | 90 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs, |
91 | struct kprobe_ctlblk *kcb) | 91 | struct kprobe_ctlblk *kcb) |
92 | { | 92 | { |
93 | regs->tstate |= TSTATE_PIL; | 93 | regs->tstate |= TSTATE_PIL; |
@@ -273,7 +273,7 @@ static void __kprobes resume_execution(struct kprobe *p, | |||
273 | kcb->kprobe_orig_tstate_pil); | 273 | kcb->kprobe_orig_tstate_pil); |
274 | } | 274 | } |
275 | 275 | ||
276 | static inline int post_kprobe_handler(struct pt_regs *regs) | 276 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) |
277 | { | 277 | { |
278 | struct kprobe *cur = kprobe_running(); | 278 | struct kprobe *cur = kprobe_running(); |
279 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 279 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -300,7 +300,7 @@ out: | |||
300 | return 1; | 300 | return 1; |
301 | } | 301 | } |
302 | 302 | ||
303 | static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 303 | static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
304 | { | 304 | { |
305 | struct kprobe *cur = kprobe_running(); | 305 | struct kprobe *cur = kprobe_running(); |
306 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 306 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index dfccff29e182..f97ddeb105ac 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -419,6 +419,7 @@ void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region | |||
419 | region->start = res->start - zero_res.start; | 419 | region->start = res->start - zero_res.start; |
420 | region->end = res->end - zero_res.start; | 420 | region->end = res->end - zero_res.start; |
421 | } | 421 | } |
422 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
422 | 423 | ||
423 | void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, | 424 | void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, |
424 | struct pci_bus_region *region) | 425 | struct pci_bus_region *region) |
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 9372d4f376d5..9e94db2573a2 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -1092,7 +1092,7 @@ void sun4v_pci_init(int node, char *model_name) | |||
1092 | } | 1092 | } |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | for_each_cpu(i) { | 1095 | for_each_possible_cpu(i) { |
1096 | unsigned long page = get_zeroed_page(GFP_ATOMIC); | 1096 | unsigned long page = get_zeroed_page(GFP_ATOMIC); |
1097 | 1097 | ||
1098 | if (!page) | 1098 | if (!page) |
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index eb93e9c52846..49e6dedd027d 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c | |||
@@ -244,6 +244,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs) | |||
244 | } | 244 | } |
245 | 245 | ||
246 | switch(request) { | 246 | switch(request) { |
247 | case PTRACE_PEEKUSR: | ||
248 | if (addr != 0) | ||
249 | pt_error_return(regs, EIO); | ||
250 | else | ||
251 | pt_succ_return(regs, 0); | ||
252 | goto out_tsk; | ||
253 | |||
247 | case PTRACE_PEEKTEXT: /* read word at location addr. */ | 254 | case PTRACE_PEEKTEXT: /* read word at location addr. */ |
248 | case PTRACE_PEEKDATA: { | 255 | case PTRACE_PEEKDATA: { |
249 | unsigned long tmp64; | 256 | unsigned long tmp64; |
@@ -602,6 +609,22 @@ asmlinkage void do_ptrace(struct pt_regs *regs) | |||
602 | 609 | ||
603 | /* PTRACE_DUMPCORE unsupported... */ | 610 | /* PTRACE_DUMPCORE unsupported... */ |
604 | 611 | ||
612 | case PTRACE_GETEVENTMSG: { | ||
613 | int err; | ||
614 | |||
615 | if (test_thread_flag(TIF_32BIT)) | ||
616 | err = put_user(child->ptrace_message, | ||
617 | (unsigned int __user *) data); | ||
618 | else | ||
619 | err = put_user(child->ptrace_message, | ||
620 | (unsigned long __user *) data); | ||
621 | if (err) | ||
622 | pt_error_return(regs, -err); | ||
623 | else | ||
624 | pt_succ_return(regs, 0); | ||
625 | break; | ||
626 | } | ||
627 | |||
605 | default: { | 628 | default: { |
606 | int err = ptrace_request(child, request, addr, data); | 629 | int err = ptrace_request(child, request, addr, data); |
607 | if (err) | 630 | if (err) |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 7d0e67c1ce50..005167f82419 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -535,7 +535,7 @@ static int __init topology_init(void) | |||
535 | while (!cpu_find_by_instance(ncpus_probed, NULL, NULL)) | 535 | while (!cpu_find_by_instance(ncpus_probed, NULL, NULL)) |
536 | ncpus_probed++; | 536 | ncpus_probed++; |
537 | 537 | ||
538 | for_each_cpu(i) { | 538 | for_each_possible_cpu(i) { |
539 | struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); | 539 | struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); |
540 | if (p) { | 540 | if (p) { |
541 | register_cpu(p, i, NULL); | 541 | register_cpu(p, i, NULL); |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 8175a6968c6b..90eaca3ec9a6 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -745,12 +745,21 @@ struct call_data_struct { | |||
745 | int wait; | 745 | int wait; |
746 | }; | 746 | }; |
747 | 747 | ||
748 | static DEFINE_SPINLOCK(call_lock); | 748 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock); |
749 | static struct call_data_struct *call_data; | 749 | static struct call_data_struct *call_data; |
750 | 750 | ||
751 | extern unsigned long xcall_call_function; | 751 | extern unsigned long xcall_call_function; |
752 | 752 | ||
753 | /* | 753 | /** |
754 | * smp_call_function(): Run a function on all other CPUs. | ||
755 | * @func: The function to run. This must be fast and non-blocking. | ||
756 | * @info: An arbitrary pointer to pass to the function. | ||
757 | * @nonatomic: currently unused. | ||
758 | * @wait: If true, wait (atomically) until function has completed on other CPUs. | ||
759 | * | ||
760 | * Returns 0 on success, else a negative status code. Does not return until | ||
761 | * remote CPUs are nearly ready to execute <<func>> or are or have executed. | ||
762 | * | ||
754 | * You must not call this function with disabled interrupts or from a | 763 | * You must not call this function with disabled interrupts or from a |
755 | * hardware interrupt handler or from a bottom half handler. | 764 | * hardware interrupt handler or from a bottom half handler. |
756 | */ | 765 | */ |
@@ -759,7 +768,6 @@ static int smp_call_function_mask(void (*func)(void *info), void *info, | |||
759 | { | 768 | { |
760 | struct call_data_struct data; | 769 | struct call_data_struct data; |
761 | int cpus; | 770 | int cpus; |
762 | long timeout; | ||
763 | 771 | ||
764 | /* Can deadlock when called with interrupts disabled */ | 772 | /* Can deadlock when called with interrupts disabled */ |
765 | WARN_ON(irqs_disabled()); | 773 | WARN_ON(irqs_disabled()); |
@@ -777,31 +785,18 @@ static int smp_call_function_mask(void (*func)(void *info), void *info, | |||
777 | goto out_unlock; | 785 | goto out_unlock; |
778 | 786 | ||
779 | call_data = &data; | 787 | call_data = &data; |
788 | mb(); | ||
780 | 789 | ||
781 | smp_cross_call_masked(&xcall_call_function, 0, 0, 0, mask); | 790 | smp_cross_call_masked(&xcall_call_function, 0, 0, 0, mask); |
782 | 791 | ||
783 | /* | 792 | /* Wait for response */ |
784 | * Wait for other cpus to complete function or at | 793 | while (atomic_read(&data.finished) != cpus) |
785 | * least snap the call data. | 794 | cpu_relax(); |
786 | */ | ||
787 | timeout = 1000000; | ||
788 | while (atomic_read(&data.finished) != cpus) { | ||
789 | if (--timeout <= 0) | ||
790 | goto out_timeout; | ||
791 | barrier(); | ||
792 | udelay(1); | ||
793 | } | ||
794 | 795 | ||
795 | out_unlock: | 796 | out_unlock: |
796 | spin_unlock(&call_lock); | 797 | spin_unlock(&call_lock); |
797 | 798 | ||
798 | return 0; | 799 | return 0; |
799 | |||
800 | out_timeout: | ||
801 | spin_unlock(&call_lock); | ||
802 | printk("XCALL: Remote cpus not responding, ncpus=%d finished=%d\n", | ||
803 | cpus, atomic_read(&data.finished)); | ||
804 | return 0; | ||
805 | } | 800 | } |
806 | 801 | ||
807 | int smp_call_function(void (*func)(void *info), void *info, | 802 | int smp_call_function(void (*func)(void *info), void *info, |
@@ -1285,7 +1280,7 @@ int setup_profiling_timer(unsigned int multiplier) | |||
1285 | return -EINVAL; | 1280 | return -EINVAL; |
1286 | 1281 | ||
1287 | spin_lock_irqsave(&prof_setup_lock, flags); | 1282 | spin_lock_irqsave(&prof_setup_lock, flags); |
1288 | for_each_cpu(i) | 1283 | for_each_possible_cpu(i) |
1289 | prof_multiplier(i) = multiplier; | 1284 | prof_multiplier(i) = multiplier; |
1290 | current_tick_offset = (timer_tick_offset / multiplier); | 1285 | current_tick_offset = (timer_tick_offset / multiplier); |
1291 | spin_unlock_irqrestore(&prof_setup_lock, flags); | 1286 | spin_unlock_irqrestore(&prof_setup_lock, flags); |
@@ -1313,12 +1308,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
1313 | } | 1308 | } |
1314 | } | 1309 | } |
1315 | 1310 | ||
1316 | for_each_cpu(i) { | 1311 | for_each_possible_cpu(i) { |
1317 | if (tlb_type == hypervisor) { | 1312 | if (tlb_type == hypervisor) { |
1318 | int j; | 1313 | int j; |
1319 | 1314 | ||
1320 | /* XXX get this mapping from machine description */ | 1315 | /* XXX get this mapping from machine description */ |
1321 | for_each_cpu(j) { | 1316 | for_each_possible_cpu(j) { |
1322 | if ((j >> 2) == (i >> 2)) | 1317 | if ((j >> 2) == (i >> 2)) |
1323 | cpu_set(j, cpu_sibling_map[i]); | 1318 | cpu_set(j, cpu_sibling_map[i]); |
1324 | } | 1319 | } |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index f5e8db1de76b..62d8a99271ea 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -276,7 +276,6 @@ EXPORT_SYMBOL(__prom_getsibling); | |||
276 | EXPORT_SYMBOL(strlen); | 276 | EXPORT_SYMBOL(strlen); |
277 | EXPORT_SYMBOL(__strlen_user); | 277 | EXPORT_SYMBOL(__strlen_user); |
278 | EXPORT_SYMBOL(__strnlen_user); | 278 | EXPORT_SYMBOL(__strnlen_user); |
279 | EXPORT_SYMBOL(strpbrk); | ||
280 | 279 | ||
281 | #ifdef CONFIG_SOLARIS_EMUL_MODULE | 280 | #ifdef CONFIG_SOLARIS_EMUL_MODULE |
282 | EXPORT_SYMBOL(linux_sparc_syscall); | 281 | EXPORT_SYMBOL(linux_sparc_syscall); |
diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index 86dd5cb81e09..f9b75760163c 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S | |||
@@ -138,6 +138,7 @@ SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1) | |||
138 | SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) | 138 | SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) |
139 | SIGN2(sys32_splice, sys_splice, %o0, %o1) | 139 | SIGN2(sys32_splice, sys_splice, %o0, %o1) |
140 | SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5) | 140 | SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5) |
141 | SIGN2(sys32_tee, sys_tee, %o0, %o1) | ||
141 | 142 | ||
142 | .globl sys32_mmap2 | 143 | .globl sys32_mmap2 |
143 | sys32_mmap2: | 144 | sys32_mmap2: |
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 857b82c82875..62672cd92eca 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S | |||
@@ -76,7 +76,7 @@ sys_call_table32: | |||
76 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy | 76 | .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy |
77 | /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink | 77 | /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink |
78 | .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid | 78 | .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid |
79 | /*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat | 79 | /*280*/ .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat |
80 | .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 | 80 | .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 |
81 | /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat | 81 | /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat |
82 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare | 82 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare |
@@ -145,7 +145,7 @@ sys_call_table: | |||
145 | .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy | 145 | .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy |
146 | /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink | 146 | /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink |
147 | .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid | 147 | .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid |
148 | /*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat | 148 | /*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat |
149 | .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 | 149 | .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 |
150 | /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat | 150 | /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat |
151 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare | 151 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index ff090bb9734b..2793a5d82380 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -1130,9 +1130,9 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in | |||
1130 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), | 1130 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), |
1131 | afsr, afar, | 1131 | afsr, afar, |
1132 | (afsr & CHAFSR_TL1) ? 1 : 0); | 1132 | (afsr & CHAFSR_TL1) ? 1 : 0); |
1133 | printk("%s" "ERROR(%d): TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n", | 1133 | printk("%s" "ERROR(%d): TPC[%lx] TNPC[%lx] O7[%lx] TSTATE[%lx]\n", |
1134 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), | 1134 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), |
1135 | regs->tpc, regs->tnpc, regs->tstate); | 1135 | regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate); |
1136 | printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n", | 1136 | printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n", |
1137 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), | 1137 | (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), |
1138 | (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT, | 1138 | (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT, |
diff --git a/arch/um/Makefile b/arch/um/Makefile index 24790bed2054..a508e7a02891 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile | |||
@@ -159,6 +159,7 @@ archclean: | |||
159 | $(SYMLINK_HEADERS): | 159 | $(SYMLINK_HEADERS): |
160 | @echo ' SYMLINK $@' | 160 | @echo ' SYMLINK $@' |
161 | ifneq ($(KBUILD_SRC),) | 161 | ifneq ($(KBUILD_SRC),) |
162 | $(Q)mkdir -p $(objtree)/include/asm-um | ||
162 | $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@ | 163 | $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@ |
163 | else | 164 | else |
164 | $(Q)cd $(TOPDIR)/$(dir $@) ; \ | 165 | $(Q)cd $(TOPDIR)/$(dir $@) ; \ |
@@ -168,7 +169,7 @@ endif | |||
168 | include/asm-um/arch: | 169 | include/asm-um/arch: |
169 | @echo ' SYMLINK $@' | 170 | @echo ' SYMLINK $@' |
170 | ifneq ($(KBUILD_SRC),) | 171 | ifneq ($(KBUILD_SRC),) |
171 | $(Q)mkdir -p include/asm-um | 172 | $(Q)mkdir -p $(objtree)/include/asm-um |
172 | $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch | 173 | $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch |
173 | else | 174 | else |
174 | $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch | 175 | $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch |
diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h index 04e3958266e0..dc36b222100b 100644 --- a/arch/um/drivers/cow.h +++ b/arch/um/drivers/cow.h | |||
@@ -46,7 +46,7 @@ extern int file_reader(__u64 offset, char *buf, int len, void *arg); | |||
46 | extern int read_cow_header(int (*reader)(__u64, char *, int, void *), | 46 | extern int read_cow_header(int (*reader)(__u64, char *, int, void *), |
47 | void *arg, __u32 *version_out, | 47 | void *arg, __u32 *version_out, |
48 | char **backing_file_out, time_t *mtime_out, | 48 | char **backing_file_out, time_t *mtime_out, |
49 | __u64 *size_out, int *sectorsize_out, | 49 | unsigned long long *size_out, int *sectorsize_out, |
50 | __u32 *align_out, int *bitmap_offset_out); | 50 | __u32 *align_out, int *bitmap_offset_out); |
51 | 51 | ||
52 | extern int write_cow_header(char *cow_file, int fd, char *backing_file, | 52 | extern int write_cow_header(char *cow_file, int fd, char *backing_file, |
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index 94de4ead4f7a..7a5b4afde692 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h | |||
@@ -28,7 +28,7 @@ static inline int cow_seek_file(int fd, __u64 offset) | |||
28 | return(os_seek_file(fd, offset)); | 28 | return(os_seek_file(fd, offset)); |
29 | } | 29 | } |
30 | 30 | ||
31 | static inline int cow_file_size(char *file, __u64 *size_out) | 31 | static inline int cow_file_size(char *file, unsigned long long *size_out) |
32 | { | 32 | { |
33 | return(os_file_size(file, size_out)); | 33 | return(os_file_size(file, size_out)); |
34 | } | 34 | } |
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index 61951b721268..6ab852bfcd3a 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c | |||
@@ -17,30 +17,34 @@ | |||
17 | 17 | ||
18 | #define PATH_LEN_V1 256 | 18 | #define PATH_LEN_V1 256 |
19 | 19 | ||
20 | typedef __u32 time32_t; | ||
21 | |||
20 | struct cow_header_v1 { | 22 | struct cow_header_v1 { |
21 | int magic; | 23 | __s32 magic; |
22 | int version; | 24 | __s32 version; |
23 | char backing_file[PATH_LEN_V1]; | 25 | char backing_file[PATH_LEN_V1]; |
24 | time_t mtime; | 26 | time32_t mtime; |
25 | __u64 size; | 27 | __u64 size; |
26 | int sectorsize; | 28 | __s32 sectorsize; |
27 | }; | 29 | } __attribute__((packed)); |
28 | 30 | ||
29 | #define PATH_LEN_V2 MAXPATHLEN | 31 | /* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in |
32 | * case other systems have different values for MAXPATHLEN. | ||
33 | * | ||
34 | * The same must hold for V2 - we want file format compatibility, not anything | ||
35 | * else. | ||
36 | */ | ||
37 | #define PATH_LEN_V3 4096 | ||
38 | #define PATH_LEN_V2 PATH_LEN_V3 | ||
30 | 39 | ||
31 | struct cow_header_v2 { | 40 | struct cow_header_v2 { |
32 | __u32 magic; | 41 | __u32 magic; |
33 | __u32 version; | 42 | __u32 version; |
34 | char backing_file[PATH_LEN_V2]; | 43 | char backing_file[PATH_LEN_V2]; |
35 | time_t mtime; | 44 | time32_t mtime; |
36 | __u64 size; | 45 | __u64 size; |
37 | int sectorsize; | 46 | __s32 sectorsize; |
38 | }; | 47 | } __attribute__((packed)); |
39 | |||
40 | /* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in | ||
41 | * case other systems have different values for MAXPATHLEN | ||
42 | */ | ||
43 | #define PATH_LEN_V3 4096 | ||
44 | 48 | ||
45 | /* Changes from V2 - | 49 | /* Changes from V2 - |
46 | * PATH_LEN_V3 as described above | 50 | * PATH_LEN_V3 as described above |
@@ -66,6 +70,15 @@ struct cow_header_v2 { | |||
66 | * Fixed (finally!) the rounding bug | 70 | * Fixed (finally!) the rounding bug |
67 | */ | 71 | */ |
68 | 72 | ||
73 | /* Until Dec2005, __attribute__((packed)) was left out from the below | ||
74 | * definition, leading on 64-bit systems to 4 bytes of padding after mtime, to | ||
75 | * align size to 8-byte alignment. This shifted all fields above (no padding | ||
76 | * was present on 32-bit, no other padding was added). | ||
77 | * | ||
78 | * However, this _can be detected_: it means that cow_format (always 0 until | ||
79 | * now) is shifted onto the first 4 bytes of backing_file, where it is otherwise | ||
80 | * impossible to find 4 zeros. -bb */ | ||
81 | |||
69 | struct cow_header_v3 { | 82 | struct cow_header_v3 { |
70 | __u32 magic; | 83 | __u32 magic; |
71 | __u32 version; | 84 | __u32 version; |
@@ -75,7 +88,19 @@ struct cow_header_v3 { | |||
75 | __u32 alignment; | 88 | __u32 alignment; |
76 | __u32 cow_format; | 89 | __u32 cow_format; |
77 | char backing_file[PATH_LEN_V3]; | 90 | char backing_file[PATH_LEN_V3]; |
78 | }; | 91 | } __attribute__((packed)); |
92 | |||
93 | /* This is the broken layout used by some 64-bit binaries. */ | ||
94 | struct cow_header_v3_broken { | ||
95 | __u32 magic; | ||
96 | __u32 version; | ||
97 | __s64 mtime; | ||
98 | __u64 size; | ||
99 | __u32 sectorsize; | ||
100 | __u32 alignment; | ||
101 | __u32 cow_format; | ||
102 | char backing_file[PATH_LEN_V3]; | ||
103 | } __attribute__((packed)); | ||
79 | 104 | ||
80 | /* COW format definitions - for now, we have only the usual COW bitmap */ | 105 | /* COW format definitions - for now, we have only the usual COW bitmap */ |
81 | #define COW_BITMAP 0 | 106 | #define COW_BITMAP 0 |
@@ -84,6 +109,7 @@ union cow_header { | |||
84 | struct cow_header_v1 v1; | 109 | struct cow_header_v1 v1; |
85 | struct cow_header_v2 v2; | 110 | struct cow_header_v2 v2; |
86 | struct cow_header_v3 v3; | 111 | struct cow_header_v3 v3; |
112 | struct cow_header_v3_broken v3_b; | ||
87 | }; | 113 | }; |
88 | 114 | ||
89 | #define COW_MAGIC 0x4f4f4f4d /* MOOO */ | 115 | #define COW_MAGIC 0x4f4f4f4d /* MOOO */ |
@@ -184,8 +210,9 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, | |||
184 | 210 | ||
185 | err = -EINVAL; | 211 | err = -EINVAL; |
186 | if(strlen(backing_file) > sizeof(header->backing_file) - 1){ | 212 | if(strlen(backing_file) > sizeof(header->backing_file) - 1){ |
213 | /* Below, %zd is for a size_t value */ | ||
187 | cow_printf("Backing file name \"%s\" is too long - names are " | 214 | cow_printf("Backing file name \"%s\" is too long - names are " |
188 | "limited to %d characters\n", backing_file, | 215 | "limited to %zd characters\n", backing_file, |
189 | sizeof(header->backing_file) - 1); | 216 | sizeof(header->backing_file) - 1); |
190 | goto out_free; | 217 | goto out_free; |
191 | } | 218 | } |
@@ -300,7 +327,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, | |||
300 | *align_out = *sectorsize_out; | 327 | *align_out = *sectorsize_out; |
301 | file = header->v2.backing_file; | 328 | file = header->v2.backing_file; |
302 | } | 329 | } |
303 | else if(version == 3){ | 330 | /* This is very subtle - see above at union cow_header definition */ |
331 | else if(version == 3 && (*((int*)header->v3.backing_file) != 0)){ | ||
304 | if(n < sizeof(header->v3)){ | 332 | if(n < sizeof(header->v3)){ |
305 | cow_printf("read_cow_header - failed to read V3 " | 333 | cow_printf("read_cow_header - failed to read V3 " |
306 | "header\n"); | 334 | "header\n"); |
@@ -310,9 +338,43 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, | |||
310 | *size_out = ntohll(header->v3.size); | 338 | *size_out = ntohll(header->v3.size); |
311 | *sectorsize_out = ntohl(header->v3.sectorsize); | 339 | *sectorsize_out = ntohl(header->v3.sectorsize); |
312 | *align_out = ntohl(header->v3.alignment); | 340 | *align_out = ntohl(header->v3.alignment); |
341 | if (*align_out == 0) { | ||
342 | cow_printf("read_cow_header - invalid COW header, " | ||
343 | "align == 0\n"); | ||
344 | } | ||
313 | *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out); | 345 | *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out); |
314 | file = header->v3.backing_file; | 346 | file = header->v3.backing_file; |
315 | } | 347 | } |
348 | else if(version == 3){ | ||
349 | cow_printf("read_cow_header - broken V3 file with" | ||
350 | " 64-bit layout - recovering content.\n"); | ||
351 | |||
352 | if(n < sizeof(header->v3_b)){ | ||
353 | cow_printf("read_cow_header - failed to read V3 " | ||
354 | "header\n"); | ||
355 | goto out; | ||
356 | } | ||
357 | |||
358 | /* this was used until Dec2005 - 64bits are needed to represent | ||
359 | * 2038+. I.e. we can safely do this truncating cast. | ||
360 | * | ||
361 | * Additionally, we must use ntohl() instead of ntohll(), since | ||
362 | * the program used to use the former (tested - I got mtime | ||
363 | * mismatch "0 vs whatever"). | ||
364 | * | ||
365 | * Ever heard about bug-to-bug-compatibility ? ;-) */ | ||
366 | *mtime_out = (time32_t) ntohl(header->v3_b.mtime); | ||
367 | |||
368 | *size_out = ntohll(header->v3_b.size); | ||
369 | *sectorsize_out = ntohl(header->v3_b.sectorsize); | ||
370 | *align_out = ntohl(header->v3_b.alignment); | ||
371 | if (*align_out == 0) { | ||
372 | cow_printf("read_cow_header - invalid COW header, " | ||
373 | "align == 0\n"); | ||
374 | } | ||
375 | *bitmap_offset_out = ROUND_UP(sizeof(header->v3_b), *align_out); | ||
376 | file = header->v3_b.backing_file; | ||
377 | } | ||
316 | else { | 378 | else { |
317 | cow_printf("read_cow_header - invalid COW version\n"); | 379 | cow_printf("read_cow_header - invalid COW version\n"); |
318 | goto out; | 380 | goto out; |
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 28e3760e8b98..6d7173fc55a3 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -62,7 +62,7 @@ static void mc_work_proc(void *unused) | |||
62 | unsigned long flags; | 62 | unsigned long flags; |
63 | 63 | ||
64 | while(!list_empty(&mc_requests)){ | 64 | while(!list_empty(&mc_requests)){ |
65 | local_save_flags(flags); | 65 | local_irq_save(flags); |
66 | req = list_entry(mc_requests.next, struct mconsole_entry, | 66 | req = list_entry(mc_requests.next, struct mconsole_entry, |
67 | list); | 67 | list); |
68 | list_del(&req->list); | 68 | list_del(&req->list); |
@@ -87,7 +87,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id, | |||
87 | if(req.cmd->context == MCONSOLE_INTR) | 87 | if(req.cmd->context == MCONSOLE_INTR) |
88 | (*req.cmd->handler)(&req); | 88 | (*req.cmd->handler)(&req); |
89 | else { | 89 | else { |
90 | new = kmalloc(sizeof(*new), GFP_ATOMIC); | 90 | new = kmalloc(sizeof(*new), GFP_NOWAIT); |
91 | if(new == NULL) | 91 | if(new == NULL) |
92 | mconsole_reply(&req, "Out of memory", 1, 0); | 92 | mconsole_reply(&req, "Out of memory", 1, 0); |
93 | else { | 93 | else { |
@@ -415,7 +415,6 @@ static int mem_config(char *str) | |||
415 | 415 | ||
416 | unplugged = page_address(page); | 416 | unplugged = page_address(page); |
417 | if(unplug_index == UNPLUGGED_PER_PAGE){ | 417 | if(unplug_index == UNPLUGGED_PER_PAGE){ |
418 | INIT_LIST_HEAD(&unplugged->list); | ||
419 | list_add(&unplugged->list, &unplugged_pages); | 418 | list_add(&unplugged->list, &unplugged_pages); |
420 | unplug_index = 0; | 419 | unplug_index = 0; |
421 | } | 420 | } |
@@ -616,7 +615,7 @@ static void console_write(struct console *console, const char *string, | |||
616 | return; | 615 | return; |
617 | 616 | ||
618 | while(1){ | 617 | while(1){ |
619 | n = min((size_t)len, ARRAY_SIZE(console_buf) - console_index); | 618 | n = min((size_t) len, ARRAY_SIZE(console_buf) - console_index); |
620 | strncpy(&console_buf[console_index], string, n); | 619 | strncpy(&console_buf[console_index], string, n); |
621 | console_index += n; | 620 | console_index += n; |
622 | string += n; | 621 | string += n; |
@@ -655,7 +654,6 @@ static void with_console(struct mc_request *req, void (*proc)(void *), | |||
655 | struct mconsole_entry entry; | 654 | struct mconsole_entry entry; |
656 | unsigned long flags; | 655 | unsigned long flags; |
657 | 656 | ||
658 | INIT_LIST_HEAD(&entry.list); | ||
659 | entry.request = *req; | 657 | entry.request = *req; |
660 | list_add(&entry.list, &clients); | 658 | list_add(&entry.list, &clients); |
661 | spin_lock_irqsave(&console_lock, flags); | 659 | spin_lock_irqsave(&console_lock, flags); |
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 0e2f06187ea7..0a7786e00cfb 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c | |||
@@ -182,7 +182,9 @@ static int change_tramp(char **argv, char *output, int output_len) | |||
182 | pe_data.stdout = fds[1]; | 182 | pe_data.stdout = fds[1]; |
183 | pid = run_helper(change_pre_exec, &pe_data, argv, NULL); | 183 | pid = run_helper(change_pre_exec, &pe_data, argv, NULL); |
184 | 184 | ||
185 | read_output(fds[0], output, output_len); | 185 | if (pid > 0) /* Avoid hang as we won't get data in failure case. */ |
186 | read_output(fds[0], output, output_len); | ||
187 | |||
186 | os_close_file(fds[0]); | 188 | os_close_file(fds[0]); |
187 | os_close_file(fds[1]); | 189 | os_close_file(fds[1]); |
188 | 190 | ||
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index b94c66114bc8..33c5f6e625e8 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c | |||
@@ -104,7 +104,7 @@ static void slirp_close(int fd, void *data) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | if(err == 0) { | 106 | if(err == 0) { |
107 | printk("slirp_close: process %d has not exited\n"); | 107 | printk("slirp_close: process %d has not exited\n", pri->pid); |
108 | return; | 108 | return; |
109 | } | 109 | } |
110 | 110 | ||
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 42557130a408..efa3d33c0be6 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h | |||
@@ -117,10 +117,6 @@ extern struct task_struct *get_task(int pid, int require); | |||
117 | extern void machine_halt(void); | 117 | extern void machine_halt(void); |
118 | extern int is_syscall(unsigned long addr); | 118 | extern int is_syscall(unsigned long addr); |
119 | 119 | ||
120 | extern void arch_switch_to_tt(struct task_struct *from, struct task_struct *to); | ||
121 | |||
122 | extern void arch_switch_to_skas(struct task_struct *from, struct task_struct *to); | ||
123 | |||
124 | extern void free_irq(unsigned int, void *); | 120 | extern void free_irq(unsigned int, void *); |
125 | extern int cpu(void); | 121 | extern int cpu(void); |
126 | 122 | ||
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h index 018b3819ab0b..8e7053013f7b 100644 --- a/arch/um/include/longjmp.h +++ b/arch/um/include/longjmp.h | |||
@@ -4,11 +4,11 @@ | |||
4 | #include <setjmp.h> | 4 | #include <setjmp.h> |
5 | #include "os.h" | 5 | #include "os.h" |
6 | 6 | ||
7 | #define UML_SIGLONGJMP(buf, val) do { \ | 7 | #define UML_LONGJMP(buf, val) do { \ |
8 | longjmp(*buf, val); \ | 8 | longjmp(*buf, val); \ |
9 | } while(0) | 9 | } while(0) |
10 | 10 | ||
11 | #define UML_SIGSETJMP(buf, enable) ({ \ | 11 | #define UML_SETJMP(buf, enable) ({ \ |
12 | int n; \ | 12 | int n; \ |
13 | enable = get_signals(); \ | 13 | enable = get_signals(); \ |
14 | n = setjmp(*buf); \ | 14 | n = setjmp(*buf); \ |
diff --git a/arch/um/include/sysdep-i386/kernel-offsets.h b/arch/um/include/sysdep-i386/kernel-offsets.h index 82f96c574144..2c13de321f2f 100644 --- a/arch/um/include/sysdep-i386/kernel-offsets.h +++ b/arch/um/include/sysdep-i386/kernel-offsets.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <linux/stddef.h> | 1 | #include <linux/stddef.h> |
2 | #include <linux/sched.h> | 2 | #include <linux/sched.h> |
3 | #include <linux/elf.h> | 3 | #include <linux/elf.h> |
4 | #include <asm/mman.h> | ||
4 | 5 | ||
5 | #define DEFINE(sym, val) \ | 6 | #define DEFINE(sym, val) \ |
6 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | 7 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) |
@@ -16,6 +17,7 @@ | |||
16 | void foo(void) | 17 | void foo(void) |
17 | { | 18 | { |
18 | OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); | 19 | OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); |
20 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); | ||
19 | #ifdef CONFIG_MODE_TT | 21 | #ifdef CONFIG_MODE_TT |
20 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | 22 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); |
21 | #endif | 23 | #endif |
diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h index 5ce93abd0b54..939cc475757a 100644 --- a/arch/um/include/sysdep-x86_64/kernel-offsets.h +++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/time.h> | 4 | #include <linux/time.h> |
5 | #include <linux/elf.h> | 5 | #include <linux/elf.h> |
6 | #include <asm/page.h> | 6 | #include <asm/page.h> |
7 | #include <asm/mman.h> | ||
7 | 8 | ||
8 | #define DEFINE(sym, val) \ | 9 | #define DEFINE(sym, val) \ |
9 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | 10 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) |
@@ -18,6 +19,7 @@ | |||
18 | 19 | ||
19 | void foo(void) | 20 | void foo(void) |
20 | { | 21 | { |
22 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); | ||
21 | #ifdef CONFIG_MODE_TT | 23 | #ifdef CONFIG_MODE_TT |
22 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | 24 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); |
23 | #endif | 25 | #endif |
diff --git a/arch/um/include/tt/tt.h b/arch/um/include/tt/tt.h index 808521980186..acb8356e1f98 100644 --- a/arch/um/include/tt/tt.h +++ b/arch/um/include/tt/tt.h | |||
@@ -19,7 +19,8 @@ extern int fork_tramp(void *sig_stack); | |||
19 | extern int do_proc_op(void *t, int proc_id); | 19 | extern int do_proc_op(void *t, int proc_id); |
20 | extern int tracer(int (*init_proc)(void *), void *sp); | 20 | extern int tracer(int (*init_proc)(void *), void *sp); |
21 | extern void attach_process(int pid); | 21 | extern void attach_process(int pid); |
22 | extern void tracer_panic(char *format, ...); | 22 | extern void tracer_panic(char *format, ...) |
23 | __attribute__ ((format (printf, 1, 2))); | ||
23 | extern void set_init_pid(int pid); | 24 | extern void set_init_pid(int pid); |
24 | extern int set_user_mode(void *task); | 25 | extern int set_user_mode(void *task); |
25 | extern void set_tracing(void *t, int tracing); | 26 | extern void set_tracing(void *t, int tracing); |
diff --git a/arch/um/include/user.h b/arch/um/include/user.h index 91b0ac4ad88c..39f8c8801076 100644 --- a/arch/um/include/user.h +++ b/arch/um/include/user.h | |||
@@ -6,8 +6,10 @@ | |||
6 | #ifndef __USER_H__ | 6 | #ifndef __USER_H__ |
7 | #define __USER_H__ | 7 | #define __USER_H__ |
8 | 8 | ||
9 | extern void panic(const char *fmt, ...); | 9 | extern void panic(const char *fmt, ...) |
10 | extern int printk(const char *fmt, ...); | 10 | __attribute__ ((format (printf, 1, 2))); |
11 | extern int printk(const char *fmt, ...) | ||
12 | __attribute__ ((format (printf, 1, 2))); | ||
11 | extern void schedule(void); | 13 | extern void schedule(void); |
12 | extern void *um_kmalloc(int size); | 14 | extern void *um_kmalloc(int size); |
13 | extern void *um_kmalloc_atomic(int size); | 15 | extern void *um_kmalloc_atomic(int size); |
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index fe0c29b5144d..802d7842514d 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h | |||
@@ -55,7 +55,8 @@ extern int get_pty(void); | |||
55 | extern void *um_kmalloc(int size); | 55 | extern void *um_kmalloc(int size); |
56 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); | 56 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); |
57 | extern void do_exec(int old_pid, int new_pid); | 57 | extern void do_exec(int old_pid, int new_pid); |
58 | extern void tracer_panic(char *msg, ...); | 58 | extern void tracer_panic(char *msg, ...) |
59 | __attribute__ ((format (printf, 1, 2))); | ||
59 | extern int detach(int pid, int sig); | 60 | extern int detach(int pid, int sig); |
60 | extern int attach(int pid); | 61 | extern int attach(int pid); |
61 | extern void kill_child_dead(int pid); | 62 | extern void kill_child_dead(int pid); |
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 7713e7a6f476..432cf0b97a13 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c | |||
@@ -39,7 +39,6 @@ EXPORT_SYMBOL(um_virt_to_phys); | |||
39 | EXPORT_SYMBOL(mode_tt); | 39 | EXPORT_SYMBOL(mode_tt); |
40 | EXPORT_SYMBOL(handle_page_fault); | 40 | EXPORT_SYMBOL(handle_page_fault); |
41 | EXPORT_SYMBOL(find_iomem); | 41 | EXPORT_SYMBOL(find_iomem); |
42 | EXPORT_SYMBOL(end_iomem); | ||
43 | 42 | ||
44 | #ifdef CONFIG_MODE_TT | 43 | #ifdef CONFIG_MODE_TT |
45 | EXPORT_SYMBOL(strncpy_from_user_tt); | 44 | EXPORT_SYMBOL(strncpy_from_user_tt); |
@@ -89,12 +88,10 @@ EXPORT_SYMBOL(dump_thread); | |||
89 | EXPORT_SYMBOL(do_gettimeofday); | 88 | EXPORT_SYMBOL(do_gettimeofday); |
90 | EXPORT_SYMBOL(do_settimeofday); | 89 | EXPORT_SYMBOL(do_settimeofday); |
91 | 90 | ||
92 | /* This is here because UML expands open to sys_open, not to a system | 91 | /* This is here because UML expands lseek to sys_lseek, not to a system |
93 | * call instruction. | 92 | * call instruction. |
94 | */ | 93 | */ |
95 | EXPORT_SYMBOL(sys_open); | ||
96 | EXPORT_SYMBOL(sys_lseek); | 94 | EXPORT_SYMBOL(sys_lseek); |
97 | EXPORT_SYMBOL(sys_read); | ||
98 | EXPORT_SYMBOL(sys_wait4); | 95 | EXPORT_SYMBOL(sys_wait4); |
99 | 96 | ||
100 | #ifdef CONFIG_SMP | 97 | #ifdef CONFIG_SMP |
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 901b85e8a1c6..8f49507e64ef 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c | |||
@@ -40,7 +40,7 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, | |||
40 | int fd) | 40 | int fd) |
41 | { | 41 | { |
42 | struct addr_change change; | 42 | struct addr_change change; |
43 | void *output; | 43 | char *output; |
44 | int n; | 44 | int n; |
45 | 45 | ||
46 | change.what = op; | 46 | change.what = op; |
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 6490a4ff40ac..6987d1d247a2 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c | |||
@@ -43,7 +43,7 @@ static int helper_child(void *arg) | |||
43 | (*data->pre_exec)(data->pre_data); | 43 | (*data->pre_exec)(data->pre_data); |
44 | execvp(argv[0], argv); | 44 | execvp(argv[0], argv); |
45 | errval = errno; | 45 | errval = errno; |
46 | printk("execvp of '%s' failed - errno = %d\n", argv[0], errno); | 46 | printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno); |
47 | os_write_file(data->fd, &errval, sizeof(errval)); | 47 | os_write_file(data->fd, &errval, sizeof(errval)); |
48 | kill(os_getpid(), SIGKILL); | 48 | kill(os_getpid(), SIGKILL); |
49 | return(0); | 49 | return(0); |
@@ -92,15 +92,15 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | |||
92 | close(fds[1]); | 92 | close(fds[1]); |
93 | fds[1] = -1; | 93 | fds[1] = -1; |
94 | 94 | ||
95 | /*Read the errno value from the child.*/ | 95 | /* Read the errno value from the child, if the exec failed, or get 0 if |
96 | * the exec succeeded because the pipe fd was set as close-on-exec. */ | ||
96 | n = os_read_file(fds[0], &ret, sizeof(ret)); | 97 | n = os_read_file(fds[0], &ret, sizeof(ret)); |
97 | if(n < 0){ | 98 | if (n < 0) { |
98 | printk("run_helper : read on pipe failed, ret = %d\n", -n); | 99 | printk("run_helper : read on pipe failed, ret = %d\n", -n); |
99 | ret = n; | 100 | ret = n; |
100 | kill(pid, SIGKILL); | 101 | kill(pid, SIGKILL); |
101 | CATCH_EINTR(waitpid(pid, NULL, 0)); | 102 | CATCH_EINTR(waitpid(pid, NULL, 0)); |
102 | } | 103 | } else if(n != 0){ |
103 | else if(n != 0){ | ||
104 | CATCH_EINTR(n = waitpid(pid, NULL, 0)); | 104 | CATCH_EINTR(n = waitpid(pid, NULL, 0)); |
105 | ret = -errno; | 105 | ret = -errno; |
106 | } else { | 106 | } else { |
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 6ab372da9657..c6432e729241 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <fcntl.h> | 8 | #include <fcntl.h> |
9 | #include <sys/types.h> | 9 | #include <sys/types.h> |
10 | #include <sys/mman.h> | 10 | #include <sys/mman.h> |
11 | #include <sys/statfs.h> | ||
11 | #include "kern_util.h" | 12 | #include "kern_util.h" |
12 | #include "user.h" | 13 | #include "user.h" |
13 | #include "user_util.h" | 14 | #include "user_util.h" |
@@ -19,6 +20,7 @@ | |||
19 | 20 | ||
20 | #include <sys/param.h> | 21 | #include <sys/param.h> |
21 | 22 | ||
23 | static char *default_tmpdir = "/tmp"; | ||
22 | static char *tempdir = NULL; | 24 | static char *tempdir = NULL; |
23 | 25 | ||
24 | static void __init find_tempdir(void) | 26 | static void __init find_tempdir(void) |
@@ -34,7 +36,7 @@ static void __init find_tempdir(void) | |||
34 | break; | 36 | break; |
35 | } | 37 | } |
36 | if((dir == NULL) || (*dir == '\0')) | 38 | if((dir == NULL) || (*dir == '\0')) |
37 | dir = "/tmp"; | 39 | dir = default_tmpdir; |
38 | 40 | ||
39 | tempdir = malloc(strlen(dir) + 2); | 41 | tempdir = malloc(strlen(dir) + 2); |
40 | if(tempdir == NULL){ | 42 | if(tempdir == NULL){ |
@@ -46,6 +48,96 @@ static void __init find_tempdir(void) | |||
46 | strcat(tempdir, "/"); | 48 | strcat(tempdir, "/"); |
47 | } | 49 | } |
48 | 50 | ||
51 | /* This will return 1, with the first character in buf being the | ||
52 | * character following the next instance of c in the file. This will | ||
53 | * read the file as needed. If there's an error, -errno is returned; | ||
54 | * if the end of the file is reached, 0 is returned. | ||
55 | */ | ||
56 | static int next(int fd, char *buf, int size, char c) | ||
57 | { | ||
58 | int n; | ||
59 | char *ptr; | ||
60 | |||
61 | while((ptr = strchr(buf, c)) == NULL){ | ||
62 | n = read(fd, buf, size - 1); | ||
63 | if(n == 0) | ||
64 | return 0; | ||
65 | else if(n < 0) | ||
66 | return -errno; | ||
67 | |||
68 | buf[n] = '\0'; | ||
69 | } | ||
70 | |||
71 | ptr++; | ||
72 | memmove(buf, ptr, strlen(ptr) + 1); | ||
73 | return 1; | ||
74 | } | ||
75 | |||
76 | static int checked_tmpdir = 0; | ||
77 | |||
78 | /* Look for a tmpfs mounted at /dev/shm. I couldn't find a cleaner | ||
79 | * way to do this than to parse /proc/mounts. statfs will return the | ||
80 | * same filesystem magic number and fs id for both /dev and /dev/shm | ||
81 | * when they are both tmpfs, so you can't tell if they are different | ||
82 | * filesystems. Also, there seems to be no other way of finding the | ||
83 | * mount point of a filesystem from within it. | ||
84 | * | ||
85 | * If a /dev/shm tmpfs entry is found, then we switch to using it. | ||
86 | * Otherwise, we stay with the default /tmp. | ||
87 | */ | ||
88 | static void which_tmpdir(void) | ||
89 | { | ||
90 | int fd, found; | ||
91 | char buf[128] = { '\0' }; | ||
92 | |||
93 | if(checked_tmpdir) | ||
94 | return; | ||
95 | |||
96 | checked_tmpdir = 1; | ||
97 | |||
98 | printf("Checking for tmpfs mount on /dev/shm..."); | ||
99 | |||
100 | fd = open("/proc/mounts", O_RDONLY); | ||
101 | if(fd < 0){ | ||
102 | printf("failed to open /proc/mounts, errno = %d\n", errno); | ||
103 | return; | ||
104 | } | ||
105 | |||
106 | while(1){ | ||
107 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' '); | ||
108 | if(found != 1) | ||
109 | break; | ||
110 | |||
111 | if(!strncmp(buf, "/dev/shm", strlen("/dev/shm"))) | ||
112 | goto found; | ||
113 | |||
114 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), '\n'); | ||
115 | if(found != 1) | ||
116 | break; | ||
117 | } | ||
118 | |||
119 | err: | ||
120 | if(found == 0) | ||
121 | printf("nothing mounted on /dev/shm\n"); | ||
122 | else if(found < 0) | ||
123 | printf("read returned errno %d\n", -found); | ||
124 | |||
125 | return; | ||
126 | |||
127 | found: | ||
128 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' '); | ||
129 | if(found != 1) | ||
130 | goto err; | ||
131 | |||
132 | if(strncmp(buf, "tmpfs", strlen("tmpfs"))){ | ||
133 | printf("not tmpfs\n"); | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | printf("OK\n"); | ||
138 | default_tmpdir = "/dev/shm"; | ||
139 | } | ||
140 | |||
49 | /* | 141 | /* |
50 | * This proc still used in tt-mode | 142 | * This proc still used in tt-mode |
51 | * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). | 143 | * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). |
@@ -53,33 +145,37 @@ static void __init find_tempdir(void) | |||
53 | */ | 145 | */ |
54 | int make_tempfile(const char *template, char **out_tempname, int do_unlink) | 146 | int make_tempfile(const char *template, char **out_tempname, int do_unlink) |
55 | { | 147 | { |
56 | char tempname[MAXPATHLEN]; | 148 | char *tempname; |
57 | int fd; | 149 | int fd; |
58 | 150 | ||
151 | which_tmpdir(); | ||
152 | tempname = malloc(MAXPATHLEN); | ||
153 | |||
59 | find_tempdir(); | 154 | find_tempdir(); |
60 | if (*template != '/') | 155 | if (template[0] != '/') |
61 | strcpy(tempname, tempdir); | 156 | strcpy(tempname, tempdir); |
62 | else | 157 | else |
63 | *tempname = 0; | 158 | tempname[0] = '\0'; |
64 | strcat(tempname, template); | 159 | strcat(tempname, template); |
65 | fd = mkstemp(tempname); | 160 | fd = mkstemp(tempname); |
66 | if(fd < 0){ | 161 | if(fd < 0){ |
67 | fprintf(stderr, "open - cannot create %s: %s\n", tempname, | 162 | fprintf(stderr, "open - cannot create %s: %s\n", tempname, |
68 | strerror(errno)); | 163 | strerror(errno)); |
69 | return -1; | 164 | goto out; |
70 | } | 165 | } |
71 | if(do_unlink && (unlink(tempname) < 0)){ | 166 | if(do_unlink && (unlink(tempname) < 0)){ |
72 | perror("unlink"); | 167 | perror("unlink"); |
73 | return -1; | 168 | goto out; |
74 | } | 169 | } |
75 | if(out_tempname){ | 170 | if(out_tempname){ |
76 | *out_tempname = strdup(tempname); | 171 | *out_tempname = tempname; |
77 | if(*out_tempname == NULL){ | 172 | } else { |
78 | perror("strdup"); | 173 | free(tempname); |
79 | return -1; | ||
80 | } | ||
81 | } | 174 | } |
82 | return(fd); | 175 | return(fd); |
176 | out: | ||
177 | free(tempname); | ||
178 | return -1; | ||
83 | } | 179 | } |
84 | 180 | ||
85 | #define TEMPNAME_TEMPLATE "vm_file-XXXXXX" | 181 | #define TEMPNAME_TEMPLATE "vm_file-XXXXXX" |
@@ -134,3 +230,26 @@ int create_mem_file(unsigned long long len) | |||
134 | } | 230 | } |
135 | return(fd); | 231 | return(fd); |
136 | } | 232 | } |
233 | |||
234 | |||
235 | void check_tmpexec(void) | ||
236 | { | ||
237 | void *addr; | ||
238 | int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); | ||
239 | |||
240 | addr = mmap(NULL, UM_KERN_PAGE_SIZE, | ||
241 | PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); | ||
242 | printf("Checking PROT_EXEC mmap in %s...",tempdir); | ||
243 | fflush(stdout); | ||
244 | if(addr == MAP_FAILED){ | ||
245 | err = errno; | ||
246 | perror("failed"); | ||
247 | if(err == EPERM) | ||
248 | printf("%s must be not mounted noexec\n",tempdir); | ||
249 | exit(1); | ||
250 | } | ||
251 | printf("OK\n"); | ||
252 | munmap(addr, UM_KERN_PAGE_SIZE); | ||
253 | |||
254 | close(fd); | ||
255 | } | ||
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 8176b0b52047..3505f44f8a25 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
@@ -190,7 +190,7 @@ int os_unmap_memory(void *addr, int len) | |||
190 | } | 190 | } |
191 | 191 | ||
192 | #ifndef MADV_REMOVE | 192 | #ifndef MADV_REMOVE |
193 | #define MADV_REMOVE 0x5 /* remove these pages & resources */ | 193 | #define MADV_REMOVE KERNEL_MADV_REMOVE |
194 | #endif | 194 | #endif |
195 | 195 | ||
196 | int os_drop_memory(void *addr, int length) | 196 | int os_drop_memory(void *addr, int length) |
@@ -216,7 +216,7 @@ int can_drop_memory(void) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, | 218 | addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, |
219 | MAP_PRIVATE, fd, 0); | 219 | MAP_SHARED, fd, 0); |
220 | if(addr == MAP_FAILED){ | 220 | if(addr == MAP_FAILED){ |
221 | printk("Mapping test memory file failed, err = %d\n", -errno); | 221 | printk("Mapping test memory file failed, err = %d\n", -errno); |
222 | return 0; | 222 | return 0; |
@@ -266,11 +266,11 @@ void init_new_thread_signals(int altstack) | |||
266 | 266 | ||
267 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) | 267 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) |
268 | { | 268 | { |
269 | sigjmp_buf buf; | 269 | jmp_buf buf; |
270 | int n, enable; | 270 | int n, enable; |
271 | 271 | ||
272 | *jmp_ptr = &buf; | 272 | *jmp_ptr = &buf; |
273 | n = UML_SIGSETJMP(&buf, enable); | 273 | n = UML_SETJMP(&buf, enable); |
274 | if(n != 0) | 274 | if(n != 0) |
275 | return(n); | 275 | return(n); |
276 | (*fn)(arg); | 276 | (*fn)(arg); |
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 9ba942947146..00e9388e947a 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c | |||
@@ -304,8 +304,8 @@ out_clear_poll: | |||
304 | .size = 0, | 304 | .size = 0, |
305 | .used = 0 }); | 305 | .used = 0 }); |
306 | out_free: | 306 | out_free: |
307 | kfree(p); | ||
308 | sigio_unlock(); | 307 | sigio_unlock(); |
308 | kfree(p); | ||
309 | out_close2: | 309 | out_close2: |
310 | close(l_sigio_private[0]); | 310 | close(l_sigio_private[0]); |
311 | close(l_sigio_private[1]); | 311 | close(l_sigio_private[1]); |
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index fbb080c2fc26..b3c11cfa995a 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c | |||
@@ -82,8 +82,8 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) | |||
82 | if (offset) { | 82 | if (offset) { |
83 | data = (unsigned long *)(mm_idp->stack + | 83 | data = (unsigned long *)(mm_idp->stack + |
84 | offset - UML_CONFIG_STUB_DATA); | 84 | offset - UML_CONFIG_STUB_DATA); |
85 | printk("do_syscall_stub : ret = %d, offset = %d, " | 85 | printk("do_syscall_stub : ret = %ld, offset = %ld, " |
86 | "data = 0x%x\n", ret, offset, data); | 86 | "data = %p\n", ret, offset, data); |
87 | syscall = (unsigned long *)((unsigned long)data + data[0]); | 87 | syscall = (unsigned long *)((unsigned long)data + data[0]); |
88 | printk("do_syscall_stub: syscall %ld failed, return value = " | 88 | printk("do_syscall_stub: syscall %ld failed, return value = " |
89 | "0x%lx, expected return value = 0x%lx\n", | 89 | "0x%lx, expected return value = 0x%lx\n", |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index bbf34cb91ce1..0776bc18ca85 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -265,7 +265,7 @@ void userspace(union uml_pt_regs *regs) | |||
265 | if(err) | 265 | if(err) |
266 | panic("userspace - could not resume userspace process, " | 266 | panic("userspace - could not resume userspace process, " |
267 | "pid=%d, ptrace operation = %d, errno = %d\n", | 267 | "pid=%d, ptrace operation = %d, errno = %d\n", |
268 | op, errno); | 268 | pid, op, errno); |
269 | 269 | ||
270 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); | 270 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); |
271 | if(err < 0) | 271 | if(err < 0) |
@@ -369,7 +369,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
369 | */ | 369 | */ |
370 | wait_stub_done(pid, -1, "copy_context_skas0"); | 370 | wait_stub_done(pid, -1, "copy_context_skas0"); |
371 | if (child_data->err != UML_CONFIG_STUB_DATA) | 371 | if (child_data->err != UML_CONFIG_STUB_DATA) |
372 | panic("copy_context_skas0 - stub-child reports error %d\n", | 372 | panic("copy_context_skas0 - stub-child reports error %ld\n", |
373 | child_data->err); | 373 | child_data->err); |
374 | 374 | ||
375 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, | 375 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, |
@@ -434,7 +434,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
434 | void (*handler)(int)) | 434 | void (*handler)(int)) |
435 | { | 435 | { |
436 | unsigned long flags; | 436 | unsigned long flags; |
437 | sigjmp_buf switch_buf, fork_buf; | 437 | jmp_buf switch_buf, fork_buf; |
438 | int enable; | 438 | int enable; |
439 | 439 | ||
440 | *switch_buf_ptr = &switch_buf; | 440 | *switch_buf_ptr = &switch_buf; |
@@ -450,7 +450,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
450 | */ | 450 | */ |
451 | flags = get_signals(); | 451 | flags = get_signals(); |
452 | block_signals(); | 452 | block_signals(); |
453 | if(UML_SIGSETJMP(&fork_buf, enable) == 0) | 453 | if(UML_SETJMP(&fork_buf, enable) == 0) |
454 | new_thread_proc(stack, handler); | 454 | new_thread_proc(stack, handler); |
455 | 455 | ||
456 | remove_sigstack(); | 456 | remove_sigstack(); |
@@ -466,35 +466,35 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
466 | 466 | ||
467 | void thread_wait(void *sw, void *fb) | 467 | void thread_wait(void *sw, void *fb) |
468 | { | 468 | { |
469 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; | 469 | jmp_buf buf, **switch_buf = sw, *fork_buf; |
470 | int enable; | 470 | int enable; |
471 | 471 | ||
472 | *switch_buf = &buf; | 472 | *switch_buf = &buf; |
473 | fork_buf = fb; | 473 | fork_buf = fb; |
474 | if(UML_SIGSETJMP(&buf, enable) == 0) | 474 | if(UML_SETJMP(&buf, enable) == 0) |
475 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); | 475 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); |
476 | } | 476 | } |
477 | 477 | ||
478 | void switch_threads(void *me, void *next) | 478 | void switch_threads(void *me, void *next) |
479 | { | 479 | { |
480 | sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; | 480 | jmp_buf my_buf, **me_ptr = me, *next_buf = next; |
481 | int enable; | 481 | int enable; |
482 | 482 | ||
483 | *me_ptr = &my_buf; | 483 | *me_ptr = &my_buf; |
484 | if(UML_SIGSETJMP(&my_buf, enable) == 0) | 484 | if(UML_SETJMP(&my_buf, enable) == 0) |
485 | UML_SIGLONGJMP(next_buf, 1); | 485 | UML_LONGJMP(next_buf, 1); |
486 | } | 486 | } |
487 | 487 | ||
488 | static sigjmp_buf initial_jmpbuf; | 488 | static jmp_buf initial_jmpbuf; |
489 | 489 | ||
490 | /* XXX Make these percpu */ | 490 | /* XXX Make these percpu */ |
491 | static void (*cb_proc)(void *arg); | 491 | static void (*cb_proc)(void *arg); |
492 | static void *cb_arg; | 492 | static void *cb_arg; |
493 | static sigjmp_buf *cb_back; | 493 | static jmp_buf *cb_back; |
494 | 494 | ||
495 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | 495 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) |
496 | { | 496 | { |
497 | sigjmp_buf **switch_buf = switch_buf_ptr; | 497 | jmp_buf **switch_buf = switch_buf_ptr; |
498 | int n, enable; | 498 | int n, enable; |
499 | 499 | ||
500 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, | 500 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, |
@@ -502,7 +502,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
502 | SIGVTALRM, -1); | 502 | SIGVTALRM, -1); |
503 | 503 | ||
504 | *fork_buf_ptr = &initial_jmpbuf; | 504 | *fork_buf_ptr = &initial_jmpbuf; |
505 | n = UML_SIGSETJMP(&initial_jmpbuf, enable); | 505 | n = UML_SETJMP(&initial_jmpbuf, enable); |
506 | switch(n){ | 506 | switch(n){ |
507 | case INIT_JMP_NEW_THREAD: | 507 | case INIT_JMP_NEW_THREAD: |
508 | new_thread_proc((void *) stack, new_thread_handler); | 508 | new_thread_proc((void *) stack, new_thread_handler); |
@@ -512,7 +512,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
512 | break; | 512 | break; |
513 | case INIT_JMP_CALLBACK: | 513 | case INIT_JMP_CALLBACK: |
514 | (*cb_proc)(cb_arg); | 514 | (*cb_proc)(cb_arg); |
515 | UML_SIGLONGJMP(cb_back, 1); | 515 | UML_LONGJMP(cb_back, 1); |
516 | break; | 516 | break; |
517 | case INIT_JMP_HALT: | 517 | case INIT_JMP_HALT: |
518 | kmalloc_ok = 0; | 518 | kmalloc_ok = 0; |
@@ -523,12 +523,12 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
523 | default: | 523 | default: |
524 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); | 524 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); |
525 | } | 525 | } |
526 | UML_SIGLONGJMP(*switch_buf, 1); | 526 | UML_LONGJMP(*switch_buf, 1); |
527 | } | 527 | } |
528 | 528 | ||
529 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) | 529 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) |
530 | { | 530 | { |
531 | sigjmp_buf here; | 531 | jmp_buf here; |
532 | int enable; | 532 | int enable; |
533 | 533 | ||
534 | cb_proc = proc; | 534 | cb_proc = proc; |
@@ -536,8 +536,8 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
536 | cb_back = &here; | 536 | cb_back = &here; |
537 | 537 | ||
538 | block_signals(); | 538 | block_signals(); |
539 | if(UML_SIGSETJMP(&here, enable) == 0) | 539 | if(UML_SETJMP(&here, enable) == 0) |
540 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); | 540 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); |
541 | unblock_signals(); | 541 | unblock_signals(); |
542 | 542 | ||
543 | cb_proc = NULL; | 543 | cb_proc = NULL; |
@@ -548,13 +548,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
548 | void halt_skas(void) | 548 | void halt_skas(void) |
549 | { | 549 | { |
550 | block_signals(); | 550 | block_signals(); |
551 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_HALT); | 551 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT); |
552 | } | 552 | } |
553 | 553 | ||
554 | void reboot_skas(void) | 554 | void reboot_skas(void) |
555 | { | 555 | { |
556 | block_signals(); | 556 | block_signals(); |
557 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); | 557 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); |
558 | } | 558 | } |
559 | 559 | ||
560 | void switch_mm_skas(struct mm_id *mm_idp) | 560 | void switch_mm_skas(struct mm_id *mm_idp) |
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 387e26af301a..503148504009 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -296,29 +296,7 @@ static void __init check_ptrace(void) | |||
296 | check_sysemu(); | 296 | check_sysemu(); |
297 | } | 297 | } |
298 | 298 | ||
299 | extern int create_tmp_file(unsigned long long len); | 299 | extern void check_tmpexec(void); |
300 | |||
301 | static void check_tmpexec(void) | ||
302 | { | ||
303 | void *addr; | ||
304 | int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); | ||
305 | |||
306 | addr = mmap(NULL, UM_KERN_PAGE_SIZE, | ||
307 | PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); | ||
308 | printf("Checking PROT_EXEC mmap in /tmp..."); | ||
309 | fflush(stdout); | ||
310 | if(addr == MAP_FAILED){ | ||
311 | err = errno; | ||
312 | perror("failed"); | ||
313 | if(err == EPERM) | ||
314 | printf("/tmp must be not mounted noexec\n"); | ||
315 | exit(1); | ||
316 | } | ||
317 | printf("OK\n"); | ||
318 | munmap(addr, UM_KERN_PAGE_SIZE); | ||
319 | |||
320 | close(fd); | ||
321 | } | ||
322 | 300 | ||
323 | void os_early_checks(void) | 301 | void os_early_checks(void) |
324 | { | 302 | { |
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c index ba21f0e04a2f..120abbe4e3ce 100644 --- a/arch/um/os-Linux/sys-i386/tls.c +++ b/arch/um/os-Linux/sys-i386/tls.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <errno.h> | ||
1 | #include <linux/unistd.h> | 2 | #include <linux/unistd.h> |
2 | #include "sysdep/tls.h" | 3 | #include "sysdep/tls.h" |
3 | #include "user_util.h" | 4 | #include "user_util.h" |
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c index a9f6b26f9828..90b29ae9af46 100644 --- a/arch/um/os-Linux/trap.c +++ b/arch/um/os-Linux/trap.c | |||
@@ -35,7 +35,7 @@ void os_fill_handlinfo(struct kern_handlers h) | |||
35 | 35 | ||
36 | void do_longjmp(void *b, int val) | 36 | void do_longjmp(void *b, int val) |
37 | { | 37 | { |
38 | sigjmp_buf *buf = b; | 38 | jmp_buf *buf = b; |
39 | 39 | ||
40 | UML_SIGLONGJMP(buf, val); | 40 | UML_LONGJMP(buf, val); |
41 | } | 41 | } |
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c index 166fb66995df..e523719330b2 100644 --- a/arch/um/os-Linux/uaccess.c +++ b/arch/um/os-Linux/uaccess.c | |||
@@ -16,9 +16,9 @@ unsigned long __do_user_copy(void *to, const void *from, int n, | |||
16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; | 16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; |
17 | int enable; | 17 | int enable; |
18 | 18 | ||
19 | sigjmp_buf jbuf; | 19 | jmp_buf jbuf; |
20 | *fault_catcher = &jbuf; | 20 | *fault_catcher = &jbuf; |
21 | if(UML_SIGSETJMP(&jbuf, enable) == 0){ | 21 | if(UML_SETJMP(&jbuf, enable) == 0){ |
22 | (*op)(to, from, n); | 22 | (*op)(to, from, n); |
23 | ret = 0; | 23 | ret = 0; |
24 | *faulted_out = 0; | 24 | *faulted_out = 0; |
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index 198e59163288..34bfc1bb9e38 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c | |||
@@ -120,7 +120,8 @@ static int not_dead_yet(char *dir) | |||
120 | 120 | ||
121 | dead = 0; | 121 | dead = 0; |
122 | fd = open(file, O_RDONLY); | 122 | fd = open(file, O_RDONLY); |
123 | if(fd < 0){ | 123 | if(fd < 0) { |
124 | fd = -errno; | ||
124 | if(fd != -ENOENT){ | 125 | if(fd != -ENOENT){ |
125 | printk("not_dead_yet : couldn't open pid file '%s', " | 126 | printk("not_dead_yet : couldn't open pid file '%s', " |
126 | "err = %d\n", file, -fd); | 127 | "err = %d\n", file, -fd); |
@@ -130,9 +131,13 @@ static int not_dead_yet(char *dir) | |||
130 | 131 | ||
131 | err = 0; | 132 | err = 0; |
132 | n = read(fd, pid, sizeof(pid)); | 133 | n = read(fd, pid, sizeof(pid)); |
133 | if(n <= 0){ | 134 | if(n < 0){ |
135 | printk("not_dead_yet : couldn't read pid file '%s', " | ||
136 | "err = %d\n", file, errno); | ||
137 | goto out_close; | ||
138 | } else if(n == 0){ | ||
134 | printk("not_dead_yet : couldn't read pid file '%s', " | 139 | printk("not_dead_yet : couldn't read pid file '%s', " |
135 | "err = %d\n", file, -n); | 140 | "0-byte read\n", file); |
136 | goto out_close; | 141 | goto out_close; |
137 | } | 142 | } |
138 | 143 | ||
@@ -155,9 +160,9 @@ static int not_dead_yet(char *dir) | |||
155 | 160 | ||
156 | return err; | 161 | return err; |
157 | 162 | ||
158 | out_close: | 163 | out_close: |
159 | close(fd); | 164 | close(fd); |
160 | out: | 165 | out: |
161 | return 0; | 166 | return 0; |
162 | } | 167 | } |
163 | 168 | ||
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 8da6ab31152a..2598158e1f53 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c | |||
@@ -18,14 +18,19 @@ extern void *memmove(void *, const void *, size_t); | |||
18 | extern void *memset(void *, int, size_t); | 18 | extern void *memset(void *, int, size_t); |
19 | extern int printf(const char *, ...); | 19 | extern int printf(const char *, ...); |
20 | 20 | ||
21 | /* If they're not defined, the export is included in lib/string.c.*/ | ||
22 | #ifdef __HAVE_ARCH_STRLEN | ||
21 | EXPORT_SYMBOL(strlen); | 23 | EXPORT_SYMBOL(strlen); |
24 | #endif | ||
25 | #ifdef __HAVE_ARCH_STRSTR | ||
26 | EXPORT_SYMBOL(strstr); | ||
27 | #endif | ||
28 | |||
22 | EXPORT_SYMBOL(memcpy); | 29 | EXPORT_SYMBOL(memcpy); |
23 | EXPORT_SYMBOL(memmove); | 30 | EXPORT_SYMBOL(memmove); |
24 | EXPORT_SYMBOL(memset); | 31 | EXPORT_SYMBOL(memset); |
25 | EXPORT_SYMBOL(printf); | 32 | EXPORT_SYMBOL(printf); |
26 | 33 | ||
27 | EXPORT_SYMBOL(strstr); | ||
28 | |||
29 | /* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms. | 34 | /* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms. |
30 | * However, the modules will use the CRC defined *here*, no matter if it is | 35 | * However, the modules will use the CRC defined *here*, no matter if it is |
31 | * good; so the versions of these symbols will always match | 36 | * good; so the versions of these symbols will always match |
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index e32065e2fdc8..c47a2a7ce70e 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c | |||
@@ -104,7 +104,7 @@ void setup_hostinfo(void) | |||
104 | int setjmp_wrapper(void (*proc)(void *, void *), ...) | 104 | int setjmp_wrapper(void (*proc)(void *, void *), ...) |
105 | { | 105 | { |
106 | va_list args; | 106 | va_list args; |
107 | sigjmp_buf buf; | 107 | jmp_buf buf; |
108 | int n; | 108 | int n; |
109 | 109 | ||
110 | n = sigsetjmp(buf, 1); | 110 | n = sigsetjmp(buf, 1); |
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index b696b451774c..5e7a9c310aa5 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules | |||
@@ -9,10 +9,8 @@ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) | |||
9 | 9 | ||
10 | $(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \ | 10 | $(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \ |
11 | c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@)) | 11 | c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@)) |
12 | $(USER_OBJS): cmd_checksrc = | 12 | $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ |
13 | $(USER_OBJS): quiet_cmd_checksrc = | 13 | -Dunix -D__unix__ -D__$(SUBARCH)__ |
14 | $(USER_OBJS): cmd_force_checksrc = | ||
15 | $(USER_OBJS): quiet_cmd_force_checksrc = | ||
16 | 14 | ||
17 | 15 | ||
18 | # The stubs and unmap.o can't try to call mcount or update basic block data | 16 | # The stubs and unmap.o can't try to call mcount or update basic block data |
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c index db524ab3f743..2a1eac1859ce 100644 --- a/arch/um/sys-i386/ksyms.c +++ b/arch/um/sys-i386/ksyms.c | |||
@@ -15,7 +15,3 @@ EXPORT_SYMBOL(__up_wakeup); | |||
15 | 15 | ||
16 | /* Networking helper routines. */ | 16 | /* Networking helper routines. */ |
17 | EXPORT_SYMBOL(csum_partial); | 17 | EXPORT_SYMBOL(csum_partial); |
18 | |||
19 | /* delay core functions */ | ||
20 | EXPORT_SYMBOL(__const_udelay); | ||
21 | EXPORT_SYMBOL(__udelay); | ||
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c index 9f3bd8ed78f5..40aa88531446 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/um/sys-i386/ptrace_user.c | |||
@@ -57,7 +57,7 @@ static void write_debugregs(int pid, unsigned long *regs) | |||
57 | if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i], | 57 | if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i], |
58 | regs[i]) < 0) | 58 | regs[i]) < 0) |
59 | printk("write_debugregs - ptrace failed on " | 59 | printk("write_debugregs - ptrace failed on " |
60 | "register %d, value = 0x%x, errno = %d\n", i, | 60 | "register %d, value = 0x%lx, errno = %d\n", i, |
61 | regs[i], errno); | 61 | regs[i], errno); |
62 | } | 62 | } |
63 | } | 63 | } |
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index f5d0e1c37ea2..0709fc6670c2 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c | |||
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, | |||
57 | return(0); | 57 | return(0); |
58 | } | 58 | } |
59 | 59 | ||
60 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate __user *to_fp, | 60 | int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp, |
61 | struct pt_regs *regs, unsigned long sp) | 61 | struct pt_regs *regs, unsigned long sp) |
62 | { | 62 | { |
63 | struct sigcontext sc; | 63 | struct sigcontext sc; |
@@ -132,7 +132,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, | |||
132 | return(err); | 132 | return(err); |
133 | } | 133 | } |
134 | 134 | ||
135 | int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp, | 135 | int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, |
136 | struct sigcontext *from, int fpsize, unsigned long sp) | 136 | struct sigcontext *from, int fpsize, unsigned long sp) |
137 | { | 137 | { |
138 | struct _fpstate __user *to_fp; | 138 | struct _fpstate __user *to_fp; |
@@ -147,7 +147,7 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp, | |||
147 | * delivery. The sp passed in is the original, and this needs | 147 | * delivery. The sp passed in is the original, and this needs |
148 | * to be restored, so we stick it in separately. | 148 | * to be restored, so we stick it in separately. |
149 | */ | 149 | */ |
150 | err |= copy_to_user(&SC_SP(to), sp, sizeof(sp)); | 150 | err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp)); |
151 | 151 | ||
152 | if(from_fp != NULL){ | 152 | if(from_fp != NULL){ |
153 | err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); | 153 | err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); |
@@ -167,7 +167,7 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from) | |||
167 | return(ret); | 167 | return(ret); |
168 | } | 168 | } |
169 | 169 | ||
170 | static int copy_sc_to_user(struct sigcontext *to, struct _fpstate __user *fp, | 170 | static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp, |
171 | struct pt_regs *from, unsigned long sp) | 171 | struct pt_regs *from, unsigned long sp) |
172 | { | 172 | { |
173 | return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), | 173 | return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), |
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c index a37f672ec964..2355dc19c46c 100644 --- a/arch/um/sys-i386/stub_segv.c +++ b/arch/um/sys-i386/stub_segv.c | |||
@@ -27,6 +27,6 @@ stub_segv_handler(int sig) | |||
27 | * the stack in its original form when we do the sigreturn here, by | 27 | * the stack in its original form when we do the sigreturn here, by |
28 | * hand. | 28 | * hand. |
29 | */ | 29 | */ |
30 | __asm__("mov %0,%%esp ; movl %1, %%eax ; " | 30 | __asm__ __volatile__("mov %0,%%esp ; movl %1, %%eax ; " |
31 | "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); | 31 | "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); |
32 | } | 32 | } |
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c index a3188e861cc7..71b9796258ef 100644 --- a/arch/um/sys-i386/tls.c +++ b/arch/um/sys-i386/tls.c | |||
@@ -378,7 +378,7 @@ static int __init __setup_host_supports_tls(void) { | |||
378 | } else | 378 | } else |
379 | printk(KERN_ERR " Host TLS support NOT detected! " | 379 | printk(KERN_ERR " Host TLS support NOT detected! " |
380 | "TLS support inside UML will not work\n"); | 380 | "TLS support inside UML will not work\n"); |
381 | return 1; | 381 | return 0; |
382 | } | 382 | } |
383 | 383 | ||
384 | __initcall(__setup_host_supports_tls); | 384 | __initcall(__setup_host_supports_tls); |
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index e75c4e1838b0..a4c46a8af008 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c | |||
@@ -137,7 +137,7 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp, | |||
137 | * delivery. The sp passed in is the original, and this needs | 137 | * delivery. The sp passed in is the original, and this needs |
138 | * to be restored, so we stick it in separately. | 138 | * to be restored, so we stick it in separately. |
139 | */ | 139 | */ |
140 | err |= copy_to_user(&SC_SP(to), sp, sizeof(sp)); | 140 | err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp)); |
141 | 141 | ||
142 | if(from_fp != NULL){ | 142 | if(from_fp != NULL){ |
143 | err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); | 143 | err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); |
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c index a27099533198..1c967026c957 100644 --- a/arch/um/sys-x86_64/stub_segv.c +++ b/arch/um/sys-x86_64/stub_segv.c | |||
@@ -33,7 +33,7 @@ stub_segv_handler(int sig) | |||
33 | struct ucontext *uc; | 33 | struct ucontext *uc; |
34 | int pid; | 34 | int pid; |
35 | 35 | ||
36 | __asm__("movq %%rdx, %0" : "=g" (uc) :); | 36 | __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); |
37 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), | 37 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), |
38 | &uc->uc_mcontext); | 38 | &uc->uc_mcontext); |
39 | 39 | ||
@@ -44,8 +44,8 @@ stub_segv_handler(int sig) | |||
44 | * the signal frame. So, we use the ucontext pointer, which we know | 44 | * the signal frame. So, we use the ucontext pointer, which we know |
45 | * already, to get the signal frame pointer, and add 8 to that. | 45 | * already, to get the signal frame pointer, and add 8 to that. |
46 | */ | 46 | */ |
47 | __asm__("movq %0, %%rsp; movq %1, %%rax ; syscall": : | 47 | __asm__ __volatile__("movq %0, %%rsp; movq %1, %%rax ; syscall": : |
48 | "g" ((unsigned long) container_of(uc, struct rt_sigframe, | 48 | "g" ((unsigned long) |
49 | uc) + 8), | 49 | container_of(uc, struct rt_sigframe, uc) + 8), |
50 | "g" (__NR_rt_sigreturn)); | 50 | "g" (__NR_rt_sigreturn)); |
51 | } | 51 | } |
diff --git a/arch/v850/kernel/v850_ksyms.c b/arch/v850/kernel/v850_ksyms.c index 8ffc29c1c89d..6bcfcfe88384 100644 --- a/arch/v850/kernel/v850_ksyms.c +++ b/arch/v850/kernel/v850_ksyms.c | |||
@@ -43,7 +43,6 @@ EXPORT_SYMBOL (strncmp); | |||
43 | EXPORT_SYMBOL (strchr); | 43 | EXPORT_SYMBOL (strchr); |
44 | EXPORT_SYMBOL (strlen); | 44 | EXPORT_SYMBOL (strlen); |
45 | EXPORT_SYMBOL (strnlen); | 45 | EXPORT_SYMBOL (strnlen); |
46 | EXPORT_SYMBOL (strpbrk); | ||
47 | EXPORT_SYMBOL (strrchr); | 46 | EXPORT_SYMBOL (strrchr); |
48 | EXPORT_SYMBOL (strstr); | 47 | EXPORT_SYMBOL (strstr); |
49 | EXPORT_SYMBOL (memset); | 48 | EXPORT_SYMBOL (memset); |
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 4310b4a311a5..408d44a59756 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -136,6 +136,11 @@ config X86_L1_CACHE_SHIFT | |||
136 | default "7" if GENERIC_CPU || MPSC | 136 | default "7" if GENERIC_CPU || MPSC |
137 | default "6" if MK8 | 137 | default "6" if MK8 |
138 | 138 | ||
139 | config X86_INTERNODE_CACHE_BYTES | ||
140 | int | ||
141 | default "4096" if X86_VSMP | ||
142 | default X86_L1_CACHE_BYTES if !X86_VSMP | ||
143 | |||
139 | config X86_TSC | 144 | config X86_TSC |
140 | bool | 145 | bool |
141 | default y | 146 | default y |
@@ -283,6 +288,11 @@ config K8_NUMA | |||
283 | Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA | 288 | Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA |
284 | instead, which also takes priority if both are compiled in. | 289 | instead, which also takes priority if both are compiled in. |
285 | 290 | ||
291 | config NODES_SHIFT | ||
292 | int | ||
293 | default "6" | ||
294 | depends on NEED_MULTIPLE_NODES | ||
295 | |||
286 | # Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig. | 296 | # Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig. |
287 | 297 | ||
288 | config X86_64_ACPI_NUMA | 298 | config X86_64_ACPI_NUMA |
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 585fd4a559c8..e573e2ab5510 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile | |||
@@ -24,37 +24,37 @@ | |||
24 | LDFLAGS := -m elf_x86_64 | 24 | LDFLAGS := -m elf_x86_64 |
25 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S | 25 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S |
26 | LDFLAGS_vmlinux := | 26 | LDFLAGS_vmlinux := |
27 | |||
28 | CHECKFLAGS += -D__x86_64__ -m64 | 27 | CHECKFLAGS += -D__x86_64__ -m64 |
29 | 28 | ||
29 | cflags-y := | ||
30 | cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) | 30 | cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) |
31 | cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) | 31 | cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) |
32 | cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) | 32 | cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) |
33 | CFLAGS += $(cflags-y) | ||
34 | 33 | ||
35 | CFLAGS += -m64 | 34 | cflags-y += -m64 |
36 | CFLAGS += -mno-red-zone | 35 | cflags-y += -mno-red-zone |
37 | CFLAGS += -mcmodel=kernel | 36 | cflags-y += -mcmodel=kernel |
38 | CFLAGS += -pipe | 37 | cflags-y += -pipe |
39 | cflags-$(CONFIG_REORDER) += -ffunction-sections | 38 | cflags-$(CONFIG_REORDER) += -ffunction-sections |
40 | # this makes reading assembly source easier, but produces worse code | 39 | # this makes reading assembly source easier, but produces worse code |
41 | # actually it makes the kernel smaller too. | 40 | # actually it makes the kernel smaller too. |
42 | CFLAGS += -fno-reorder-blocks | 41 | cflags-y += -fno-reorder-blocks |
43 | CFLAGS += -Wno-sign-compare | 42 | cflags-y += -Wno-sign-compare |
44 | ifneq ($(CONFIG_UNWIND_INFO),y) | 43 | ifneq ($(CONFIG_UNWIND_INFO),y) |
45 | CFLAGS += -fno-asynchronous-unwind-tables | 44 | cflags-y += -fno-asynchronous-unwind-tables |
46 | endif | 45 | endif |
47 | ifneq ($(CONFIG_DEBUG_INFO),y) | 46 | ifneq ($(CONFIG_DEBUG_INFO),y) |
48 | # -fweb shrinks the kernel a bit, but the difference is very small | 47 | # -fweb shrinks the kernel a bit, but the difference is very small |
49 | # it also messes up debugging, so don't use it for now. | 48 | # it also messes up debugging, so don't use it for now. |
50 | #CFLAGS += $(call cc-option,-fweb) | 49 | #cflags-y += $(call cc-option,-fweb) |
51 | endif | 50 | endif |
52 | # -funit-at-a-time shrinks the kernel .text considerably | 51 | # -funit-at-a-time shrinks the kernel .text considerably |
53 | # unfortunately it makes reading oopses harder. | 52 | # unfortunately it makes reading oopses harder. |
54 | CFLAGS += $(call cc-option,-funit-at-a-time) | 53 | cflags-y += $(call cc-option,-funit-at-a-time) |
55 | # prevent gcc from generating any FP code by mistake | 54 | # prevent gcc from generating any FP code by mistake |
56 | CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) | 55 | cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) |
57 | 56 | ||
57 | CFLAGS += $(cflags-y) | ||
58 | AFLAGS += -m64 | 58 | AFLAGS += -m64 |
59 | 59 | ||
60 | head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o | 60 | head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o |
diff --git a/arch/x86_64/boot/video.S b/arch/x86_64/boot/video.S index 0587477c99f2..32327bb37aff 100644 --- a/arch/x86_64/boot/video.S +++ b/arch/x86_64/boot/video.S | |||
@@ -97,6 +97,7 @@ | |||
97 | #define PARAM_VESAPM_OFF 0x30 | 97 | #define PARAM_VESAPM_OFF 0x30 |
98 | #define PARAM_LFB_PAGES 0x32 | 98 | #define PARAM_LFB_PAGES 0x32 |
99 | #define PARAM_VESA_ATTRIB 0x34 | 99 | #define PARAM_VESA_ATTRIB 0x34 |
100 | #define PARAM_CAPABILITIES 0x36 | ||
100 | 101 | ||
101 | /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ | 102 | /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ |
102 | #ifdef CONFIG_VIDEO_RETAIN | 103 | #ifdef CONFIG_VIDEO_RETAIN |
@@ -233,6 +234,10 @@ mopar_gr: | |||
233 | movw 18(%di), %ax | 234 | movw 18(%di), %ax |
234 | movl %eax, %fs:(PARAM_LFB_SIZE) | 235 | movl %eax, %fs:(PARAM_LFB_SIZE) |
235 | 236 | ||
237 | # store mode capabilities | ||
238 | movl 10(%di), %eax | ||
239 | movl %eax, %fs:(PARAM_CAPABILITIES) | ||
240 | |||
236 | # switching the DAC to 8-bit is for <= 8 bpp only | 241 | # switching the DAC to 8-bit is for <= 8 bpp only |
237 | movw %fs:(PARAM_LFB_DEPTH), %ax | 242 | movw %fs:(PARAM_LFB_DEPTH), %ax |
238 | cmpw $8, %ax | 243 | cmpw $8, %ax |
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 566ecc97ee5a..69db0c0721d1 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16-git9 | 3 | # Linux kernel version: 2.6.17-rc1-git11 |
4 | # Sat Mar 25 15:18:40 2006 | 4 | # Sun Apr 16 07:22:36 2006 |
5 | # | 5 | # |
6 | CONFIG_X86_64=y | 6 | CONFIG_X86_64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -9,6 +9,7 @@ CONFIG_X86=y | |||
9 | CONFIG_SEMAPHORE_SLEEPERS=y | 9 | CONFIG_SEMAPHORE_SLEEPERS=y |
10 | CONFIG_MMU=y | 10 | CONFIG_MMU=y |
11 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 11 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
12 | CONFIG_GENERIC_HWEIGHT=y | ||
12 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 13 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
13 | CONFIG_X86_CMPXCHG=y | 14 | CONFIG_X86_CMPXCHG=y |
14 | CONFIG_EARLY_PRINTK=y | 15 | CONFIG_EARLY_PRINTK=y |
@@ -55,11 +56,8 @@ CONFIG_BASE_FULL=y | |||
55 | CONFIG_FUTEX=y | 56 | CONFIG_FUTEX=y |
56 | CONFIG_EPOLL=y | 57 | CONFIG_EPOLL=y |
57 | CONFIG_SHMEM=y | 58 | CONFIG_SHMEM=y |
58 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
59 | CONFIG_CC_ALIGN_LABELS=0 | ||
60 | CONFIG_CC_ALIGN_LOOPS=0 | ||
61 | CONFIG_CC_ALIGN_JUMPS=0 | ||
62 | CONFIG_SLAB=y | 59 | CONFIG_SLAB=y |
60 | CONFIG_DOUBLEFAULT=y | ||
63 | # CONFIG_TINY_SHMEM is not set | 61 | # CONFIG_TINY_SHMEM is not set |
64 | CONFIG_BASE_SMALL=0 | 62 | CONFIG_BASE_SMALL=0 |
65 | # CONFIG_SLOB is not set | 63 | # CONFIG_SLOB is not set |
@@ -70,7 +68,6 @@ CONFIG_BASE_SMALL=0 | |||
70 | CONFIG_MODULES=y | 68 | CONFIG_MODULES=y |
71 | CONFIG_MODULE_UNLOAD=y | 69 | CONFIG_MODULE_UNLOAD=y |
72 | CONFIG_MODULE_FORCE_UNLOAD=y | 70 | CONFIG_MODULE_FORCE_UNLOAD=y |
73 | CONFIG_OBSOLETE_MODPARM=y | ||
74 | # CONFIG_MODVERSIONS is not set | 71 | # CONFIG_MODVERSIONS is not set |
75 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 72 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
76 | # CONFIG_KMOD is not set | 73 | # CONFIG_KMOD is not set |
@@ -81,6 +78,7 @@ CONFIG_STOP_MACHINE=y | |||
81 | # | 78 | # |
82 | CONFIG_LBD=y | 79 | CONFIG_LBD=y |
83 | # CONFIG_BLK_DEV_IO_TRACE is not set | 80 | # CONFIG_BLK_DEV_IO_TRACE is not set |
81 | # CONFIG_LSF is not set | ||
84 | 82 | ||
85 | # | 83 | # |
86 | # IO Schedulers | 84 | # IO Schedulers |
@@ -105,6 +103,7 @@ CONFIG_X86_PC=y | |||
105 | CONFIG_GENERIC_CPU=y | 103 | CONFIG_GENERIC_CPU=y |
106 | CONFIG_X86_L1_CACHE_BYTES=128 | 104 | CONFIG_X86_L1_CACHE_BYTES=128 |
107 | CONFIG_X86_L1_CACHE_SHIFT=7 | 105 | CONFIG_X86_L1_CACHE_SHIFT=7 |
106 | CONFIG_X86_INTERNODE_CACHE_BYTES=128 | ||
108 | CONFIG_X86_TSC=y | 107 | CONFIG_X86_TSC=y |
109 | CONFIG_X86_GOOD_APIC=y | 108 | CONFIG_X86_GOOD_APIC=y |
110 | # CONFIG_MICROCODE is not set | 109 | # CONFIG_MICROCODE is not set |
@@ -116,12 +115,14 @@ CONFIG_X86_LOCAL_APIC=y | |||
116 | CONFIG_MTRR=y | 115 | CONFIG_MTRR=y |
117 | CONFIG_SMP=y | 116 | CONFIG_SMP=y |
118 | CONFIG_SCHED_SMT=y | 117 | CONFIG_SCHED_SMT=y |
118 | CONFIG_SCHED_MC=y | ||
119 | # CONFIG_PREEMPT_NONE is not set | 119 | # CONFIG_PREEMPT_NONE is not set |
120 | CONFIG_PREEMPT_VOLUNTARY=y | 120 | CONFIG_PREEMPT_VOLUNTARY=y |
121 | # CONFIG_PREEMPT is not set | 121 | # CONFIG_PREEMPT is not set |
122 | CONFIG_PREEMPT_BKL=y | 122 | CONFIG_PREEMPT_BKL=y |
123 | CONFIG_NUMA=y | 123 | CONFIG_NUMA=y |
124 | CONFIG_K8_NUMA=y | 124 | CONFIG_K8_NUMA=y |
125 | CONFIG_NODES_SHIFT=6 | ||
125 | CONFIG_X86_64_ACPI_NUMA=y | 126 | CONFIG_X86_64_ACPI_NUMA=y |
126 | CONFIG_NUMA_EMU=y | 127 | CONFIG_NUMA_EMU=y |
127 | CONFIG_ARCH_DISCONTIGMEM_ENABLE=y | 128 | CONFIG_ARCH_DISCONTIGMEM_ENABLE=y |
@@ -138,6 +139,7 @@ CONFIG_NEED_MULTIPLE_NODES=y | |||
138 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 139 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
139 | CONFIG_MIGRATION=y | 140 | CONFIG_MIGRATION=y |
140 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y | 141 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y |
142 | CONFIG_OUT_OF_LINE_PFN_TO_PAGE=y | ||
141 | CONFIG_NR_CPUS=32 | 143 | CONFIG_NR_CPUS=32 |
142 | CONFIG_HOTPLUG_CPU=y | 144 | CONFIG_HOTPLUG_CPU=y |
143 | CONFIG_HPET_TIMER=y | 145 | CONFIG_HPET_TIMER=y |
@@ -289,6 +291,7 @@ CONFIG_IP_PNP_DHCP=y | |||
289 | # CONFIG_INET_AH is not set | 291 | # CONFIG_INET_AH is not set |
290 | # CONFIG_INET_ESP is not set | 292 | # CONFIG_INET_ESP is not set |
291 | # CONFIG_INET_IPCOMP is not set | 293 | # CONFIG_INET_IPCOMP is not set |
294 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
292 | # CONFIG_INET_TUNNEL is not set | 295 | # CONFIG_INET_TUNNEL is not set |
293 | CONFIG_INET_DIAG=y | 296 | CONFIG_INET_DIAG=y |
294 | CONFIG_INET_TCP_DIAG=y | 297 | CONFIG_INET_TCP_DIAG=y |
@@ -300,6 +303,7 @@ CONFIG_IPV6=y | |||
300 | # CONFIG_INET6_AH is not set | 303 | # CONFIG_INET6_AH is not set |
301 | # CONFIG_INET6_ESP is not set | 304 | # CONFIG_INET6_ESP is not set |
302 | # CONFIG_INET6_IPCOMP is not set | 305 | # CONFIG_INET6_IPCOMP is not set |
306 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
303 | # CONFIG_INET6_TUNNEL is not set | 307 | # CONFIG_INET6_TUNNEL is not set |
304 | # CONFIG_IPV6_TUNNEL is not set | 308 | # CONFIG_IPV6_TUNNEL is not set |
305 | # CONFIG_NETFILTER is not set | 309 | # CONFIG_NETFILTER is not set |
@@ -542,7 +546,6 @@ CONFIG_SCSI_SATA_INTEL_COMBINED=y | |||
542 | # CONFIG_SCSI_INIA100 is not set | 546 | # CONFIG_SCSI_INIA100 is not set |
543 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 547 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
544 | # CONFIG_SCSI_IPR is not set | 548 | # CONFIG_SCSI_IPR is not set |
545 | # CONFIG_SCSI_QLOGIC_FC is not set | ||
546 | # CONFIG_SCSI_QLOGIC_1280 is not set | 549 | # CONFIG_SCSI_QLOGIC_1280 is not set |
547 | # CONFIG_SCSI_QLA_FC is not set | 550 | # CONFIG_SCSI_QLA_FC is not set |
548 | # CONFIG_SCSI_LPFC is not set | 551 | # CONFIG_SCSI_LPFC is not set |
@@ -704,7 +707,6 @@ CONFIG_S2IO=m | |||
704 | # Wireless LAN (non-hamradio) | 707 | # Wireless LAN (non-hamradio) |
705 | # | 708 | # |
706 | # CONFIG_NET_RADIO is not set | 709 | # CONFIG_NET_RADIO is not set |
707 | # CONFIG_NET_WIRELESS_RTNETLINK is not set | ||
708 | 710 | ||
709 | # | 711 | # |
710 | # Wan interfaces | 712 | # Wan interfaces |
@@ -791,7 +793,7 @@ CONFIG_HW_CONSOLE=y | |||
791 | # | 793 | # |
792 | CONFIG_SERIAL_8250=y | 794 | CONFIG_SERIAL_8250=y |
793 | CONFIG_SERIAL_8250_CONSOLE=y | 795 | CONFIG_SERIAL_8250_CONSOLE=y |
794 | # CONFIG_SERIAL_8250_ACPI is not set | 796 | CONFIG_SERIAL_8250_PCI=y |
795 | CONFIG_SERIAL_8250_NR_UARTS=4 | 797 | CONFIG_SERIAL_8250_NR_UARTS=4 |
796 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | 798 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 |
797 | # CONFIG_SERIAL_8250_EXTENDED is not set | 799 | # CONFIG_SERIAL_8250_EXTENDED is not set |
@@ -921,6 +923,7 @@ CONFIG_HWMON=y | |||
921 | # Digital Video Broadcasting Devices | 923 | # Digital Video Broadcasting Devices |
922 | # | 924 | # |
923 | # CONFIG_DVB is not set | 925 | # CONFIG_DVB is not set |
926 | # CONFIG_USB_DABUSB is not set | ||
924 | 927 | ||
925 | # | 928 | # |
926 | # Graphics support | 929 | # Graphics support |
@@ -932,6 +935,8 @@ CONFIG_VIDEO_SELECT=y | |||
932 | # Console display driver support | 935 | # Console display driver support |
933 | # | 936 | # |
934 | CONFIG_VGA_CONSOLE=y | 937 | CONFIG_VGA_CONSOLE=y |
938 | CONFIG_VGACON_SOFT_SCROLLBACK=y | ||
939 | CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=256 | ||
935 | CONFIG_DUMMY_CONSOLE=y | 940 | CONFIG_DUMMY_CONSOLE=y |
936 | 941 | ||
937 | # | 942 | # |
@@ -1041,9 +1046,7 @@ CONFIG_USB_HIDINPUT=y | |||
1041 | # CONFIG_USB_ACECAD is not set | 1046 | # CONFIG_USB_ACECAD is not set |
1042 | # CONFIG_USB_KBTAB is not set | 1047 | # CONFIG_USB_KBTAB is not set |
1043 | # CONFIG_USB_POWERMATE is not set | 1048 | # CONFIG_USB_POWERMATE is not set |
1044 | # CONFIG_USB_MTOUCH is not set | 1049 | # CONFIG_USB_TOUCHSCREEN is not set |
1045 | # CONFIG_USB_ITMTOUCH is not set | ||
1046 | # CONFIG_USB_EGALAX is not set | ||
1047 | # CONFIG_USB_YEALINK is not set | 1050 | # CONFIG_USB_YEALINK is not set |
1048 | # CONFIG_USB_XPAD is not set | 1051 | # CONFIG_USB_XPAD is not set |
1049 | # CONFIG_USB_ATI_REMOTE is not set | 1052 | # CONFIG_USB_ATI_REMOTE is not set |
@@ -1058,15 +1061,6 @@ CONFIG_USB_HIDINPUT=y | |||
1058 | # CONFIG_USB_MICROTEK is not set | 1061 | # CONFIG_USB_MICROTEK is not set |
1059 | 1062 | ||
1060 | # | 1063 | # |
1061 | # USB Multimedia devices | ||
1062 | # | ||
1063 | # CONFIG_USB_DABUSB is not set | ||
1064 | |||
1065 | # | ||
1066 | # Video4Linux support is needed for USB Multimedia device support | ||
1067 | # | ||
1068 | |||
1069 | # | ||
1070 | # USB Network Adapters | 1064 | # USB Network Adapters |
1071 | # | 1065 | # |
1072 | # CONFIG_USB_CATC is not set | 1066 | # CONFIG_USB_CATC is not set |
@@ -1118,9 +1112,23 @@ CONFIG_USB_MON=y | |||
1118 | # CONFIG_MMC is not set | 1112 | # CONFIG_MMC is not set |
1119 | 1113 | ||
1120 | # | 1114 | # |
1115 | # LED devices | ||
1116 | # | ||
1117 | # CONFIG_NEW_LEDS is not set | ||
1118 | |||
1119 | # | ||
1120 | # LED drivers | ||
1121 | # | ||
1122 | |||
1123 | # | ||
1124 | # LED Triggers | ||
1125 | # | ||
1126 | |||
1127 | # | ||
1121 | # InfiniBand support | 1128 | # InfiniBand support |
1122 | # | 1129 | # |
1123 | # CONFIG_INFINIBAND is not set | 1130 | # CONFIG_INFINIBAND is not set |
1131 | # CONFIG_IPATH_CORE is not set | ||
1124 | 1132 | ||
1125 | # | 1133 | # |
1126 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) | 1134 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) |
@@ -1128,6 +1136,11 @@ CONFIG_USB_MON=y | |||
1128 | # CONFIG_EDAC is not set | 1136 | # CONFIG_EDAC is not set |
1129 | 1137 | ||
1130 | # | 1138 | # |
1139 | # Real Time Clock | ||
1140 | # | ||
1141 | # CONFIG_RTC_CLASS is not set | ||
1142 | |||
1143 | # | ||
1131 | # Firmware Drivers | 1144 | # Firmware Drivers |
1132 | # | 1145 | # |
1133 | # CONFIG_EDD is not set | 1146 | # CONFIG_EDD is not set |
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 35b2faccdc6c..57fc37e0fb9c 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <asm/vsyscall32.h> | 15 | #include <asm/vsyscall32.h> |
16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
17 | 17 | ||
18 | #define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8) | ||
19 | |||
18 | .macro IA32_ARG_FIXUP noebp=0 | 20 | .macro IA32_ARG_FIXUP noebp=0 |
19 | movl %edi,%r8d | 21 | movl %edi,%r8d |
20 | .if \noebp | 22 | .if \noebp |
@@ -109,8 +111,8 @@ ENTRY(ia32_sysenter_target) | |||
109 | CFI_REMEMBER_STATE | 111 | CFI_REMEMBER_STATE |
110 | jnz sysenter_tracesys | 112 | jnz sysenter_tracesys |
111 | sysenter_do_call: | 113 | sysenter_do_call: |
112 | cmpl $(IA32_NR_syscalls),%eax | 114 | cmpl $(IA32_NR_syscalls-1),%eax |
113 | jae ia32_badsys | 115 | ja ia32_badsys |
114 | IA32_ARG_FIXUP 1 | 116 | IA32_ARG_FIXUP 1 |
115 | call *ia32_sys_call_table(,%rax,8) | 117 | call *ia32_sys_call_table(,%rax,8) |
116 | movq %rax,RAX-ARGOFFSET(%rsp) | 118 | movq %rax,RAX-ARGOFFSET(%rsp) |
@@ -210,8 +212,8 @@ ENTRY(ia32_cstar_target) | |||
210 | CFI_REMEMBER_STATE | 212 | CFI_REMEMBER_STATE |
211 | jnz cstar_tracesys | 213 | jnz cstar_tracesys |
212 | cstar_do_call: | 214 | cstar_do_call: |
213 | cmpl $IA32_NR_syscalls,%eax | 215 | cmpl $IA32_NR_syscalls-1,%eax |
214 | jae ia32_badsys | 216 | ja ia32_badsys |
215 | IA32_ARG_FIXUP 1 | 217 | IA32_ARG_FIXUP 1 |
216 | call *ia32_sys_call_table(,%rax,8) | 218 | call *ia32_sys_call_table(,%rax,8) |
217 | movq %rax,RAX-ARGOFFSET(%rsp) | 219 | movq %rax,RAX-ARGOFFSET(%rsp) |
@@ -296,8 +298,8 @@ ENTRY(ia32_syscall) | |||
296 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) | 298 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) |
297 | jnz ia32_tracesys | 299 | jnz ia32_tracesys |
298 | ia32_do_syscall: | 300 | ia32_do_syscall: |
299 | cmpl $(IA32_NR_syscalls),%eax | 301 | cmpl $(IA32_NR_syscalls-1),%eax |
300 | jae ia32_badsys | 302 | ja ia32_badsys |
301 | IA32_ARG_FIXUP | 303 | IA32_ARG_FIXUP |
302 | call *ia32_sys_call_table(,%rax,8) # xxx: rip relative | 304 | call *ia32_sys_call_table(,%rax,8) # xxx: rip relative |
303 | ia32_sysret: | 305 | ia32_sysret: |
@@ -685,12 +687,12 @@ ia32_sys_call_table: | |||
685 | .quad sys_readlinkat /* 305 */ | 687 | .quad sys_readlinkat /* 305 */ |
686 | .quad sys_fchmodat | 688 | .quad sys_fchmodat |
687 | .quad sys_faccessat | 689 | .quad sys_faccessat |
688 | .quad sys_ni_syscall /* pselect6 for now */ | 690 | .quad quiet_ni_syscall /* pselect6 for now */ |
689 | .quad sys_ni_syscall /* ppoll for now */ | 691 | .quad quiet_ni_syscall /* ppoll for now */ |
690 | .quad sys_unshare /* 310 */ | 692 | .quad sys_unshare /* 310 */ |
691 | .quad compat_sys_set_robust_list | 693 | .quad compat_sys_set_robust_list |
692 | .quad compat_sys_get_robust_list | 694 | .quad compat_sys_get_robust_list |
695 | .quad sys_splice | ||
696 | .quad sys_sync_file_range | ||
697 | .quad sys_tee | ||
693 | ia32_syscall_end: | 698 | ia32_syscall_end: |
694 | .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 | ||
695 | .quad ni_syscall | ||
696 | .endr | ||
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index a098a11e7755..059c88313f4e 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile | |||
@@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \ | |||
8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ | 8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ |
9 | x8664_ksyms.o i387.o syscall.o vsyscall.o \ | 9 | x8664_ksyms.o i387.o syscall.o vsyscall.o \ |
10 | setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ | 10 | setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ |
11 | dmi_scan.o pci-dma.o pci-nommu.o | 11 | pci-dma.o pci-nommu.o |
12 | 12 | ||
13 | obj-$(CONFIG_X86_MCE) += mce.o | 13 | obj-$(CONFIG_X86_MCE) += mce.o |
14 | obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o | 14 | obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o |
@@ -49,5 +49,3 @@ intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o | |||
49 | quirks-y += ../../i386/kernel/quirks.o | 49 | quirks-y += ../../i386/kernel/quirks.o |
50 | i8237-y += ../../i386/kernel/i8237.o | 50 | i8237-y += ../../i386/kernel/i8237.o |
51 | msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o | 51 | msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o |
52 | dmi_scan-y += ../../i386/kernel/dmi_scan.o | ||
53 | |||
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index fffd6b0a2fab..70b9d21ed675 100644 --- a/arch/x86_64/kernel/aperture.c +++ b/arch/x86_64/kernel/aperture.c | |||
@@ -80,7 +80,7 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) | |||
80 | printk("Aperture from %s beyond 4GB. Ignoring.\n",name); | 80 | printk("Aperture from %s beyond 4GB. Ignoring.\n",name); |
81 | return 0; | 81 | return 0; |
82 | } | 82 | } |
83 | if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) { | 83 | if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) { |
84 | printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); | 84 | printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); |
85 | return 0; | 85 | return 0; |
86 | } | 86 | } |
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 293cd71a266a..62776c07cff1 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -80,7 +80,12 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) | |||
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) | 83 | /* |
84 | * This function checks if any part of the range <start,end> is mapped | ||
85 | * with type. | ||
86 | */ | ||
87 | int __meminit | ||
88 | e820_any_mapped(unsigned long start, unsigned long end, unsigned type) | ||
84 | { | 89 | { |
85 | int i; | 90 | int i; |
86 | for (i = 0; i < e820.nr_map; i++) { | 91 | for (i = 0; i < e820.nr_map; i++) { |
@@ -94,6 +99,35 @@ int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) | |||
94 | return 0; | 99 | return 0; |
95 | } | 100 | } |
96 | 101 | ||
102 | /* | ||
103 | * This function checks if the entire range <start,end> is mapped with type. | ||
104 | * | ||
105 | * Note: this function only works correct if the e820 table is sorted and | ||
106 | * not-overlapping, which is the case | ||
107 | */ | ||
108 | int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type) | ||
109 | { | ||
110 | int i; | ||
111 | for (i = 0; i < e820.nr_map; i++) { | ||
112 | struct e820entry *ei = &e820.map[i]; | ||
113 | if (type && ei->type != type) | ||
114 | continue; | ||
115 | /* is the region (part) in overlap with the current region ?*/ | ||
116 | if (ei->addr >= end || ei->addr + ei->size <= start) | ||
117 | continue; | ||
118 | |||
119 | /* if the region is at the beginning of <start,end> we move | ||
120 | * start to the end of the region since it's ok until there | ||
121 | */ | ||
122 | if (ei->addr <= start) | ||
123 | start = ei->addr + ei->size; | ||
124 | /* if start is now at or beyond end, we're done, full coverage */ | ||
125 | if (start >= end) | ||
126 | return 1; /* we're done */ | ||
127 | } | ||
128 | return 0; | ||
129 | } | ||
130 | |||
97 | /* | 131 | /* |
98 | * Find a free area in a specific range. | 132 | * Find a free area in a specific range. |
99 | */ | 133 | */ |
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 8538bfea30e6..c946e4fe67a7 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -180,6 +180,10 @@ rff_trace: | |||
180 | * | 180 | * |
181 | * XXX if we had a free scratch register we could save the RSP into the stack frame | 181 | * XXX if we had a free scratch register we could save the RSP into the stack frame |
182 | * and report it properly in ps. Unfortunately we haven't. | 182 | * and report it properly in ps. Unfortunately we haven't. |
183 | * | ||
184 | * When user can change the frames always force IRET. That is because | ||
185 | * it deals with uncanonical addresses better. SYSRET has trouble | ||
186 | * with them due to bugs in both AMD and Intel CPUs. | ||
183 | */ | 187 | */ |
184 | 188 | ||
185 | ENTRY(system_call) | 189 | ENTRY(system_call) |
@@ -254,7 +258,10 @@ sysret_signal: | |||
254 | xorl %esi,%esi # oldset -> arg2 | 258 | xorl %esi,%esi # oldset -> arg2 |
255 | call ptregscall_common | 259 | call ptregscall_common |
256 | 1: movl $_TIF_NEED_RESCHED,%edi | 260 | 1: movl $_TIF_NEED_RESCHED,%edi |
257 | jmp sysret_check | 261 | /* Use IRET because user could have changed frame. This |
262 | works because ptregscall_common has called FIXUP_TOP_OF_STACK. */ | ||
263 | cli | ||
264 | jmp int_with_check | ||
258 | 265 | ||
259 | badsys: | 266 | badsys: |
260 | movq $-ENOSYS,RAX-ARGOFFSET(%rsp) | 267 | movq $-ENOSYS,RAX-ARGOFFSET(%rsp) |
@@ -280,7 +287,8 @@ tracesys: | |||
280 | call syscall_trace_leave | 287 | call syscall_trace_leave |
281 | RESTORE_TOP_OF_STACK %rbx | 288 | RESTORE_TOP_OF_STACK %rbx |
282 | RESTORE_REST | 289 | RESTORE_REST |
283 | jmp ret_from_sys_call | 290 | /* Use IRET because user could have changed frame */ |
291 | jmp int_ret_from_sys_call | ||
284 | CFI_ENDPROC | 292 | CFI_ENDPROC |
285 | 293 | ||
286 | /* | 294 | /* |
@@ -408,25 +416,9 @@ ENTRY(stub_execve) | |||
408 | CFI_ADJUST_CFA_OFFSET -8 | 416 | CFI_ADJUST_CFA_OFFSET -8 |
409 | CFI_REGISTER rip, r11 | 417 | CFI_REGISTER rip, r11 |
410 | SAVE_REST | 418 | SAVE_REST |
411 | movq %r11, %r15 | ||
412 | CFI_REGISTER rip, r15 | ||
413 | FIXUP_TOP_OF_STACK %r11 | 419 | FIXUP_TOP_OF_STACK %r11 |
414 | call sys_execve | 420 | call sys_execve |
415 | GET_THREAD_INFO(%rcx) | ||
416 | bt $TIF_IA32,threadinfo_flags(%rcx) | ||
417 | CFI_REMEMBER_STATE | ||
418 | jc exec_32bit | ||
419 | RESTORE_TOP_OF_STACK %r11 | 421 | RESTORE_TOP_OF_STACK %r11 |
420 | movq %r15, %r11 | ||
421 | CFI_REGISTER rip, r11 | ||
422 | RESTORE_REST | ||
423 | pushq %r11 | ||
424 | CFI_ADJUST_CFA_OFFSET 8 | ||
425 | CFI_REL_OFFSET rip, 0 | ||
426 | ret | ||
427 | |||
428 | exec_32bit: | ||
429 | CFI_RESTORE_STATE | ||
430 | movq %rax,RAX(%rsp) | 422 | movq %rax,RAX(%rsp) |
431 | RESTORE_REST | 423 | RESTORE_REST |
432 | jmp int_ret_from_sys_call | 424 | jmp int_ret_from_sys_call |
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index accbff3fec49..1eaa5dae6174 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c | |||
@@ -53,7 +53,7 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | |||
53 | /* | 53 | /* |
54 | * returns non-zero if opcode modifies the interrupt flag. | 54 | * returns non-zero if opcode modifies the interrupt flag. |
55 | */ | 55 | */ |
56 | static inline int is_IF_modifier(kprobe_opcode_t *insn) | 56 | static __always_inline int is_IF_modifier(kprobe_opcode_t *insn) |
57 | { | 57 | { |
58 | switch (*insn) { | 58 | switch (*insn) { |
59 | case 0xfa: /* cli */ | 59 | case 0xfa: /* cli */ |
@@ -84,7 +84,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
84 | * If it does, return the address of the 32-bit displacement word. | 84 | * If it does, return the address of the 32-bit displacement word. |
85 | * If not, return null. | 85 | * If not, return null. |
86 | */ | 86 | */ |
87 | static inline s32 *is_riprel(u8 *insn) | 87 | static s32 __kprobes *is_riprel(u8 *insn) |
88 | { | 88 | { |
89 | #define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \ | 89 | #define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \ |
90 | (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ | 90 | (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ |
@@ -229,7 +229,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) | |||
229 | mutex_unlock(&kprobe_mutex); | 229 | mutex_unlock(&kprobe_mutex); |
230 | } | 230 | } |
231 | 231 | ||
232 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 232 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
233 | { | 233 | { |
234 | kcb->prev_kprobe.kp = kprobe_running(); | 234 | kcb->prev_kprobe.kp = kprobe_running(); |
235 | kcb->prev_kprobe.status = kcb->kprobe_status; | 235 | kcb->prev_kprobe.status = kcb->kprobe_status; |
@@ -237,7 +237,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
237 | kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags; | 237 | kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags; |
238 | } | 238 | } |
239 | 239 | ||
240 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 240 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
241 | { | 241 | { |
242 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | 242 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
243 | kcb->kprobe_status = kcb->prev_kprobe.status; | 243 | kcb->kprobe_status = kcb->prev_kprobe.status; |
@@ -245,7 +245,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
245 | kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags; | 245 | kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags; |
246 | } | 246 | } |
247 | 247 | ||
248 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | 248 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
249 | struct kprobe_ctlblk *kcb) | 249 | struct kprobe_ctlblk *kcb) |
250 | { | 250 | { |
251 | __get_cpu_var(current_kprobe) = p; | 251 | __get_cpu_var(current_kprobe) = p; |
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 10b3e348fc99..6f0790e8b6d3 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #define MISC_MCELOG_MINOR 227 | 29 | #define MISC_MCELOG_MINOR 227 |
30 | #define NR_BANKS 6 | 30 | #define NR_BANKS 6 |
31 | 31 | ||
32 | atomic_t mce_entry; | ||
33 | |||
32 | static int mce_dont_init; | 34 | static int mce_dont_init; |
33 | 35 | ||
34 | /* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic, | 36 | /* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic, |
@@ -172,10 +174,12 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
172 | int i; | 174 | int i; |
173 | int panicm_found = 0; | 175 | int panicm_found = 0; |
174 | 176 | ||
177 | atomic_inc(&mce_entry); | ||
178 | |||
175 | if (regs) | 179 | if (regs) |
176 | notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL); | 180 | notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL); |
177 | if (!banks) | 181 | if (!banks) |
178 | return; | 182 | goto out2; |
179 | 183 | ||
180 | memset(&m, 0, sizeof(struct mce)); | 184 | memset(&m, 0, sizeof(struct mce)); |
181 | m.cpu = safe_smp_processor_id(); | 185 | m.cpu = safe_smp_processor_id(); |
@@ -266,6 +270,8 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
266 | out: | 270 | out: |
267 | /* Last thing done in the machine check exception to clear state. */ | 271 | /* Last thing done in the machine check exception to clear state. */ |
268 | wrmsrl(MSR_IA32_MCG_STATUS, 0); | 272 | wrmsrl(MSR_IA32_MCG_STATUS, 0); |
273 | out2: | ||
274 | atomic_dec(&mce_entry); | ||
269 | } | 275 | } |
270 | 276 | ||
271 | /* | 277 | /* |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index d9e4067faf05..4e6357fe0ec3 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/proto.h> | 34 | #include <asm/proto.h> |
35 | #include <asm/kdebug.h> | 35 | #include <asm/kdebug.h> |
36 | #include <asm/local.h> | 36 | #include <asm/local.h> |
37 | #include <asm/mce.h> | ||
37 | 38 | ||
38 | /* | 39 | /* |
39 | * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: | 40 | * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: |
@@ -480,6 +481,12 @@ void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) | |||
480 | __get_cpu_var(nmi_touch) = 0; | 481 | __get_cpu_var(nmi_touch) = 0; |
481 | touched = 1; | 482 | touched = 1; |
482 | } | 483 | } |
484 | #ifdef CONFIG_X86_MCE | ||
485 | /* Could check oops_in_progress here too, but it's safer | ||
486 | not too */ | ||
487 | if (atomic_read(&mce_entry) > 0) | ||
488 | touched = 1; | ||
489 | #endif | ||
483 | if (!touched && __get_cpu_var(last_irq_sum) == sum) { | 490 | if (!touched && __get_cpu_var(last_irq_sum) == sum) { |
484 | /* | 491 | /* |
485 | * Ayiee, looks like this CPU is stuck ... | 492 | * Ayiee, looks like this CPU is stuck ... |
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c index 03c9eeedb0f3..af035ede70cd 100644 --- a/arch/x86_64/kernel/pci-dma.c +++ b/arch/x86_64/kernel/pci-dma.c | |||
@@ -48,9 +48,11 @@ dma_alloc_pages(struct device *dev, gfp_t gfp, unsigned order) | |||
48 | { | 48 | { |
49 | struct page *page; | 49 | struct page *page; |
50 | int node; | 50 | int node; |
51 | #ifdef CONFIG_PCI | ||
51 | if (dev->bus == &pci_bus_type) | 52 | if (dev->bus == &pci_bus_type) |
52 | node = pcibus_to_node(to_pci_dev(dev)->bus); | 53 | node = pcibus_to_node(to_pci_dev(dev)->bus); |
53 | else | 54 | else |
55 | #endif | ||
54 | node = numa_node_id(); | 56 | node = numa_node_id(); |
55 | page = alloc_pages_node(node, gfp, order); | 57 | page = alloc_pages_node(node, gfp, order); |
56 | return page ? page_address(page) : NULL; | 58 | return page ? page_address(page) : NULL; |
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 70dd8e5c6889..fb903e65e079 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -575,8 +575,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
575 | prev->userrsp = read_pda(oldrsp); | 575 | prev->userrsp = read_pda(oldrsp); |
576 | write_pda(oldrsp, next->userrsp); | 576 | write_pda(oldrsp, next->userrsp); |
577 | write_pda(pcurrent, next_p); | 577 | write_pda(pcurrent, next_p); |
578 | |||
578 | /* This must be here to ensure both math_state_restore() and | 579 | /* This must be here to ensure both math_state_restore() and |
579 | kernel_fpu_begin() work consistently. */ | 580 | kernel_fpu_begin() work consistently. |
581 | And the AMD workaround requires it to be after DS reload. */ | ||
580 | unlazy_fpu(prev_p); | 582 | unlazy_fpu(prev_p); |
581 | write_pda(kernelstack, | 583 | write_pda(kernelstack, |
582 | task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); | 584 | task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); |
@@ -781,10 +783,16 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) | |||
781 | } | 783 | } |
782 | case ARCH_GET_GS: { | 784 | case ARCH_GET_GS: { |
783 | unsigned long base; | 785 | unsigned long base; |
786 | unsigned gsindex; | ||
784 | if (task->thread.gsindex == GS_TLS_SEL) | 787 | if (task->thread.gsindex == GS_TLS_SEL) |
785 | base = read_32bit_tls(task, GS_TLS); | 788 | base = read_32bit_tls(task, GS_TLS); |
786 | else if (doit) | 789 | else if (doit) { |
787 | rdmsrl(MSR_KERNEL_GS_BASE, base); | 790 | asm("movl %%gs,%0" : "=r" (gsindex)); |
791 | if (gsindex) | ||
792 | rdmsrl(MSR_KERNEL_GS_BASE, base); | ||
793 | else | ||
794 | base = task->thread.gs; | ||
795 | } | ||
788 | else | 796 | else |
789 | base = task->thread.gs; | 797 | base = task->thread.gs; |
790 | ret = put_user(base, (unsigned long __user *)addr); | 798 | ret = put_user(base, (unsigned long __user *)addr); |
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c index d44b2c1e63a6..da8e7903d817 100644 --- a/arch/x86_64/kernel/ptrace.c +++ b/arch/x86_64/kernel/ptrace.c | |||
@@ -274,11 +274,6 @@ static int putreg(struct task_struct *child, | |||
274 | return -EIO; | 274 | return -EIO; |
275 | value &= 0xffff; | 275 | value &= 0xffff; |
276 | break; | 276 | break; |
277 | case offsetof(struct user_regs_struct, rip): | ||
278 | /* Check if the new RIP address is canonical */ | ||
279 | if (value >= TASK_SIZE_OF(child)) | ||
280 | return -EIO; | ||
281 | break; | ||
282 | } | 277 | } |
283 | put_stack_long(child, regno - sizeof(struct pt_regs), value); | 278 | put_stack_long(child, regno - sizeof(struct pt_regs), value); |
284 | return 0; | 279 | return 0; |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 0856ad444f90..759070c82751 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -353,8 +353,10 @@ static __init void parse_cmdline_early (char ** cmdline_p) | |||
353 | if (fullarg(from, "enable_timer_pin_1")) | 353 | if (fullarg(from, "enable_timer_pin_1")) |
354 | disable_timer_pin_1 = -1; | 354 | disable_timer_pin_1 = -1; |
355 | 355 | ||
356 | if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) | 356 | if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) { |
357 | clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); | ||
357 | disable_apic = 1; | 358 | disable_apic = 1; |
359 | } | ||
358 | 360 | ||
359 | if (fullarg(from, "noapic")) | 361 | if (fullarg(from, "noapic")) |
360 | skip_ioapic_setup = 1; | 362 | skip_ioapic_setup = 1; |
@@ -928,6 +930,10 @@ static int __init init_amd(struct cpuinfo_x86 *c) | |||
928 | if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)) | 930 | if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)) |
929 | set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); | 931 | set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); |
930 | 932 | ||
933 | /* Enable workaround for FXSAVE leak */ | ||
934 | if (c->x86 >= 6) | ||
935 | set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability); | ||
936 | |||
931 | r = get_model_name(c); | 937 | r = get_model_name(c); |
932 | if (!r) { | 938 | if (!r) { |
933 | switch (c->x86) { | 939 | switch (c->x86) { |
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index ef8bc46dc140..7392570f975d 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
@@ -726,7 +726,7 @@ static __init int late_hpet_init(void) | |||
726 | unsigned int ntimer; | 726 | unsigned int ntimer; |
727 | 727 | ||
728 | if (!vxtime.hpet_address) | 728 | if (!vxtime.hpet_address) |
729 | return -1; | 729 | return 0; |
730 | 730 | ||
731 | memset(&hd, 0, sizeof (hd)); | 731 | memset(&hd, 0, sizeof (hd)); |
732 | 732 | ||
@@ -917,6 +917,8 @@ void __init time_init(void) | |||
917 | vxtime.hpet_address = 0; | 917 | vxtime.hpet_address = 0; |
918 | 918 | ||
919 | if (hpet_use_timer) { | 919 | if (hpet_use_timer) { |
920 | /* set tick_nsec to use the proper rate for HPET */ | ||
921 | tick_nsec = TICK_NSEC_HPET; | ||
920 | cpu_khz = hpet_calibrate_tsc(); | 922 | cpu_khz = hpet_calibrate_tsc(); |
921 | timename = "HPET"; | 923 | timename = "HPET"; |
922 | #ifdef CONFIG_X86_PM_TIMER | 924 | #ifdef CONFIG_X86_PM_TIMER |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 6bda322d3caf..2700b1375c1f 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/moduleparam.h> | 30 | #include <linux/moduleparam.h> |
31 | #include <linux/nmi.h> | 31 | #include <linux/nmi.h> |
32 | #include <linux/kprobes.h> | 32 | #include <linux/kprobes.h> |
33 | #include <linux/kexec.h> | ||
33 | 34 | ||
34 | #include <asm/system.h> | 35 | #include <asm/system.h> |
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
@@ -433,6 +434,8 @@ void __kprobes __die(const char * str, struct pt_regs * regs, long err) | |||
433 | printk(KERN_ALERT "RIP "); | 434 | printk(KERN_ALERT "RIP "); |
434 | printk_address(regs->rip); | 435 | printk_address(regs->rip); |
435 | printk(" RSP <%016lx>\n", regs->rsp); | 436 | printk(" RSP <%016lx>\n", regs->rsp); |
437 | if (kexec_should_crash(current)) | ||
438 | crash_kexec(regs); | ||
436 | } | 439 | } |
437 | 440 | ||
438 | void die(const char * str, struct pt_regs * regs, long err) | 441 | void die(const char * str, struct pt_regs * regs, long err) |
@@ -455,6 +458,8 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs) | |||
455 | */ | 458 | */ |
456 | printk(str, safe_smp_processor_id()); | 459 | printk(str, safe_smp_processor_id()); |
457 | show_registers(regs); | 460 | show_registers(regs); |
461 | if (kexec_should_crash(current)) | ||
462 | crash_kexec(regs); | ||
458 | if (panic_on_timeout || panic_on_oops) | 463 | if (panic_on_timeout || panic_on_oops) |
459 | panic("nmi watchdog"); | 464 | panic("nmi watchdog"); |
460 | printk("console shuts up ...\n"); | 465 | printk("console shuts up ...\n"); |
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 39ff0708f803..b81f473c4a19 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S | |||
@@ -65,7 +65,7 @@ SECTIONS | |||
65 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { | 65 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { |
66 | *(.data.cacheline_aligned) | 66 | *(.data.cacheline_aligned) |
67 | } | 67 | } |
68 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | 68 | . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES); |
69 | .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { | 69 | .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { |
70 | *(.data.read_mostly) | 70 | *(.data.read_mostly) |
71 | } | 71 | } |
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index d78f46056bda..1def21c9f7cd 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c | |||
@@ -112,7 +112,6 @@ EXPORT_SYMBOL_GPL(unset_nmi_callback); | |||
112 | #undef memcpy | 112 | #undef memcpy |
113 | #undef memset | 113 | #undef memset |
114 | #undef memmove | 114 | #undef memmove |
115 | #undef strlen | ||
116 | 115 | ||
117 | extern void * memset(void *,int,__kernel_size_t); | 116 | extern void * memset(void *,int,__kernel_size_t); |
118 | extern size_t strlen(const char *); | 117 | extern size_t strlen(const char *); |
@@ -121,8 +120,6 @@ extern void * memcpy(void *,const void *,__kernel_size_t); | |||
121 | extern void * __memcpy(void *,const void *,__kernel_size_t); | 120 | extern void * __memcpy(void *,const void *,__kernel_size_t); |
122 | 121 | ||
123 | EXPORT_SYMBOL(memset); | 122 | EXPORT_SYMBOL(memset); |
124 | EXPORT_SYMBOL(strlen); | ||
125 | EXPORT_SYMBOL(strpbrk); | ||
126 | EXPORT_SYMBOL(memmove); | 123 | EXPORT_SYMBOL(memmove); |
127 | EXPORT_SYMBOL(memcpy); | 124 | EXPORT_SYMBOL(memcpy); |
128 | EXPORT_SYMBOL(__memcpy); | 125 | EXPORT_SYMBOL(__memcpy); |
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index e5f7f1c34462..4ba34e95d835 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -305,7 +305,7 @@ static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned | |||
305 | if (paddr >= end) | 305 | if (paddr >= end) |
306 | break; | 306 | break; |
307 | 307 | ||
308 | if (!after_bootmem && !e820_mapped(paddr, paddr+PUD_SIZE, 0)) { | 308 | if (!after_bootmem && !e820_any_mapped(paddr, paddr+PUD_SIZE, 0)) { |
309 | set_pud(pud, __pud(0)); | 309 | set_pud(pud, __pud(0)); |
310 | continue; | 310 | continue; |
311 | } | 311 | } |
@@ -507,9 +507,8 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) | |||
507 | 507 | ||
508 | /* | 508 | /* |
509 | * Memory hotplug specific functions | 509 | * Memory hotplug specific functions |
510 | * These are only for non-NUMA machines right now. | ||
511 | */ | 510 | */ |
512 | #ifdef CONFIG_MEMORY_HOTPLUG | 511 | #if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) |
513 | 512 | ||
514 | void online_page(struct page *page) | 513 | void online_page(struct page *page) |
515 | { | 514 | { |
@@ -520,6 +519,38 @@ void online_page(struct page *page) | |||
520 | num_physpages++; | 519 | num_physpages++; |
521 | } | 520 | } |
522 | 521 | ||
522 | #ifndef CONFIG_MEMORY_HOTPLUG | ||
523 | /* | ||
524 | * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, | ||
525 | * just online the pages. | ||
526 | */ | ||
527 | int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) | ||
528 | { | ||
529 | int err = -EIO; | ||
530 | unsigned long pfn; | ||
531 | unsigned long total = 0, mem = 0; | ||
532 | for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { | ||
533 | if (pfn_valid(pfn)) { | ||
534 | online_page(pfn_to_page(pfn)); | ||
535 | err = 0; | ||
536 | mem++; | ||
537 | } | ||
538 | total++; | ||
539 | } | ||
540 | if (!err) { | ||
541 | z->spanned_pages += total; | ||
542 | z->present_pages += mem; | ||
543 | z->zone_pgdat->node_spanned_pages += total; | ||
544 | z->zone_pgdat->node_present_pages += mem; | ||
545 | } | ||
546 | return err; | ||
547 | } | ||
548 | #endif | ||
549 | |||
550 | /* | ||
551 | * Memory is added always to NORMAL zone. This means you will never get | ||
552 | * additional DMA/DMA32 memory. | ||
553 | */ | ||
523 | int add_memory(u64 start, u64 size) | 554 | int add_memory(u64 start, u64 size) |
524 | { | 555 | { |
525 | struct pglist_data *pgdat = NODE_DATA(0); | 556 | struct pglist_data *pgdat = NODE_DATA(0); |
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index 4be82d6e2b48..cc02573a3271 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -100,11 +100,30 @@ int early_pfn_to_nid(unsigned long pfn) | |||
100 | } | 100 | } |
101 | #endif | 101 | #endif |
102 | 102 | ||
103 | static void * __init | ||
104 | early_node_mem(int nodeid, unsigned long start, unsigned long end, | ||
105 | unsigned long size) | ||
106 | { | ||
107 | unsigned long mem = find_e820_area(start, end, size); | ||
108 | void *ptr; | ||
109 | if (mem != -1L) | ||
110 | return __va(mem); | ||
111 | ptr = __alloc_bootmem_nopanic(size, | ||
112 | SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)); | ||
113 | if (ptr == 0) { | ||
114 | printk(KERN_ERR "Cannot find %lu bytes in node %d\n", | ||
115 | size, nodeid); | ||
116 | return NULL; | ||
117 | } | ||
118 | return ptr; | ||
119 | } | ||
120 | |||
103 | /* Initialize bootmem allocator for a node */ | 121 | /* Initialize bootmem allocator for a node */ |
104 | void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) | 122 | void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) |
105 | { | 123 | { |
106 | unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start; | 124 | unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start; |
107 | unsigned long nodedata_phys; | 125 | unsigned long nodedata_phys; |
126 | void *bootmap; | ||
108 | const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE); | 127 | const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE); |
109 | 128 | ||
110 | start = round_up(start, ZONE_ALIGN); | 129 | start = round_up(start, ZONE_ALIGN); |
@@ -114,13 +133,11 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en | |||
114 | start_pfn = start >> PAGE_SHIFT; | 133 | start_pfn = start >> PAGE_SHIFT; |
115 | end_pfn = end >> PAGE_SHIFT; | 134 | end_pfn = end >> PAGE_SHIFT; |
116 | 135 | ||
117 | nodedata_phys = find_e820_area(start, end, pgdat_size); | 136 | node_data[nodeid] = early_node_mem(nodeid, start, end, pgdat_size); |
118 | if (nodedata_phys == -1L) | 137 | if (node_data[nodeid] == NULL) |
119 | panic("Cannot find memory pgdat in node %d\n", nodeid); | 138 | return; |
120 | 139 | nodedata_phys = __pa(node_data[nodeid]); | |
121 | Dprintk("nodedata_phys %lx\n", nodedata_phys); | ||
122 | 140 | ||
123 | node_data[nodeid] = phys_to_virt(nodedata_phys); | ||
124 | memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t)); | 141 | memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t)); |
125 | NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid]; | 142 | NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid]; |
126 | NODE_DATA(nodeid)->node_start_pfn = start_pfn; | 143 | NODE_DATA(nodeid)->node_start_pfn = start_pfn; |
@@ -129,9 +146,15 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en | |||
129 | /* Find a place for the bootmem map */ | 146 | /* Find a place for the bootmem map */ |
130 | bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); | 147 | bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); |
131 | bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE); | 148 | bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE); |
132 | bootmap_start = find_e820_area(bootmap_start, end, bootmap_pages<<PAGE_SHIFT); | 149 | bootmap = early_node_mem(nodeid, bootmap_start, end, |
133 | if (bootmap_start == -1L) | 150 | bootmap_pages<<PAGE_SHIFT); |
134 | panic("Not enough continuous space for bootmap on node %d", nodeid); | 151 | if (bootmap == NULL) { |
152 | if (nodedata_phys < start || nodedata_phys >= end) | ||
153 | free_bootmem((unsigned long)node_data[nodeid],pgdat_size); | ||
154 | node_data[nodeid] = NULL; | ||
155 | return; | ||
156 | } | ||
157 | bootmap_start = __pa(bootmap); | ||
135 | Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages); | 158 | Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages); |
136 | 159 | ||
137 | bootmap_size = init_bootmem_node(NODE_DATA(nodeid), | 160 | bootmap_size = init_bootmem_node(NODE_DATA(nodeid), |
@@ -142,6 +165,9 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en | |||
142 | 165 | ||
143 | reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); | 166 | reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); |
144 | reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT); | 167 | reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT); |
168 | #ifdef CONFIG_ACPI_NUMA | ||
169 | srat_reserve_add_area(nodeid); | ||
170 | #endif | ||
145 | node_set_online(nodeid); | 171 | node_set_online(nodeid); |
146 | } | 172 | } |
147 | 173 | ||
@@ -335,6 +361,8 @@ __init int numa_setup(char *opt) | |||
335 | #ifdef CONFIG_ACPI_NUMA | 361 | #ifdef CONFIG_ACPI_NUMA |
336 | if (!strncmp(opt,"noacpi",6)) | 362 | if (!strncmp(opt,"noacpi",6)) |
337 | acpi_numa = -1; | 363 | acpi_numa = -1; |
364 | if (!strncmp(opt,"hotadd=", 7)) | ||
365 | hotadd_percent = simple_strtoul(opt+7, NULL, 10); | ||
338 | #endif | 366 | #endif |
339 | return 1; | 367 | return 1; |
340 | } | 368 | } |
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c index 2eb879590dc4..15ae9fcd65a7 100644 --- a/arch/x86_64/mm/srat.c +++ b/arch/x86_64/mm/srat.c | |||
@@ -15,15 +15,26 @@ | |||
15 | #include <linux/bitmap.h> | 15 | #include <linux/bitmap.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/topology.h> | 17 | #include <linux/topology.h> |
18 | #include <linux/bootmem.h> | ||
19 | #include <linux/mm.h> | ||
18 | #include <asm/proto.h> | 20 | #include <asm/proto.h> |
19 | #include <asm/numa.h> | 21 | #include <asm/numa.h> |
20 | #include <asm/e820.h> | 22 | #include <asm/e820.h> |
21 | 23 | ||
24 | #if (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \ | ||
25 | defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) \ | ||
26 | && !defined(CONFIG_MEMORY_HOTPLUG) | ||
27 | #define RESERVE_HOTADD 1 | ||
28 | #endif | ||
29 | |||
22 | static struct acpi_table_slit *acpi_slit; | 30 | static struct acpi_table_slit *acpi_slit; |
23 | 31 | ||
24 | static nodemask_t nodes_parsed __initdata; | 32 | static nodemask_t nodes_parsed __initdata; |
25 | static nodemask_t nodes_found __initdata; | 33 | static nodemask_t nodes_found __initdata; |
26 | static struct bootnode nodes[MAX_NUMNODES] __initdata; | 34 | static struct bootnode nodes[MAX_NUMNODES] __initdata; |
35 | static struct bootnode nodes_add[MAX_NUMNODES] __initdata; | ||
36 | static int found_add_area __initdata; | ||
37 | int hotadd_percent __initdata = 10; | ||
27 | static u8 pxm2node[256] = { [0 ... 255] = 0xff }; | 38 | static u8 pxm2node[256] = { [0 ... 255] = 0xff }; |
28 | 39 | ||
29 | /* Too small nodes confuse the VM badly. Usually they result | 40 | /* Too small nodes confuse the VM badly. Usually they result |
@@ -71,6 +82,10 @@ static __init int conflicting_nodes(unsigned long start, unsigned long end) | |||
71 | static __init void cutoff_node(int i, unsigned long start, unsigned long end) | 82 | static __init void cutoff_node(int i, unsigned long start, unsigned long end) |
72 | { | 83 | { |
73 | struct bootnode *nd = &nodes[i]; | 84 | struct bootnode *nd = &nodes[i]; |
85 | |||
86 | if (found_add_area) | ||
87 | return; | ||
88 | |||
74 | if (nd->start < start) { | 89 | if (nd->start < start) { |
75 | nd->start = start; | 90 | nd->start = start; |
76 | if (nd->end < nd->start) | 91 | if (nd->end < nd->start) |
@@ -90,6 +105,8 @@ static __init void bad_srat(void) | |||
90 | acpi_numa = -1; | 105 | acpi_numa = -1; |
91 | for (i = 0; i < MAX_LOCAL_APIC; i++) | 106 | for (i = 0; i < MAX_LOCAL_APIC; i++) |
92 | apicid_to_node[i] = NUMA_NO_NODE; | 107 | apicid_to_node[i] = NUMA_NO_NODE; |
108 | for (i = 0; i < MAX_NUMNODES; i++) | ||
109 | nodes_add[i].start = nodes[i].end = 0; | ||
93 | } | 110 | } |
94 | 111 | ||
95 | static __init inline int srat_disabled(void) | 112 | static __init inline int srat_disabled(void) |
@@ -155,11 +172,114 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) | |||
155 | pxm, pa->apic_id, node); | 172 | pxm, pa->apic_id, node); |
156 | } | 173 | } |
157 | 174 | ||
175 | #ifdef RESERVE_HOTADD | ||
176 | /* | ||
177 | * Protect against too large hotadd areas that would fill up memory. | ||
178 | */ | ||
179 | static int hotadd_enough_memory(struct bootnode *nd) | ||
180 | { | ||
181 | static unsigned long allocated; | ||
182 | static unsigned long last_area_end; | ||
183 | unsigned long pages = (nd->end - nd->start) >> PAGE_SHIFT; | ||
184 | long mem = pages * sizeof(struct page); | ||
185 | unsigned long addr; | ||
186 | unsigned long allowed; | ||
187 | unsigned long oldpages = pages; | ||
188 | |||
189 | if (mem < 0) | ||
190 | return 0; | ||
191 | allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE; | ||
192 | allowed = (allowed / 100) * hotadd_percent; | ||
193 | if (allocated + mem > allowed) { | ||
194 | /* Give them at least part of their hotadd memory upto hotadd_percent | ||
195 | It would be better to spread the limit out | ||
196 | over multiple hotplug areas, but that is too complicated | ||
197 | right now */ | ||
198 | if (allocated >= allowed) | ||
199 | return 0; | ||
200 | pages = (allowed - allocated + mem) / sizeof(struct page); | ||
201 | mem = pages * sizeof(struct page); | ||
202 | nd->end = nd->start + pages*PAGE_SIZE; | ||
203 | } | ||
204 | /* Not completely fool proof, but a good sanity check */ | ||
205 | addr = find_e820_area(last_area_end, end_pfn<<PAGE_SHIFT, mem); | ||
206 | if (addr == -1UL) | ||
207 | return 0; | ||
208 | if (pages != oldpages) | ||
209 | printk(KERN_NOTICE "SRAT: Hotadd area limited to %lu bytes\n", | ||
210 | pages << PAGE_SHIFT); | ||
211 | last_area_end = addr + mem; | ||
212 | allocated += mem; | ||
213 | return 1; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * It is fine to add this area to the nodes data it will be used later | ||
218 | * This code supports one contigious hot add area per node. | ||
219 | */ | ||
220 | static int reserve_hotadd(int node, unsigned long start, unsigned long end) | ||
221 | { | ||
222 | unsigned long s_pfn = start >> PAGE_SHIFT; | ||
223 | unsigned long e_pfn = end >> PAGE_SHIFT; | ||
224 | int changed = 0; | ||
225 | struct bootnode *nd = &nodes_add[node]; | ||
226 | |||
227 | /* I had some trouble with strange memory hotadd regions breaking | ||
228 | the boot. Be very strict here and reject anything unexpected. | ||
229 | If you want working memory hotadd write correct SRATs. | ||
230 | |||
231 | The node size check is a basic sanity check to guard against | ||
232 | mistakes */ | ||
233 | if ((signed long)(end - start) < NODE_MIN_SIZE) { | ||
234 | printk(KERN_ERR "SRAT: Hotplug area too small\n"); | ||
235 | return -1; | ||
236 | } | ||
237 | |||
238 | /* This check might be a bit too strict, but I'm keeping it for now. */ | ||
239 | if (e820_hole_size(s_pfn, e_pfn) != e_pfn - s_pfn) { | ||
240 | printk(KERN_ERR "SRAT: Hotplug area has existing memory\n"); | ||
241 | return -1; | ||
242 | } | ||
243 | |||
244 | if (!hotadd_enough_memory(&nodes_add[node])) { | ||
245 | printk(KERN_ERR "SRAT: Hotplug area too large\n"); | ||
246 | return -1; | ||
247 | } | ||
248 | |||
249 | /* Looks good */ | ||
250 | |||
251 | found_add_area = 1; | ||
252 | if (nd->start == nd->end) { | ||
253 | nd->start = start; | ||
254 | nd->end = end; | ||
255 | changed = 1; | ||
256 | } else { | ||
257 | if (nd->start == end) { | ||
258 | nd->start = start; | ||
259 | changed = 1; | ||
260 | } | ||
261 | if (nd->end == start) { | ||
262 | nd->end = end; | ||
263 | changed = 1; | ||
264 | } | ||
265 | if (!changed) | ||
266 | printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); | ||
267 | } | ||
268 | |||
269 | if ((nd->end >> PAGE_SHIFT) > end_pfn) | ||
270 | end_pfn = nd->end >> PAGE_SHIFT; | ||
271 | |||
272 | if (changed) | ||
273 | printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", nd->start, nd->end); | ||
274 | return 0; | ||
275 | } | ||
276 | #endif | ||
277 | |||
158 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ | 278 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ |
159 | void __init | 279 | void __init |
160 | acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | 280 | acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) |
161 | { | 281 | { |
162 | struct bootnode *nd; | 282 | struct bootnode *nd, oldnode; |
163 | unsigned long start, end; | 283 | unsigned long start, end; |
164 | int node, pxm; | 284 | int node, pxm; |
165 | int i; | 285 | int i; |
@@ -172,6 +292,8 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
172 | } | 292 | } |
173 | if (ma->flags.enabled == 0) | 293 | if (ma->flags.enabled == 0) |
174 | return; | 294 | return; |
295 | if (ma->flags.hot_pluggable && hotadd_percent == 0) | ||
296 | return; | ||
175 | start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); | 297 | start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); |
176 | end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); | 298 | end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); |
177 | pxm = ma->proximity_domain; | 299 | pxm = ma->proximity_domain; |
@@ -181,10 +303,6 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
181 | bad_srat(); | 303 | bad_srat(); |
182 | return; | 304 | return; |
183 | } | 305 | } |
184 | /* It is fine to add this area to the nodes data it will be used later*/ | ||
185 | if (ma->flags.hot_pluggable == 1) | ||
186 | printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n", | ||
187 | start, end); | ||
188 | i = conflicting_nodes(start, end); | 306 | i = conflicting_nodes(start, end); |
189 | if (i == node) { | 307 | if (i == node) { |
190 | printk(KERN_WARNING | 308 | printk(KERN_WARNING |
@@ -199,6 +317,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
199 | return; | 317 | return; |
200 | } | 318 | } |
201 | nd = &nodes[node]; | 319 | nd = &nodes[node]; |
320 | oldnode = *nd; | ||
202 | if (!node_test_and_set(node, nodes_parsed)) { | 321 | if (!node_test_and_set(node, nodes_parsed)) { |
203 | nd->start = start; | 322 | nd->start = start; |
204 | nd->end = end; | 323 | nd->end = end; |
@@ -208,8 +327,19 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
208 | if (nd->end < end) | 327 | if (nd->end < end) |
209 | nd->end = end; | 328 | nd->end = end; |
210 | } | 329 | } |
330 | |||
211 | printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, | 331 | printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, |
212 | nd->start, nd->end); | 332 | nd->start, nd->end); |
333 | |||
334 | #ifdef RESERVE_HOTADD | ||
335 | if (ma->flags.hot_pluggable && reserve_hotadd(node, start, end) < 0) { | ||
336 | /* Ignore hotadd region. Undo damage */ | ||
337 | printk(KERN_NOTICE "SRAT: Hotplug region ignored\n"); | ||
338 | *nd = oldnode; | ||
339 | if ((nd->start | nd->end) == 0) | ||
340 | node_clear(node, nodes_parsed); | ||
341 | } | ||
342 | #endif | ||
213 | } | 343 | } |
214 | 344 | ||
215 | /* Sanity check to catch more bad SRATs (they are amazingly common). | 345 | /* Sanity check to catch more bad SRATs (they are amazingly common). |
@@ -225,6 +355,9 @@ static int nodes_cover_memory(void) | |||
225 | unsigned long e = nodes[i].end >> PAGE_SHIFT; | 355 | unsigned long e = nodes[i].end >> PAGE_SHIFT; |
226 | pxmram += e - s; | 356 | pxmram += e - s; |
227 | pxmram -= e820_hole_size(s, e); | 357 | pxmram -= e820_hole_size(s, e); |
358 | pxmram -= nodes_add[i].end - nodes_add[i].start; | ||
359 | if ((long)pxmram < 0) | ||
360 | pxmram = 0; | ||
228 | } | 361 | } |
229 | 362 | ||
230 | e820ram = end_pfn - e820_hole_size(0, end_pfn); | 363 | e820ram = end_pfn - e820_hole_size(0, end_pfn); |
@@ -258,7 +391,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
258 | 391 | ||
259 | /* First clean up the node list */ | 392 | /* First clean up the node list */ |
260 | for (i = 0; i < MAX_NUMNODES; i++) { | 393 | for (i = 0; i < MAX_NUMNODES; i++) { |
261 | cutoff_node(i, start, end); | 394 | cutoff_node(i, start, end); |
262 | if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) | 395 | if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) |
263 | unparse_node(i); | 396 | unparse_node(i); |
264 | } | 397 | } |
@@ -282,6 +415,12 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
282 | /* Finally register nodes */ | 415 | /* Finally register nodes */ |
283 | for_each_node_mask(i, nodes_parsed) | 416 | for_each_node_mask(i, nodes_parsed) |
284 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | 417 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); |
418 | /* Try again in case setup_node_bootmem missed one due | ||
419 | to missing bootmem */ | ||
420 | for_each_node_mask(i, nodes_parsed) | ||
421 | if (!node_online(i)) | ||
422 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | ||
423 | |||
285 | for (i = 0; i < NR_CPUS; i++) { | 424 | for (i = 0; i < NR_CPUS; i++) { |
286 | if (cpu_to_node[i] == NUMA_NO_NODE) | 425 | if (cpu_to_node[i] == NUMA_NO_NODE) |
287 | continue; | 426 | continue; |
@@ -303,6 +442,25 @@ static int node_to_pxm(int n) | |||
303 | return 0; | 442 | return 0; |
304 | } | 443 | } |
305 | 444 | ||
445 | void __init srat_reserve_add_area(int nodeid) | ||
446 | { | ||
447 | if (found_add_area && nodes_add[nodeid].end) { | ||
448 | u64 total_mb; | ||
449 | |||
450 | printk(KERN_INFO "SRAT: Reserving hot-add memory space " | ||
451 | "for node %d at %Lx-%Lx\n", | ||
452 | nodeid, nodes_add[nodeid].start, nodes_add[nodeid].end); | ||
453 | total_mb = (nodes_add[nodeid].end - nodes_add[nodeid].start) | ||
454 | >> PAGE_SHIFT; | ||
455 | total_mb *= sizeof(struct page); | ||
456 | total_mb >>= 20; | ||
457 | printk(KERN_INFO "SRAT: This will cost you %Lu MB of " | ||
458 | "pre-allocated memory.\n", (unsigned long long)total_mb); | ||
459 | reserve_bootmem_node(NODE_DATA(nodeid), nodes_add[nodeid].start, | ||
460 | nodes_add[nodeid].end - nodes_add[nodeid].start); | ||
461 | } | ||
462 | } | ||
463 | |||
306 | int __node_distance(int a, int b) | 464 | int __node_distance(int a, int b) |
307 | { | 465 | { |
308 | int index; | 466 | int index; |
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index e616500207e4..a2060e4d5de6 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c | |||
@@ -9,11 +9,16 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/acpi.h> | 10 | #include <linux/acpi.h> |
11 | #include <linux/bitmap.h> | 11 | #include <linux/bitmap.h> |
12 | #include <asm/e820.h> | ||
13 | |||
12 | #include "pci.h" | 14 | #include "pci.h" |
13 | 15 | ||
14 | #define MMCONFIG_APER_SIZE (256*1024*1024) | 16 | #define MMCONFIG_APER_SIZE (256*1024*1024) |
17 | /* Verify the first 16 busses. We assume that systems with more busses | ||
18 | get MCFG right. */ | ||
19 | #define MAX_CHECK_BUS 16 | ||
15 | 20 | ||
16 | static DECLARE_BITMAP(fallback_slots, 32); | 21 | static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS); |
17 | 22 | ||
18 | /* Static virtual mapping of the MMCONFIG aperture */ | 23 | /* Static virtual mapping of the MMCONFIG aperture */ |
19 | struct mmcfg_virt { | 24 | struct mmcfg_virt { |
@@ -55,7 +60,8 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) | |||
55 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) | 60 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) |
56 | { | 61 | { |
57 | char __iomem *addr; | 62 | char __iomem *addr; |
58 | if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), fallback_slots)) | 63 | if (seg == 0 && bus < MAX_CHECK_BUS && |
64 | test_bit(32*bus + PCI_SLOT(devfn), fallback_slots)) | ||
59 | return NULL; | 65 | return NULL; |
60 | addr = get_virt(seg, bus); | 66 | addr = get_virt(seg, bus); |
61 | if (!addr) | 67 | if (!addr) |
@@ -69,8 +75,10 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
69 | char __iomem *addr; | 75 | char __iomem *addr; |
70 | 76 | ||
71 | /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ | 77 | /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ |
72 | if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) | 78 | if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) { |
79 | *value = -1; | ||
73 | return -EINVAL; | 80 | return -EINVAL; |
81 | } | ||
74 | 82 | ||
75 | addr = pci_dev_base(seg, bus, devfn); | 83 | addr = pci_dev_base(seg, bus, devfn); |
76 | if (!addr) | 84 | if (!addr) |
@@ -129,21 +137,26 @@ static struct pci_raw_ops pci_mmcfg = { | |||
129 | Normally this can be expressed in the MCFG by not listing them | 137 | Normally this can be expressed in the MCFG by not listing them |
130 | and assigning suitable _SEGs, but this isn't implemented in some BIOS. | 138 | and assigning suitable _SEGs, but this isn't implemented in some BIOS. |
131 | Instead try to discover all devices on bus 0 that are unreachable using MM | 139 | Instead try to discover all devices on bus 0 that are unreachable using MM |
132 | and fallback for them. | 140 | and fallback for them. */ |
133 | We only do this for bus 0/seg 0 */ | ||
134 | static __init void unreachable_devices(void) | 141 | static __init void unreachable_devices(void) |
135 | { | 142 | { |
136 | int i; | 143 | int i, k; |
137 | for (i = 0; i < 32; i++) { | 144 | /* Use the max bus number from ACPI here? */ |
138 | u32 val1; | 145 | for (k = 0; k < MAX_CHECK_BUS; k++) { |
139 | char __iomem *addr; | 146 | for (i = 0; i < 32; i++) { |
140 | 147 | u32 val1; | |
141 | pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1); | 148 | char __iomem *addr; |
142 | if (val1 == 0xffffffff) | 149 | |
143 | continue; | 150 | pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1); |
144 | addr = pci_dev_base(0, 0, PCI_DEVFN(i, 0)); | 151 | if (val1 == 0xffffffff) |
145 | if (addr == NULL|| readl(addr) != val1) { | 152 | continue; |
146 | set_bit(i, fallback_slots); | 153 | addr = pci_dev_base(0, k, PCI_DEVFN(i, 0)); |
154 | if (addr == NULL|| readl(addr) != val1) { | ||
155 | set_bit(i + 32*k, fallback_slots); | ||
156 | printk(KERN_NOTICE | ||
157 | "PCI: No mmconfig possible on device %x:%x\n", | ||
158 | k, i); | ||
159 | } | ||
147 | } | 160 | } |
148 | } | 161 | } |
149 | } | 162 | } |
@@ -161,6 +174,14 @@ void __init pci_mmcfg_init(void) | |||
161 | (pci_mmcfg_config[0].base_address == 0)) | 174 | (pci_mmcfg_config[0].base_address == 0)) |
162 | return; | 175 | return; |
163 | 176 | ||
177 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||
178 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | ||
179 | E820_RESERVED)) { | ||
180 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | ||
181 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||
182 | return; | ||
183 | } | ||
184 | |||
164 | /* RED-PEN i386 doesn't do _nocache right now */ | 185 | /* RED-PEN i386 doesn't do _nocache right now */ |
165 | pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); | 186 | pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); |
166 | if (pci_mmcfg_virt == NULL) { | 187 | if (pci_mmcfg_virt == NULL) { |
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 152b9370789b..a15b6e3e72c8 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -48,7 +48,6 @@ EXPORT_SYMBOL(memchr); | |||
48 | EXPORT_SYMBOL(strcat); | 48 | EXPORT_SYMBOL(strcat); |
49 | EXPORT_SYMBOL(strchr); | 49 | EXPORT_SYMBOL(strchr); |
50 | EXPORT_SYMBOL(strlen); | 50 | EXPORT_SYMBOL(strlen); |
51 | EXPORT_SYMBOL(strpbrk); | ||
52 | EXPORT_SYMBOL(strncat); | 51 | EXPORT_SYMBOL(strncat); |
53 | EXPORT_SYMBOL(strnlen); | 52 | EXPORT_SYMBOL(strnlen); |
54 | EXPORT_SYMBOL(strrchr); | 53 | EXPORT_SYMBOL(strrchr); |