static void __init create_trampoline(unsigned long addr) { unsigned int *p = (unsigned int *)addr; /* The maximum range of a single instruction branch, is the current * instruction's address + (32 MB - 4) bytes. For the trampoline we * need to branch to current address + 32 MB. So we insert a nop at * the trampoline address, then the next instruction (+ 4 bytes) * does a branch to (32 MB - 4). The net effect is that when we * branch to "addr" we jump to ("addr" + 32 MB). Although it requires * two instructions it doesn't require any registers. */ patch_instruction(p, PPC_INST_NOP); patch_branch(++p, addr + PHYSICAL_START, 0); }
static void __init create_trampoline(unsigned long addr) { unsigned int *p = (unsigned int *)addr; /* */ patch_instruction(p, PPC_INST_NOP); patch_branch(++p, addr + PHYSICAL_START, 0); }
static int __init smp_86xx_kick_cpu(int nr) { unsigned int save_vector; unsigned long target, flags; int n = 0; unsigned int *vector = (unsigned int *)(KERNELBASE + 0x100); if (nr < 0 || nr >= NR_CPUS) return -ENOENT; pr_debug("smp_86xx_kick_cpu: kick CPU #%d\n", nr); local_irq_save(flags); save_vector = *vector; target = (unsigned long) __secondary_start_mpc86xx; patch_branch(vector, target, BRANCH_SET_LINK); smp_86xx_release_core(nr); while ((__secondary_hold_acknowledge != nr) && (n++, n < 1000)) mdelay(1); *vector = save_vector; flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); local_irq_restore(flags); pr_debug("wait CPU #%d for %d msecs.\n", nr, n); return 0; }
/* Returns whether it had to change page protections */ static bool patch_coarse_branch(cache_pc stub, cache_pc tgt, bool hot_patch, coarse_info_t *info /*OPTIONAL*/) { // COMPLETEDD #498 patch_coarse_branch bool stubs_readonly = false; bool stubs_restore = false; if (DYNAMO_OPTION(persist_protect_stubs)) { if (info == NULL) info = get_stub_coarse_info(stub); ASSERT(info != NULL); if (info->stubs_readonly) { stubs_readonly = true; stubs_restore = true; /* if we don't preserve mapped-in COW state the protection change * will fail (case 10570) */ make_copy_on_writable((byte *)PAGE_START(entrance_stub_jmp(stub)), /* stub jmp can't cross page boundary (can't * cross cache line in fact) */ PAGE_SIZE); if (DYNAMO_OPTION(persist_protect_stubs_limit) > 0) { info->stubs_write_count++; if (info->stubs_write_count > DYNAMO_OPTION(persist_protect_stubs_limit)) { SYSLOG_INTERNAL_WARNING_ONCE("pcache stubs over write limit"); STATS_INC(pcache_unprot_over_limit); stubs_restore = false; info->stubs_readonly = false; } } } } patch_branch(entrance_stub_jmp(stub), tgt, HOT_PATCHABLE); if (stubs_restore) make_unwritable((byte *)PAGE_START(entrance_stub_jmp(stub)), PAGE_SIZE); return stubs_readonly; }