diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2011-04-21 00:20:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-21 19:44:44 -0400 |
commit | 5fcafb7a23e35b2f1a5243f4dd536240f52c8ceb (patch) | |
tree | f3967b2d935e2e492d55ec80d69c3437750cdde0 /arch/sparc | |
parent | 1827237065815373421c087c84d2a779d61c13d3 (diff) |
sparc32: always define boot_cpu_id
Define boot_cpu_id in single-processor kernels as well. This is
to support architectures which can boot on other than CPU0.
Sam Ravnborg has written the cleanup parts by extracting
boot_cpu_id from smp_32.c into setup_32.c and cleaned up
sun4d_irq.c.
boot_cpu_id was initialized before BSS was cleared in
sun4c_continue_boot, instead boot_cpu_id is set to 0xff to
avoid BSS. If boot_cpu_id is untouched (0xff) by bootup code
it will be overwritten to 0. boot_cpu_id4 is automatically
calculated in common code.
Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/include/asm/setup.h | 12 | ||||
-rw-r--r-- | arch/sparc/kernel/head_32.S | 26 | ||||
-rw-r--r-- | arch/sparc/kernel/setup_32.c | 4 | ||||
-rw-r--r-- | arch/sparc/kernel/smp_32.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4d_irq.c | 5 |
5 files changed, 35 insertions, 14 deletions
diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h index 2643c62f4ac0..64718ba26434 100644 --- a/arch/sparc/include/asm/setup.h +++ b/arch/sparc/include/asm/setup.h | |||
@@ -11,4 +11,16 @@ | |||
11 | # define COMMAND_LINE_SIZE 256 | 11 | # define COMMAND_LINE_SIZE 256 |
12 | #endif | 12 | #endif |
13 | 13 | ||
14 | #ifdef __KERNEL__ | ||
15 | |||
16 | #ifdef CONFIG_SPARC32 | ||
17 | /* The CPU that was used for booting | ||
18 | * Only sun4d + leon may have boot_cpu_id != 0 | ||
19 | */ | ||
20 | extern unsigned char boot_cpu_id; | ||
21 | extern unsigned char boot_cpu_id4; | ||
22 | #endif | ||
23 | |||
24 | #endif /* __KERNEL__ */ | ||
25 | |||
14 | #endif /* _SPARC_SETUP_H */ | 26 | #endif /* _SPARC_SETUP_H */ |
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index 59423491cef8..520c615d3766 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S | |||
@@ -816,10 +816,7 @@ got_prop: | |||
816 | 816 | ||
817 | .global leon_smp_init | 817 | .global leon_smp_init |
818 | leon_smp_init: | 818 | leon_smp_init: |
819 | sethi %hi(boot_cpu_id), %g1 ! master always 0 | 819 | /* let boot_cpu_id default to 0 (master always 0) */ |
820 | stb %g0, [%g1 + %lo(boot_cpu_id)] | ||
821 | sethi %hi(boot_cpu_id4), %g1 ! master always 0 | ||
822 | stb %g0, [%g1 + %lo(boot_cpu_id4)] | ||
823 | 820 | ||
824 | rd %asr17,%g1 | 821 | rd %asr17,%g1 |
825 | srl %g1,28,%g1 | 822 | srl %g1,28,%g1 |
@@ -893,9 +890,6 @@ sun4d_init: | |||
893 | sta %g4, [%g0] ASI_M_VIKING_TMP1 | 890 | sta %g4, [%g0] ASI_M_VIKING_TMP1 |
894 | sethi %hi(boot_cpu_id), %g5 | 891 | sethi %hi(boot_cpu_id), %g5 |
895 | stb %g4, [%g5 + %lo(boot_cpu_id)] | 892 | stb %g4, [%g5 + %lo(boot_cpu_id)] |
896 | sll %g4, 2, %g4 | ||
897 | sethi %hi(boot_cpu_id4), %g5 | ||
898 | stb %g4, [%g5 + %lo(boot_cpu_id4)] | ||
899 | #endif | 893 | #endif |
900 | 894 | ||
901 | /* Fall through to sun4m_init */ | 895 | /* Fall through to sun4m_init */ |
@@ -1024,14 +1018,28 @@ sun4c_continue_boot: | |||
1024 | bl 1b | 1018 | bl 1b |
1025 | add %o0, 0x1, %o0 | 1019 | add %o0, 0x1, %o0 |
1026 | 1020 | ||
1021 | /* If boot_cpu_id has not been setup by machine specific | ||
1022 | * init-code above we default it to zero. | ||
1023 | */ | ||
1024 | sethi %hi(boot_cpu_id), %g2 | ||
1025 | ldub [%g2 + %lo(boot_cpu_id)], %g3 | ||
1026 | cmp %g3, 0xff | ||
1027 | bne 1f | ||
1028 | nop | ||
1029 | mov %g0, %g3 | ||
1030 | stub %g3, [%g2 + %lo(boot_cpu_id)] | ||
1031 | |||
1032 | 1: /* boot_cpu_id set. calculate boot_cpu_id4 = boot_cpu_id*4 */ | ||
1033 | sll %g3, 2, %g3 | ||
1034 | sethi %hi(boot_cpu_id4), %g2 | ||
1035 | stub %g3, [%g2 + %lo(boot_cpu_id4)] | ||
1036 | |||
1027 | /* Initialize the uwinmask value for init task just in case. | 1037 | /* Initialize the uwinmask value for init task just in case. |
1028 | * But first make current_set[boot_cpu_id] point to something useful. | 1038 | * But first make current_set[boot_cpu_id] point to something useful. |
1029 | */ | 1039 | */ |
1030 | set init_thread_union, %g6 | 1040 | set init_thread_union, %g6 |
1031 | set current_set, %g2 | 1041 | set current_set, %g2 |
1032 | #ifdef CONFIG_SMP | 1042 | #ifdef CONFIG_SMP |
1033 | sethi %hi(boot_cpu_id4), %g3 | ||
1034 | ldub [%g3 + %lo(boot_cpu_id4)], %g3 | ||
1035 | st %g6, [%g2] | 1043 | st %g6, [%g2] |
1036 | add %g2, %g3, %g2 | 1044 | add %g2, %g3, %g2 |
1037 | #endif | 1045 | #endif |
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index ef8a2ed95161..3609bdee9ed2 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c | |||
@@ -103,6 +103,10 @@ static unsigned int boot_flags __initdata = 0; | |||
103 | /* Exported for mm/init.c:paging_init. */ | 103 | /* Exported for mm/init.c:paging_init. */ |
104 | unsigned long cmdline_memory_size __initdata = 0; | 104 | unsigned long cmdline_memory_size __initdata = 0; |
105 | 105 | ||
106 | /* which CPU booted us (0xff = not set) */ | ||
107 | unsigned char boot_cpu_id = 0xff; /* 0xff will make it into DATA section... */ | ||
108 | unsigned char boot_cpu_id4; /* boot_cpu_id << 2 */ | ||
109 | |||
106 | static void | 110 | static void |
107 | prom_console_write(struct console *con, const char *s, unsigned n) | 111 | prom_console_write(struct console *con, const char *s, unsigned n) |
108 | { | 112 | { |
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 91c10fb70858..4a1d5b7f20d3 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c | |||
@@ -37,8 +37,6 @@ | |||
37 | #include "irq.h" | 37 | #include "irq.h" |
38 | 38 | ||
39 | volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; | 39 | volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; |
40 | unsigned char boot_cpu_id = 0; | ||
41 | unsigned char boot_cpu_id4 = 0; /* boot_cpu_id << 2 */ | ||
42 | 40 | ||
43 | cpumask_t smp_commenced_mask = CPU_MASK_NONE; | 41 | cpumask_t smp_commenced_mask = CPU_MASK_NONE; |
44 | 42 | ||
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 14a043531dcb..b830914e32d3 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/io.h> | 14 | #include <asm/io.h> |
15 | #include <asm/sbi.h> | 15 | #include <asm/sbi.h> |
16 | #include <asm/cacheflush.h> | 16 | #include <asm/cacheflush.h> |
17 | #include <asm/setup.h> | ||
17 | 18 | ||
18 | #include "kernel.h" | 19 | #include "kernel.h" |
19 | #include "irq.h" | 20 | #include "irq.h" |
@@ -438,11 +439,9 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn) | |||
438 | void __init sun4d_init_sbi_irq(void) | 439 | void __init sun4d_init_sbi_irq(void) |
439 | { | 440 | { |
440 | struct device_node *dp; | 441 | struct device_node *dp; |
441 | int target_cpu = 0; | 442 | int target_cpu; |
442 | 443 | ||
443 | #ifdef CONFIG_SMP | ||
444 | target_cpu = boot_cpu_id; | 444 | target_cpu = boot_cpu_id; |
445 | #endif | ||
446 | for_each_node_by_name(dp, "sbi") { | 445 | for_each_node_by_name(dp, "sbi") { |
447 | int devid = of_getintprop_default(dp, "device-id", 0); | 446 | int devid = of_getintprop_default(dp, "device-id", 0); |
448 | int board = of_getintprop_default(dp, "board#", 0); | 447 | int board = of_getintprop_default(dp, "board#", 0); |