Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
ea4423c3
Commit
ea4423c3
authored
Jun 19, 2005
by
Russell King
Browse files
Options
Browse Files
Download
Plain Diff
Merge with ../linux-2.6-smp
parents
36c5ed23
fe6ef2da
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
436 additions
and
2 deletions
+436
-2
arch/arm/kernel/head.S
arch/arm/kernel/head.S
+44
-0
arch/arm/kernel/smp.c
arch/arm/kernel/smp.c
+107
-0
arch/arm/mach-integrator/Makefile
arch/arm/mach-integrator/Makefile
+1
-0
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/core.c
+19
-1
arch/arm/mach-integrator/headsmp.S
arch/arm/mach-integrator/headsmp.S
+37
-0
arch/arm/mach-integrator/leds.c
arch/arm/mach-integrator/leds.c
+3
-1
arch/arm/mach-integrator/platsmp.c
arch/arm/mach-integrator/platsmp.c
+192
-0
include/asm-arm/arch-integrator/smp.h
include/asm-arm/arch-integrator/smp.h
+19
-0
include/asm-arm/smp.h
include/asm-arm/smp.h
+14
-0
No files found.
arch/arm/kernel/head.S
View file @
ea4423c3
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
*
linux
/
arch
/
arm
/
kernel
/
head
.
S
*
linux
/
arch
/
arm
/
kernel
/
head
.
S
*
*
*
Copyright
(
C
)
1994
-
2002
Russell
King
*
Copyright
(
C
)
1994
-
2002
Russell
King
*
Copyright
(
c
)
2003
ARM
Limited
*
All
Rights
Reserved
*
*
*
This
program
is
free
software
; you can redistribute it and/or modify
*
This
program
is
free
software
; you can redistribute it and/or modify
*
it
under
the
terms
of
the
GNU
General
Public
License
version
2
as
*
it
under
the
terms
of
the
GNU
General
Public
License
version
2
as
...
@@ -165,6 +167,48 @@ __mmap_switched:
...
@@ -165,6 +167,48 @@ __mmap_switched:
stmia
r6
,
{
r0
,
r4
}
@
Save
control
register
values
stmia
r6
,
{
r0
,
r4
}
@
Save
control
register
values
b
start_kernel
b
start_kernel
#if defined(CONFIG_SMP)
.
type
secondary_startup
,
#
function
ENTRY
(
secondary_startup
)
/
*
*
Common
entry
point
for
secondary
CPUs
.
*
*
Ensure
that
we
're in SVC mode, and IRQs are disabled. Lookup
*
the
processor
type
-
there
is
no
need
to
check
the
machine
type
*
as
it
has
already
been
validated
by
the
primary
processor
.
*/
msr
cpsr_c
,
#
PSR_F_BIT
| PSR_I_BIT |
MODE_SVC
bl
__lookup_processor_type
movs
r10
,
r5
@
invalid
processor
?
moveq
r0
,
#
'p'
@
yes
,
error
'p'
beq
__error
/
*
*
Use
the
page
tables
supplied
from
__cpu_up
.
*/
adr
r4
,
__secondary_data
ldmia
r4
,
{
r5
,
r6
,
r13
}
@
address
to
jump
to
after
sub
r4
,
r4
,
r5
@
mmu
has
been
enabled
ldr
r4
,
[
r6
,
r4
]
@
get
secondary_data
.
pgdir
adr
lr
,
__enable_mmu
@
return
address
add
pc
,
r10
,
#
12
@
initialise
processor
@
(
return
control
reg
)
/
*
*
r6
=
&
secondary_data
*/
ENTRY
(
__secondary_switched
)
ldr
sp
,
[
r6
,
#
4
]
@
get
secondary_data
.
stack
mov
fp
,
#
0
b
secondary_start_kernel
.
type
__secondary_data
,
%
object
__secondary_data
:
.
long
.
.
long
secondary_data
.
long
__secondary_switched
#endif /* defined(CONFIG_SMP) */
/*
/*
...
...
arch/arm/kernel/smp.c
View file @
ea4423c3
...
@@ -24,6 +24,9 @@
...
@@ -24,6 +24,9 @@
#include <asm/atomic.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
#include <asm/cacheflush.h>
#include <asm/cpu.h>
#include <asm/cpu.h>
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/processor.h>
#include <asm/processor.h>
#include <asm/tlbflush.h>
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
#include <asm/ptrace.h>
...
@@ -36,6 +39,13 @@
...
@@ -36,6 +39,13 @@
cpumask_t
cpu_present_mask
;
cpumask_t
cpu_present_mask
;
cpumask_t
cpu_online_map
;
cpumask_t
cpu_online_map
;
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
* where to place its SVC stack
*/
struct
secondary_data
secondary_data
;
/*
/*
* structures for inter-processor calls
* structures for inter-processor calls
* - A collection of single bit ipi messages.
* - A collection of single bit ipi messages.
...
@@ -71,6 +81,8 @@ static DEFINE_SPINLOCK(smp_call_function_lock);
...
@@ -71,6 +81,8 @@ static DEFINE_SPINLOCK(smp_call_function_lock);
int
__init
__cpu_up
(
unsigned
int
cpu
)
int
__init
__cpu_up
(
unsigned
int
cpu
)
{
{
struct
task_struct
*
idle
;
struct
task_struct
*
idle
;
pgd_t
*
pgd
;
pmd_t
*
pmd
;
int
ret
;
int
ret
;
/*
/*
...
@@ -83,10 +95,55 @@ int __init __cpu_up(unsigned int cpu)
...
@@ -83,10 +95,55 @@ int __init __cpu_up(unsigned int cpu)
return
PTR_ERR
(
idle
);
return
PTR_ERR
(
idle
);
}
}
/*
* Allocate initial page tables to allow the new CPU to
* enable the MMU safely. This essentially means a set
* of our "standard" page tables, with the addition of
* a 1:1 mapping for the physical address of the kernel.
*/
pgd
=
pgd_alloc
(
&
init_mm
);
pmd
=
pmd_offset
(
pgd
,
PHYS_OFFSET
);
*
pmd
=
__pmd
((
PHYS_OFFSET
&
PGDIR_MASK
)
|
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
);
/*
* We need to tell the secondary core where to find
* its stack and the page tables.
*/
secondary_data
.
stack
=
(
void
*
)
idle
->
thread_info
+
THREAD_SIZE
-
8
;
secondary_data
.
pgdir
=
virt_to_phys
(
pgd
);
wmb
();
/*
/*
* Now bring the CPU into our world.
* Now bring the CPU into our world.
*/
*/
ret
=
boot_secondary
(
cpu
,
idle
);
ret
=
boot_secondary
(
cpu
,
idle
);
if
(
ret
==
0
)
{
unsigned
long
timeout
;
/*
* CPU was successfully started, wait for it
* to come online or time out.
*/
timeout
=
jiffies
+
HZ
;
while
(
time_before
(
jiffies
,
timeout
))
{
if
(
cpu_online
(
cpu
))
break
;
udelay
(
10
);
barrier
();
}
if
(
!
cpu_online
(
cpu
))
ret
=
-
EIO
;
}
secondary_data
.
stack
=
0
;
secondary_data
.
pgdir
=
0
;
*
pmd_offset
(
pgd
,
PHYS_OFFSET
)
=
__pmd
(
0
);
pgd_free
(
pgd
);
if
(
ret
)
{
if
(
ret
)
{
printk
(
KERN_CRIT
"cpu_up: processor %d failed to boot
\n
"
,
cpu
);
printk
(
KERN_CRIT
"cpu_up: processor %d failed to boot
\n
"
,
cpu
);
/*
/*
...
@@ -97,6 +154,56 @@ int __init __cpu_up(unsigned int cpu)
...
@@ -97,6 +154,56 @@ int __init __cpu_up(unsigned int cpu)
return
ret
;
return
ret
;
}
}
/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
*/
asmlinkage
void
__init
secondary_start_kernel
(
void
)
{
struct
mm_struct
*
mm
=
&
init_mm
;
unsigned
int
cpu
=
smp_processor_id
();
printk
(
"CPU%u: Booted secondary processor
\n
"
,
cpu
);
/*
* All kernel threads share the same mm context; grab a
* reference and switch to it.
*/
atomic_inc
(
&
mm
->
mm_users
);
atomic_inc
(
&
mm
->
mm_count
);
current
->
active_mm
=
mm
;
cpu_set
(
cpu
,
mm
->
cpu_vm_mask
);
cpu_switch_mm
(
mm
->
pgd
,
mm
);
enter_lazy_tlb
(
mm
,
current
);
cpu_init
();
/*
* Give the platform a chance to do its own initialisation.
*/
platform_secondary_init
(
cpu
);
/*
* Enable local interrupts.
*/
local_irq_enable
();
local_fiq_enable
();
calibrate_delay
();
smp_store_cpu_info
(
cpu
);
/*
* OK, now it's safe to let the boot CPU continue
*/
cpu_set
(
cpu
,
cpu_online_map
);
/*
* OK, it's off to the idle thread for us
*/
cpu_idle
();
}
/*
/*
* Called by both boot and secondaries to move global data into
* Called by both boot and secondaries to move global data into
* per-processor storage.
* per-processor storage.
...
...
arch/arm/mach-integrator/Makefile
View file @
ea4423c3
...
@@ -12,3 +12,4 @@ obj-$(CONFIG_LEDS) += leds.o
...
@@ -12,3 +12,4 @@ obj-$(CONFIG_LEDS) += leds.o
obj-$(CONFIG_PCI)
+=
pci_v3.o pci.o
obj-$(CONFIG_PCI)
+=
pci_v3.o pci.o
obj-$(CONFIG_CPU_FREQ_INTEGRATOR)
+=
cpu.o
obj-$(CONFIG_CPU_FREQ_INTEGRATOR)
+=
cpu.o
obj-$(CONFIG_INTEGRATOR_IMPD1)
+=
impd1.o
obj-$(CONFIG_INTEGRATOR_IMPD1)
+=
impd1.o
obj-$(CONFIG_SMP)
+=
platsmp.o headsmp.o
arch/arm/mach-integrator/core.c
View file @
ea4423c3
...
@@ -14,6 +14,7 @@
...
@@ -14,6 +14,7 @@
#include <linux/spinlock.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <asm/hardware.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/irq.h>
...
@@ -221,7 +222,24 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -221,7 +222,24 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
*/
timer1
->
TimerClear
=
1
;
timer1
->
TimerClear
=
1
;
/*
* the clock tick routines are only processed on the
* primary CPU
*/
if
(
hard_smp_processor_id
()
==
0
)
{
nmi_tick
();
timer_tick
(
regs
);
timer_tick
(
regs
);
#ifdef CONFIG_SMP
smp_send_timer
();
#endif
}
#ifdef CONFIG_SMP
/*
* this is the ARM equivalent of the APIC timer interrupt
*/
update_process_times
(
user_mode
(
regs
));
#endif
/* CONFIG_SMP */
write_sequnlock
(
&
xtime_lock
);
write_sequnlock
(
&
xtime_lock
);
...
...
arch/arm/mach-integrator/headsmp.S
0 → 100644
View file @
ea4423c3
/*
*
linux
/
arch
/
arm
/
mach
-
integrator
/
headsmp
.
S
*
*
Copyright
(
c
)
2003
ARM
Limited
*
All
Rights
Reserved
*
*
This
program
is
free
software
; you can redistribute it and/or modify
*
it
under
the
terms
of
the
GNU
General
Public
License
version
2
as
*
published
by
the
Free
Software
Foundation
.
*/
#include <linux/linkage.h>
#include <linux/init.h>
__INIT
/*
*
Integrator
specific
entry
point
for
secondary
CPUs
.
This
provides
*
a
"holding pen"
into
which
all
secondary
cores
are
held
until
we
're
*
ready
for
them
to
initialise
.
*/
ENTRY
(
integrator_secondary_startup
)
adr
r4
,
1
f
ldmia
r4
,
{
r5
,
r6
}
sub
r4
,
r4
,
r5
ldr
r6
,
[
r6
,
r4
]
pen
:
ldr
r7
,
[
r6
]
cmp
r7
,
r0
bne
pen
/
*
*
we
've been released from the holding pen: secondary_stack
*
should
now
contain
the
SVC
stack
for
this
core
*/
b
secondary_startup
1
:
.
long
.
.
long
phys_pen_release
arch/arm/mach-integrator/leds.c
View file @
ea4423c3
...
@@ -22,6 +22,8 @@
...
@@ -22,6 +22,8 @@
*/
*/
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/io.h>
...
@@ -85,4 +87,4 @@ static int __init leds_init(void)
...
@@ -85,4 +87,4 @@ static int __init leds_init(void)
return
0
;
return
0
;
}
}
_
_initcall
(
leds_init
);
core
_initcall
(
leds_init
);
arch/arm/mach-integrator/platsmp.c
0 → 100644
View file @
ea4423c3
/*
* linux/arch/arm/mach-cintegrator/platsmp.c
*
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <asm/atomic.h>
#include <asm/delay.h>
#include <asm/mmu_context.h>
#include <asm/procinfo.h>
#include <asm/ptrace.h>
#include <asm/smp.h>
extern
void
integrator_secondary_startup
(
void
);
/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
volatile
int
__initdata
pen_release
=
-
1
;
unsigned
long
__initdata
phys_pen_release
=
0
;
static
DEFINE_SPINLOCK
(
boot_lock
);
void
__init
platform_secondary_init
(
unsigned
int
cpu
)
{
/*
* the primary core may have used a "cross call" soft interrupt
* to get this processor out of WFI in the BootMonitor - make
* sure that we are no longer being sent this soft interrupt
*/
smp_cross_call_done
(
cpumask_of_cpu
(
cpu
));
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
secondary_scan_irqs
();
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
pen_release
=
-
1
;
/*
* Synchronise with the boot thread.
*/
spin_lock
(
&
boot_lock
);
spin_unlock
(
&
boot_lock
);
}
int
__init
boot_secondary
(
unsigned
int
cpu
,
struct
task_struct
*
idle
)
{
unsigned
long
timeout
;
/*
* set synchronisation state between this boot processor
* and the secondary one
*/
spin_lock
(
&
boot_lock
);
/*
* The secondary processor is waiting to be released from
* the holding pen - release it, then wait for it to flag
* that it has been released by resetting pen_release.
*
* Note that "pen_release" is the hardware CPU ID, whereas
* "cpu" is Linux's internal ID.
*/
pen_release
=
cpu
;
/*
* XXX
*
* This is a later addition to the booting protocol: the
* bootMonitor now puts secondary cores into WFI, so
* poke_milo() no longer gets the cores moving; we need
* to send a soft interrupt to wake the secondary core.
* Use smp_cross_call() for this, since there's little
* point duplicating the code here
*/
smp_cross_call
(
cpumask_of_cpu
(
cpu
));
timeout
=
jiffies
+
(
1
*
HZ
);
while
(
time_before
(
jiffies
,
timeout
))
{
if
(
pen_release
==
-
1
)
break
;
udelay
(
10
);
}
/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
*/
spin_unlock
(
&
boot_lock
);
return
pen_release
!=
-
1
?
-
ENOSYS
:
0
;
}
static
void
__init
poke_milo
(
void
)
{
extern
void
secondary_startup
(
void
);
/* nobody is to be released from the pen yet */
pen_release
=
-
1
;
phys_pen_release
=
virt_to_phys
(
&
pen_release
);
/*
* write the address of secondary startup into the system-wide
* flags register, then clear the bottom two bits, which is what
* BootMonitor is waiting for
*/
#if 1
#define CINTEGRATOR_HDR_FLAGSS_OFFSET 0x30
__raw_writel
(
virt_to_phys
(
integrator_secondary_startup
),
(
IO_ADDRESS
(
INTEGRATOR_HDR_BASE
)
+
CINTEGRATOR_HDR_FLAGSS_OFFSET
));
#define CINTEGRATOR_HDR_FLAGSC_OFFSET 0x34
__raw_writel
(
3
,
(
IO_ADDRESS
(
INTEGRATOR_HDR_BASE
)
+
CINTEGRATOR_HDR_FLAGSC_OFFSET
));
#endif
mb
();
}
void
__init
smp_prepare_cpus
(
unsigned
int
max_cpus
)
{
unsigned
int
ncores
=
get_core_count
();
unsigned
int
cpu
=
smp_processor_id
();
int
i
;
/* sanity check */
if
(
ncores
==
0
)
{
printk
(
KERN_ERR
"Integrator/CP: strange CM count of 0? Default to 1
\n
"
);
ncores
=
1
;
}
if
(
ncores
>
NR_CPUS
)
{
printk
(
KERN_WARNING
"Integrator/CP: no. of cores (%d) greater than configured "
"maximum of %d - clipping
\n
"
,
ncores
,
NR_CPUS
);
ncores
=
NR_CPUS
;
}
/*
* start with some more config for the Boot CPU, now that
* the world is a bit more alive (which was not the case
* when smp_prepare_boot_cpu() was called)
*/
smp_store_cpu_info
(
cpu
);
/*
* are we trying to boot more cores than exist?
*/
if
(
max_cpus
>
ncores
)
max_cpus
=
ncores
;
/*
* Initialise the present mask - this tells us which CPUs should
* be present.
*/
for
(
i
=
0
;
i
<
max_cpus
;
i
++
)
{
cpu_set
(
i
,
cpu_present_mask
);
}
/*
* Do we need any more CPUs? If so, then let them know where
* to start. Note that, on modern versions of MILO, the "poke"
* doesn't actually do anything until each individual core is
* sent a soft interrupt to get it out of WFI
*/
if
(
max_cpus
>
1
)
poke_milo
();
}
include/asm-arm/arch-integrator/smp.h
0 → 100644
View file @
ea4423c3
#ifndef ASMARM_ARCH_SMP_H
#define ASMARM_ARCH_SMP_H
#include <linux/config.h>
#include <asm/arch/hardware.h>
#include <asm/io.h>
#define hard_smp_processor_id() \
({ \
unsigned int cpunum; \
__asm__("mrc p15, 0, %0, c0, c0, 5" \
: "=r" (cpunum)); \
cpunum &= 0x0F; \
})
extern
void
secondary_scan_irqs
(
void
);
#endif
include/asm-arm/smp.h
View file @
ea4423c3
...
@@ -55,4 +55,18 @@ extern void smp_cross_call(cpumask_t callmap);
...
@@ -55,4 +55,18 @@ extern void smp_cross_call(cpumask_t callmap);
*/
*/
extern
int
boot_secondary
(
unsigned
int
cpu
,
struct
task_struct
*
);
extern
int
boot_secondary
(
unsigned
int
cpu
,
struct
task_struct
*
);
/*
* Perform platform specific initialisation of the specified CPU.
*/
extern
void
platform_secondary_init
(
unsigned
int
cpu
);
/*
* Initial data for bringing up a secondary CPU.
*/
struct
secondary_data
{
unsigned
long
pgdir
;
void
*
stack
;
};
extern
struct
secondary_data
secondary_data
;
#endif
/* ifndef __ASM_ARM_SMP_H */
#endif
/* ifndef __ASM_ARM_SMP_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment