Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 279914
b: refs/heads/master
c: 290130a
h: refs/heads/master
v: v3
  • Loading branch information
Will Deacon committed Dec 12, 2011
1 parent a05760c commit 3d550c5
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2d81f1fe81b753a5744fd2deceafab3e62ba02d5
refs/heads/master: 290130a17718c1451bb8a77a5e2510e0279bd5f3
50 changes: 40 additions & 10 deletions trunk/arch/arm/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,23 @@ static int __init hlt_setup(char *__unused)
__setup("nohlt", nohlt_setup);
__setup("hlt", hlt_setup);

void soft_restart(unsigned long addr)
extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
typedef void (*phys_reset_t)(unsigned long);

/*
* A temporary stack to use for CPU reset. This is static so that we
* don't clobber it with the identity mapping. When running with this
* stack, any references to the current task *will not work* so you
* should really do as little as possible before jumping to your reset
* code.
*/
static u64 soft_restart_stack[16];

static void __soft_restart(void *addr)
{
/* Disable interrupts first */
local_irq_disable();
local_fiq_disable();
phys_reset_t phys_reset;

/*
* Tell the mm system that we are going to reboot -
* we may need it to insert some 1:1 mappings so that
* soft boot works.
*/
/* Take out a flat memory mapping. */
setup_mm_for_reboot();

/* Clean and invalidate caches */
Expand All @@ -114,7 +120,31 @@ void soft_restart(unsigned long addr)
/* Push out any further dirty data, and ensure cache is empty */
flush_cache_all();

cpu_reset(addr);
/* Switch to the identity mapping. */
phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
phys_reset((unsigned long)addr);

/* Should never get here. */
BUG();
}

void soft_restart(unsigned long addr)
{
u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);

/* Disable interrupts first */
local_irq_disable();
local_fiq_disable();

/* Disable the L2 if we're the last man standing. */
if (num_online_cpus() == 1)
outer_disable();

/* Change to the new stack and continue with the reset. */
call_with_stack(__soft_restart, (void *)addr, (void *)stack);

/* Should never get here. */
BUG();
}

void arm_machine_restart(char mode, const char *cmd)
Expand Down

0 comments on commit 3d550c5

Please sign in to comment.