1/* 2 * Blackfin architecture-dependent process handling 3 * 4 * Copyright 2004-2009 Analog Devices Inc. 5 * 6 * Licensed under the GPL-2 or later 7 */ 8 9#include <linux/module.h> 10#include <linux/unistd.h> 11#include <linux/user.h> 12#include <linux/uaccess.h> 13#include <linux/slab.h> 14#include <linux/sched.h> 15#include <linux/tick.h> 16#include <linux/fs.h> 17#include <linux/err.h> 18 19#include <asm/blackfin.h> 20#include <asm/fixed_code.h> 21#include <asm/mem_map.h> 22#include <asm/irq.h> 23 24asmlinkage void ret_from_fork(void); 25 26/* Points to the SDRAM backup memory for the stack that is currently in 27 * L1 scratchpad memory. 28 */ 29void *current_l1_stack_save; 30 31/* The number of tasks currently using a L1 stack area. The SRAM is 32 * allocated/deallocated whenever this changes from/to zero. 33 */ 34int nr_l1stack_tasks; 35 36/* Start and length of the area in L1 scratchpad memory which we've allocated 37 * for process stacks. 38 */ 39void *l1_stack_base; 40unsigned long l1_stack_len; 41 42/* 43 * Powermanagement idle function, if any.. 44 */ 45void (*pm_idle)(void) = NULL; 46EXPORT_SYMBOL(pm_idle); 47 48void (*pm_power_off)(void) = NULL; 49EXPORT_SYMBOL(pm_power_off); 50 51/* 52 * The idle loop on BFIN 53 */ 54#ifdef CONFIG_IDLE_L1 55static void default_idle(void)__attribute__((l1_text)); 56void cpu_idle(void)__attribute__((l1_text)); 57#endif 58 59/* 60 * This is our default idle handler. We need to disable 61 * interrupts here to ensure we don't miss a wakeup call. 62 */ 63static void default_idle(void) 64{ 65#ifdef CONFIG_IPIPE 66 ipipe_suspend_domain(); 67#endif 68 hard_local_irq_disable(); 69 if (!need_resched()) 70 idle_with_irq_disabled(); 71 72 hard_local_irq_enable(); 73} 74 75/* 76 * The idle thread. We try to conserve power, while trying to keep 77 * overall latency low. The architecture specific idle is passed 78 * a value to indicate the level of "idleness" of the system. 79 */ 80void cpu_idle(void) 81{ 82 /* endless idle loop with no priority at all */ 83 while (1) { 84 void (*idle)(void) = pm_idle; 85 86#ifdef CONFIG_HOTPLUG_CPU 87 if (cpu_is_offline(smp_processor_id())) 88 cpu_die(); 89#endif 90 if (!idle) 91 idle = default_idle; 92 tick_nohz_idle_enter(); 93 rcu_idle_enter(); 94 while (!need_resched()) 95 idle(); 96 rcu_idle_exit(); 97 tick_nohz_idle_exit(); 98 schedule_preempt_disabled(); 99 } 100} 101 102/* 103 * This gets run with P1 containing the 104 * function to call, and R1 containing 105 * the "args". Note P0 is clobbered on the way here. 106 */ 107void kernel_thread_helper(void); 108__asm__(".section .text\n" 109 ".align 4\n" 110 "_kernel_thread_helper:\n\t" 111 "\tsp += -12;\n\t" 112 "\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous"); 113 114/* 115 * Create a kernel thread. 116 */ 117pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags) 118{ 119 struct pt_regs regs; 120 121 memset(®s, 0, sizeof(regs)); 122 123 regs.r1 = (unsigned long)arg; 124 regs.p1 = (unsigned long)fn; 125 regs.pc = (unsigned long)kernel_thread_helper; 126 regs.orig_p0 = -1; 127 /* Set bit 2 to tell ret_from_fork we should be returning to kernel 128 mode. */ 129 regs.ipend = 0x8002; 130 __asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):); 131 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, 132 NULL); 133} 134EXPORT_SYMBOL(kernel_thread); 135 136/* 137 * Do necessary setup to start up a newly executed thread. 138 * 139 * pass the data segment into user programs if it exists, 140 * it can't hurt anything as far as I can tell 141 */ 142void start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) 143{ 144 regs->pc = new_ip; 145 if (current->mm) 146 regs->p5 = current->mm->start_data; 147#ifndef CONFIG_SMP 148 task_thread_info(current)->l1_task_info.stack_start = 149 (void *)current->mm->context.stack_start; 150 task_thread_info(current)->l1_task_info.lowest_sp = (void *)new_sp; 151 memcpy(L1_SCRATCH_TASK_INFO, &task_thread_info(current)->l1_task_info, 152 sizeof(*L1_SCRATCH_TASK_INFO)); 153#endif 154 wrusp(new_sp); 155} 156EXPORT_SYMBOL_GPL(start_thread); 157 158void flush_thread(void) 159{ 160} 161 162asmlinkage int bfin_vfork(struct pt_regs *regs) 163{ 164 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, 165 NULL); 166} 167 168asmlinkage int bfin_clone(struct pt_regs *regs) 169{ 170 unsigned long clone_flags; 171 unsigned long newsp; 172 173#ifdef __ARCH_SYNC_CORE_DCACHE 174 if (current->rt.nr_cpus_allowed == num_possible_cpus()) 175 set_cpus_allowed_ptr(current, cpumask_of(smp_processor_id())); 176#endif 177 178 /* syscall2 puts clone_flags in r0 and usp in r1 */ 179 clone_flags = regs->r0; 180 newsp = regs->r1; 181 if (!newsp) 182 newsp = rdusp(); 183 else 184 newsp -= 12; 185 return do_fork(clone_flags, newsp, regs, 0, NULL, NULL); 186} 187 188int 189copy_thread(unsigned long clone_flags, 190 unsigned long usp, unsigned long topstk, 191 struct task_struct *p, struct pt_regs *regs) 192{ 193 struct pt_regs *childregs; 194 195 childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; 196 *childregs = *regs; 197 childregs->r0 = 0; 198 199 p->thread.usp = usp; 200 p->thread.ksp = (unsigned long)childregs; 201 p->thread.pc = (unsigned long)ret_from_fork; 202 203 return 0; 204} 205 206/* 207 * sys_execve() executes a new program. 208 */ 209asmlinkage int sys_execve(const char __user *name, 210 const char __user *const __user *argv, 211 const char __user *const __user *envp) 212{ 213 int error; 214 char *filename; 215 struct pt_regs *regs = (struct pt_regs *)((&name) + 6); 216 217 filename = getname(name); 218 error = PTR_ERR(filename); 219 if (IS_ERR(filename)) 220 return error; 221 error = do_execve(filename, argv, envp, regs); 222 putname(filename); 223 return error; 224} 225 226unsigned long get_wchan(struct task_struct *p) 227{ 228 unsigned long fp, pc; 229 unsigned long stack_page; 230 int count = 0; 231 if (!p || p == current || p->state == TASK_RUNNING) 232 return 0; 233 234 stack_page = (unsigned long)p; 235 fp = p->thread.usp; 236 do { 237 if (fp < stack_page + sizeof(struct thread_info) || 238 fp >= 8184 + stack_page) 239 return 0; 240 pc = ((unsigned long *)fp)[1]; 241 if (!in_sched_functions(pc)) 242 return pc; 243 fp = *(unsigned long *)fp; 244 } 245 while (count++ < 16); 246 return 0; 247} 248 249void finish_atomic_sections (struct pt_regs *regs) 250{ 251 int __user *up0 = (int __user *)regs->p0; 252 253 switch (regs->pc) { 254 default: 255 /* not in middle of an atomic step, so resume like normal */ 256 return; 257 258 case ATOMIC_XCHG32 + 2: 259 put_user(regs->r1, up0); 260 break; 261 262 case ATOMIC_CAS32 + 2: 263 case ATOMIC_CAS32 + 4: 264 if (regs->r0 == regs->r1) 265 case ATOMIC_CAS32 + 6: 266 put_user(regs->r2, up0); 267 break; 268 269 case ATOMIC_ADD32 + 2: 270 regs->r0 = regs->r1 + regs->r0; 271 /* fall through */ 272 case ATOMIC_ADD32 + 4: 273 put_user(regs->r0, up0); 274 break; 275 276 case ATOMIC_SUB32 + 2: 277 regs->r0 = regs->r1 - regs->r0; 278 /* fall through */ 279 case ATOMIC_SUB32 + 4: 280 put_user(regs->r0, up0); 281 break; 282 283 case ATOMIC_IOR32 + 2: 284 regs->r0 = regs->r1 | regs->r0; 285 /* fall through */ 286 case ATOMIC_IOR32 + 4: 287 put_user(regs->r0, up0); 288 break; 289 290 case ATOMIC_AND32 + 2: 291 regs->r0 = regs->r1 & regs->r0; 292 /* fall through */ 293 case ATOMIC_AND32 + 4: 294 put_user(regs->r0, up0); 295 break; 296 297 case ATOMIC_XOR32 + 2: 298 regs->r0 = regs->r1 ^ regs->r0; 299 /* fall through */ 300 case ATOMIC_XOR32 + 4: 301 put_user(regs->r0, up0); 302 break; 303 } 304 305 /* 306 * We've finished the atomic section, and the only thing left for 307 * userspace is to do a RTS, so we might as well handle that too 308 * since we need to update the PC anyways. 309 */ 310 regs->pc = regs->rets; 311} 312 313static inline 314int in_mem(unsigned long addr, unsigned long size, 315 unsigned long start, unsigned long end) 316{ 317 return addr >= start && addr + size <= end; 318} 319static inline 320int in_mem_const_off(unsigned long addr, unsigned long size, unsigned long off, 321 unsigned long const_addr, unsigned long const_size) 322{ 323 return const_size && 324 in_mem(addr, size, const_addr + off, const_addr + const_size); 325} 326static inline 327int in_mem_const(unsigned long addr, unsigned long size, 328 unsigned long const_addr, unsigned long const_size) 329{ 330 return in_mem_const_off(addr, size, 0, const_addr, const_size); 331} 332#define ASYNC_ENABLED(bnum, bctlnum) \ 333({ \ 334 (bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? 0 : \ 335 bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? 0 : \ 336 1; \ 337}) 338/* 339 * We can't read EBIU banks that aren't enabled or we end up hanging 340 * on the access to the async space. Make sure we validate accesses 341 * that cross async banks too. 342 * 0 - found, but unusable 343 * 1 - found & usable 344 * 2 - not found 345 */ 346static 347int in_async(unsigned long addr, unsigned long size) 348{ 349 if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE) { 350 if (!ASYNC_ENABLED(0, 0)) 351 return 0; 352 if (addr + size <= ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE) 353 return 1; 354 size -= ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE - addr; 355 addr = ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE; 356 } 357 if (addr >= ASYNC_BANK1_BASE && addr < ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE) { 358 if (!ASYNC_ENABLED(1, 0)) 359 return 0; 360 if (addr + size <= ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE) 361 return 1; 362 size -= ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE - addr; 363 addr = ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE; 364 } 365 if (addr >= ASYNC_BANK2_BASE && addr < ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE) { 366 if (!ASYNC_ENABLED(2, 1)) 367 return 0; 368 if (addr + size <= ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE) 369 return 1; 370 size -= ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE - addr; 371 addr = ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE; 372 } 373 if (addr >= ASYNC_BANK3_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { 374 if (ASYNC_ENABLED(3, 1)) 375 return 0; 376 if (addr + size <= ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) 377 return 1; 378 return 0; 379 } 380 381 /* not within async bounds */ 382 return 2; 383} 384 385int bfin_mem_access_type(unsigned long addr, unsigned long size) 386{ 387 int cpu = raw_smp_processor_id(); 388 389 /* Check that things do not wrap around */ 390 if (addr > ULONG_MAX - size) 391 return -EFAULT; 392 393 if (in_mem(addr, size, FIXED_CODE_START, physical_mem_end)) 394 return BFIN_MEM_ACCESS_CORE; 395 396 if (in_mem_const(addr, size, L1_CODE_START, L1_CODE_LENGTH)) 397 return cpu == 0 ? BFIN_MEM_ACCESS_ITEST : BFIN_MEM_ACCESS_IDMA; 398 if (in_mem_const(addr, size, L1_SCRATCH_START, L1_SCRATCH_LENGTH)) 399 return cpu == 0 ? BFIN_MEM_ACCESS_CORE_ONLY : -EFAULT; 400 if (in_mem_const(addr, size, L1_DATA_A_START, L1_DATA_A_LENGTH)) 401 return cpu == 0 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; 402 if (in_mem_const(addr, size, L1_DATA_B_START, L1_DATA_B_LENGTH)) 403 return cpu == 0 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; 404#ifdef COREB_L1_CODE_START 405 if (in_mem_const(addr, size, COREB_L1_CODE_START, COREB_L1_CODE_LENGTH)) 406 return cpu == 1 ? BFIN_MEM_ACCESS_ITEST : BFIN_MEM_ACCESS_IDMA; 407 if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH)) 408 return cpu == 1 ? BFIN_MEM_ACCESS_CORE_ONLY : -EFAULT; 409 if (in_mem_const(addr, size, COREB_L1_DATA_A_START, COREB_L1_DATA_A_LENGTH)) 410 return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; 411 if (in_mem_const(addr, size, COREB_L1_DATA_B_START, COREB_L1_DATA_B_LENGTH)) 412 return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; 413#endif 414 if (in_mem_const(addr, size, L2_START, L2_LENGTH)) 415 return BFIN_MEM_ACCESS_CORE; 416 417 if (addr >= SYSMMR_BASE) 418 return BFIN_MEM_ACCESS_CORE_ONLY; 419 420 switch (in_async(addr, size)) { 421 case 0: return -EFAULT; 422 case 1: return BFIN_MEM_ACCESS_CORE; 423 case 2: /* fall through */; 424 } 425 426 if (in_mem_const(addr, size, BOOT_ROM_START, BOOT_ROM_LENGTH)) 427 return BFIN_MEM_ACCESS_CORE; 428 if (in_mem_const(addr, size, L1_ROM_START, L1_ROM_LENGTH)) 429 return BFIN_MEM_ACCESS_DMA; 430 431 return -EFAULT; 432} 433 434#if defined(CONFIG_ACCESS_CHECK) 435#ifdef CONFIG_ACCESS_OK_L1 436__attribute__((l1_text)) 437#endif 438/* Return 1 if access to memory range is OK, 0 otherwise */ 439int _access_ok(unsigned long addr, unsigned long size) 440{ 441 int aret; 442 443 if (size == 0) 444 return 1; 445 /* Check that things do not wrap around */ 446 if (addr > ULONG_MAX - size) 447 return 0; 448 if (segment_eq(get_fs(), KERNEL_DS)) 449 return 1; 450#ifdef CONFIG_MTD_UCLINUX 451 if (1) 452#else 453 if (0) 454#endif 455 { 456 if (in_mem(addr, size, memory_start, memory_end)) 457 return 1; 458 if (in_mem(addr, size, memory_mtd_end, physical_mem_end)) 459 return 1; 460# ifndef CONFIG_ROMFS_ON_MTD 461 if (0) 462# endif 463 /* For XIP, allow user space to use pointers within the ROMFS. */ 464 if (in_mem(addr, size, memory_mtd_start, memory_mtd_end)) 465 return 1; 466 } else { 467 if (in_mem(addr, size, memory_start, physical_mem_end)) 468 return 1; 469 } 470 471 if (in_mem(addr, size, (unsigned long)__init_begin, (unsigned long)__init_end)) 472 return 1; 473 474 if (in_mem_const(addr, size, L1_CODE_START, L1_CODE_LENGTH)) 475 return 1; 476 if (in_mem_const_off(addr, size, _etext_l1 - _stext_l1, L1_CODE_START, L1_CODE_LENGTH)) 477 return 1; 478 if (in_mem_const_off(addr, size, _ebss_l1 - _sdata_l1, L1_DATA_A_START, L1_DATA_A_LENGTH)) 479 return 1; 480 if (in_mem_const_off(addr, size, _ebss_b_l1 - _sdata_b_l1, L1_DATA_B_START, L1_DATA_B_LENGTH)) 481 return 1; 482#ifdef COREB_L1_CODE_START 483 if (in_mem_const(addr, size, COREB_L1_CODE_START, COREB_L1_CODE_LENGTH)) 484 return 1; 485 if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH)) 486 return 1; 487 if (in_mem_const(addr, size, COREB_L1_DATA_A_START, COREB_L1_DATA_A_LENGTH)) 488 return 1; 489 if (in_mem_const(addr, size, COREB_L1_DATA_B_START, COREB_L1_DATA_B_LENGTH)) 490 return 1; 491#endif 492 493#ifndef CONFIG_EXCEPTION_L1_SCRATCH 494 if (in_mem_const(addr, size, (unsigned long)l1_stack_base, l1_stack_len)) 495 return 1; 496#endif 497 498 aret = in_async(addr, size); 499 if (aret < 2) 500 return aret; 501 502 if (in_mem_const_off(addr, size, _ebss_l2 - _stext_l2, L2_START, L2_LENGTH)) 503 return 1; 504 505 if (in_mem_const(addr, size, BOOT_ROM_START, BOOT_ROM_LENGTH)) 506 return 1; 507 if (in_mem_const(addr, size, L1_ROM_START, L1_ROM_LENGTH)) 508 return 1; 509 510 return 0; 511} 512EXPORT_SYMBOL(_access_ok); 513#endif /* CONFIG_ACCESS_CHECK */ 514