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
8b22c249
Commit
8b22c249
authored
Jun 19, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/home/rmk/linux-2.6-arm
parents
7df55125
ea4423c3
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
442 additions
and
3 deletions
+442
-3
arch/arm/kernel/head.S
arch/arm/kernel/head.S
+44
-0
arch/arm/kernel/setup.c
arch/arm/kernel/setup.c
+1
-1
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
arch/arm/mach-pxa/pm.c
arch/arm/mach-pxa/pm.c
+2
-0
arch/arm/mach-sa1100/pm.c
arch/arm/mach-sa1100/pm.c
+2
-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
include/asm-arm/system.h
include/asm-arm/system.h
+1
-0
No files found.
arch/arm/kernel/head.S
View file @
8b22c249
...
...
@@ -2,6 +2,8 @@
*
linux
/
arch
/
arm
/
kernel
/
head
.
S
*
*
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
*
it
under
the
terms
of
the
GNU
General
Public
License
version
2
as
...
...
@@ -165,6 +167,48 @@ __mmap_switched:
stmia
r6
,
{
r0
,
r4
}
@
Save
control
register
values
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/setup.c
View file @
8b22c249
...
...
@@ -328,7 +328,7 @@ static void __init setup_processor(void)
* cpu_init dumps the cache information, initialises SMP specific
* information, and sets up the per-CPU stacks.
*/
void
__init
cpu_init
(
void
)
void
cpu_init
(
void
)
{
unsigned
int
cpu
=
smp_processor_id
();
struct
stack
*
stk
=
&
stacks
[
cpu
];
...
...
arch/arm/kernel/smp.c
View file @
8b22c249
...
...
@@ -24,6 +24,9 @@
#include <asm/atomic.h>
#include <asm/cacheflush.h>
#include <asm/cpu.h>
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/processor.h>
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
...
...
@@ -36,6 +39,13 @@
cpumask_t
cpu_present_mask
;
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
* - A collection of single bit ipi messages.
...
...
@@ -71,6 +81,8 @@ static DEFINE_SPINLOCK(smp_call_function_lock);
int
__init
__cpu_up
(
unsigned
int
cpu
)
{
struct
task_struct
*
idle
;
pgd_t
*
pgd
;
pmd_t
*
pmd
;
int
ret
;
/*
...
...
@@ -83,10 +95,55 @@ int __init __cpu_up(unsigned int cpu)
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.
*/
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
)
{
printk
(
KERN_CRIT
"cpu_up: processor %d failed to boot
\n
"
,
cpu
);
/*
...
...
@@ -97,6 +154,56 @@ int __init __cpu_up(unsigned int cpu)
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
* per-processor storage.
...
...
arch/arm/mach-integrator/Makefile
View file @
8b22c249
...
...
@@ -12,3 +12,4 @@ obj-$(CONFIG_LEDS) += leds.o
obj-$(CONFIG_PCI)
+=
pci_v3.o pci.o
obj-$(CONFIG_CPU_FREQ_INTEGRATOR)
+=
cpu.o
obj-$(CONFIG_INTEGRATOR_IMPD1)
+=
impd1.o
obj-$(CONFIG_SMP)
+=
platsmp.o headsmp.o
arch/arm/mach-integrator/core.c
View file @
8b22c249
...
...
@@ -14,6 +14,7 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <asm/hardware.h>
#include <asm/irq.h>
...
...
@@ -221,7 +222,24 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
timer1
->
TimerClear
=
1
;
timer_tick
(
regs
);
/*
* the clock tick routines are only processed on the
* primary CPU
*/
if
(
hard_smp_processor_id
()
==
0
)
{
nmi_tick
();
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
);
...
...
arch/arm/mach-integrator/headsmp.S
0 → 100644
View file @
8b22c249
/*
*
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 @
8b22c249
...
...
@@ -22,6 +22,8 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/io.h>
...
...
@@ -85,4 +87,4 @@ static int __init leds_init(void)
return
0
;
}
_
_initcall
(
leds_init
);
core
_initcall
(
leds_init
);
arch/arm/mach-integrator/platsmp.c
0 → 100644
View file @
8b22c249
/*
* 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
();
}
arch/arm/mach-pxa/pm.c
View file @
8b22c249
...
...
@@ -133,6 +133,8 @@ static int pxa_pm_enter(suspend_state_t state)
/* *** go zzz *** */
pxa_cpu_pm_enter
(
state
);
cpu_init
();
/* after sleeping, validate the checksum */
checksum
=
0
;
for
(
i
=
0
;
i
<
SLEEP_SAVE_SIZE
-
1
;
i
++
)
...
...
arch/arm/mach-sa1100/pm.c
View file @
8b22c249
...
...
@@ -88,6 +88,8 @@ static int sa11x0_pm_enter(suspend_state_t state)
/* go zzz */
sa1100_cpu_suspend
();
cpu_init
();
/*
* Ensure not to come back here if it wasn't intended
*/
...
...
include/asm-arm/arch-integrator/smp.h
0 → 100644
View file @
8b22c249
#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 @
8b22c249
...
...
@@ -55,4 +55,18 @@ extern void smp_cross_call(cpumask_t callmap);
*/
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 */
include/asm-arm/system.h
View file @
8b22c249
...
...
@@ -104,6 +104,7 @@ extern void show_pte(struct mm_struct *mm, unsigned long addr);
extern
void
__show_regs
(
struct
pt_regs
*
);
extern
int
cpu_architecture
(
void
);
extern
void
cpu_init
(
void
);
#define set_cr(x) \
__asm__ __volatile__( \
...
...
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