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/smp_lock.h> 11#include <linux/unistd.h> 12#include <linux/user.h> 13#include <linux/uaccess.h> 14#include <linux/slab.h> 15#include <linux/sched.h> 16#include <linux/tick.h> 17#include <linux/fs.h> 18#include <linux/err.h> 19 20#include <asm/blackfin.h> 21#include <asm/fixed_code.h> 22#include <asm/mem_map.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 local_irq_disable_hw(); 69 if (!need_resched()) 70 idle_with_irq_disabled(); 71 72 local_irq_enable_hw(); 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_stop_sched_tick(1); 93 while (!need_resched()) 94 idle(); 95 tick_nohz_restart_sched_tick(); 96 preempt_enable_no_resched(); 97 schedule(); 98 preempt_disable(); 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 set_fs(USER_DS); 145 regs->pc = new_ip; 146 if (current->mm) 147 regs->p5 = current->mm->start_data; 148#ifndef CONFIG_SMP 149 task_thread_info(current)->l1_task_info.stack_start = 150 (void *)current->mm->context.stack_start; 151 task_thread_info(current)->l1_task_info.lowest_sp = (void *)new_sp; 152 memcpy(L1_SCRATCH_TASK_INFO, &task_thread_info(current)->l1_task_info, 153 sizeof(*L1_SCRATCH_TASK_INFO)); 154#endif 155 wrusp(new_sp); 156} 157EXPORT_SYMBOL_GPL(start_thread); 158 159void flush_thread(void) 160{ 161} 162 163asmlinkage int bfin_vfork(struct pt_regs *regs) 164{ 165 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, 166 NULL); 167} 168 169asmlinkage int bfin_clone(struct pt_regs *regs) 170{ 171 unsigned long clone_flags; 172 unsigned long newsp; 173 174#ifdef __ARCH_SYNC_CORE_DCACHE 175 if (current->rt.nr_cpus_allowed == num_possible_cpus()) { 176 current->cpus_allowed = cpumask_of_cpu(smp_processor_id()); 177 current->rt.nr_cpus_allowed = 1; 178 } 179#endif 180 181 /* syscall2 puts clone_flags in r0 and usp in r1 */ 182 clone_flags = regs->r0; 183 newsp = regs->r1; 184 if (!newsp) 185 newsp = rdusp(); 186 else 187 newsp -= 12; 188 return do_fork(clone_flags, newsp, regs, 0, NULL, NULL); 189} 190 191int 192copy_thread(unsigned long clone_flags, 193 unsigned long usp, unsigned long topstk, 194 struct task_struct *p, struct pt_regs *regs) 195{ 196 struct pt_regs *childregs; 197 198 childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; 199 *childregs = *regs; 200 childregs->r0 = 0; 201 202 p->thread.usp = usp; 203 p->thread.ksp = (unsigned long)childregs; 204 p->thread.pc = (unsigned long)ret_from_fork; 205 206 return 0; 207} 208 209/* 210 * sys_execve() executes a new program. 211 */ 212asmlinkage int sys_execve(const char __user *name, 213 const char __user *const __user *argv, 214 const char __user *const __user *envp) 215{ 216 int error; 217 char *filename; 218 struct pt_regs *regs = (struct pt_regs *)((&name) + 6); 219 220 filename = getname(name); 221 error = PTR_ERR(filename); 222 if (IS_ERR(filename)) 223 return error; 224 error = do_execve(filename, argv, envp, regs); 225 putname(filename); 226 return error; 227} 228 229unsigned long get_wchan(struct task_struct *p) 230{ 231 unsigned long fp, pc; 232 unsigned long stack_page; 233 int count = 0; 234 if (!p || p == current || p->state == TASK_RUNNING) 235 return 0; 236 237 stack_page = (unsigned long)p; 238 fp = p->thread.usp; 239 do { 240 if (fp < stack_page + sizeof(struct thread_info) || 241 fp >= 8184 + stack_page) 242 return 0; 243 pc = ((unsigned long *)fp)[1]; 244 if (!in_sched_functions(pc)) 245 return pc; 246 fp = *(unsigned long *)fp; 247 } 248 while (count++ < 16); 249 return 0; 250} 251 252void finish_atomic_sections (struct pt_regs *regs) 253{ 254 int __user *up0 = (int __user *)regs->p0; 255 256 switch (regs->pc) { 257 default: 258 /* not in middle of an atomic step, so resume like normal */ 259 return; 260 261 case ATOMIC_XCHG32 + 2: 262 put_user(regs->r1, up0); 263 break; 264 265 case ATOMIC_CAS32 + 2: 266 case ATOMIC_CAS32 + 4: 267 if (regs->r0 == regs->r1) 268 case ATOMIC_CAS32 + 6: 269 put_user(regs->r2, up0); 270 break; 271 272 case ATOMIC_ADD32 + 2: 273 regs->r0 = regs->r1 + regs->r0; 274 /* fall through */ 275 case ATOMIC_ADD32 + 4: 276 put_user(regs->r0, up0); 277 break; 278 279 case ATOMIC_SUB32 + 2: 280 regs->r0 = regs->r1 - regs->r0; 281 /* fall through */ 282 case ATOMIC_SUB32 + 4: 283 put_user(regs->r0, up0); 284 break; 285 286 case ATOMIC_IOR32 + 2: 287 regs->r0 = regs->r1 | regs->r0; 288 /* fall through */ 289 case ATOMIC_IOR32 + 4: 290 put_user(regs->r0, up0); 291 break; 292 293 case ATOMIC_AND32 + 2: 294 regs->r0 = regs->r1 & regs->r0; 295 /* fall through */ 296 case ATOMIC_AND32 + 4: 297 put_user(regs->r0, up0); 298 break; 299 300 case ATOMIC_XOR32 + 2: 301 regs->r0 = regs->r1 ^ regs->r0; 302 /* fall through */ 303 case ATOMIC_XOR32 + 4: 304 put_user(regs->r0, up0); 305 break; 306 } 307 308 /* 309 * We've finished the atomic section, and the only thing left for 310 * userspace is to do a RTS, so we might as well handle that too 311 * since we need to update the PC anyways. 312 */ 313 regs->pc = regs->rets; 314} 315 316static inline 317int in_mem(unsigned long addr, unsigned long size, 318 unsigned long start, unsigned long end) 319{ 320 return addr >= start && addr + size <= end; 321} 322static inline 323int in_mem_const_off(unsigned long addr, unsigned long size, unsigned long off, 324 unsigned long const_addr, unsigned long const_size) 325{ 326 return const_size && 327 in_mem(addr, size, const_addr + off, const_addr + const_size); 328} 329static inline 330int in_mem_const(unsigned long addr, unsigned long size, 331 unsigned long const_addr, unsigned long const_size) 332{ 333 return in_mem_const_off(addr, size, 0, const_addr, const_size); 334} 335#define ASYNC_ENABLED(bnum, bctlnum) \ 336({ \ 337 (bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? 0 : \ 338 bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? 0 : \ 339 1; \ 340}) 341/* 342 * We can't read EBIU banks that aren't enabled or we end up hanging 343 * on the access to the async space. Make sure we validate accesses 344 * that cross async banks too. 345 * 0 - found, but unusable 346 * 1 - found & usable 347 * 2 - not found 348 */ 349static 350int in_async(unsigned long addr, unsigned long size) 351{ 352 if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE) { 353 if (!ASYNC_ENABLED(0, 0)) 354 return 0; 355 if (addr + size <= ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE) 356 return 1; 357 size -= ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE - addr; 358 addr = ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE; 359 } 360 if (addr >= ASYNC_BANK1_BASE && addr < ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE) { 361 if (!ASYNC_ENABLED(1, 0)) 362 return 0; 363 if (addr + size <= ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE) 364 return 1; 365 size -= ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE - addr; 366 addr = ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE; 367 } 368 if (addr >= ASYNC_BANK2_BASE && addr < ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE) { 369 if (!ASYNC_ENABLED(2, 1)) 370 return 0; 371 if (addr + size <= ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE) 372 return 1; 373 size -= ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE - addr; 374 addr = ASYNC_BANK2_BASE + ASYNC_BANK2_SIZE; 375 } 376 if (addr >= ASYNC_BANK3_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { 377 if (ASYNC_ENABLED(3, 1)) 378 return 0; 379 if (addr + size <= ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) 380 return 1; 381 return 0; 382 } 383 384 /* not within async bounds */ 385 return 2; 386} 387 388int bfin_mem_access_type(unsigned long addr, unsigned long size) 389{ 390 int cpu = raw_smp_processor_id(); 391 392 /* Check that things do not wrap around */ 393 if (addr > ULONG_MAX - size) 394 return -EFAULT; 395 396 if (in_mem(addr, size, FIXED_CODE_START, physical_mem_end)) 397 return BFIN_MEM_ACCESS_CORE; 398 399 if (in_mem_const(addr, size, L1_CODE_START, L1_CODE_LENGTH)) 400 return cpu == 0 ? BFIN_MEM_ACCESS_ITEST : BFIN_MEM_ACCESS_IDMA; 401 if (in_mem_const(addr, size, L1_SCRATCH_START, L1_SCRATCH_LENGTH)) 402 return cpu == 0 ? BFIN_MEM_ACCESS_CORE_ONLY : -EFAULT; 403 if (in_mem_const(addr, size, L1_DATA_A_START, L1_DATA_A_LENGTH)) 404 return cpu == 0 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; 405 if (in_mem_const(addr, size, L1_DATA_B_START, L1_DATA_B_LENGTH)) 406 return cpu == 0 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; 407#ifdef COREB_L1_CODE_START 408 if (in_mem_const(addr, size, COREB_L1_CODE_START, COREB_L1_CODE_LENGTH)) 409 return cpu == 1 ? BFIN_MEM_ACCESS_ITEST : BFIN_MEM_ACCESS_IDMA; 410 if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH)) 411 return cpu == 1 ? BFIN_MEM_ACCESS_CORE_ONLY : -EFAULT; 412 if (in_mem_const(addr, size, COREB_L1_DATA_A_START, COREB_L1_DATA_A_LENGTH)) 413 return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; 414 if (in_mem_const(addr, size, COREB_L1_DATA_B_START, COREB_L1_DATA_B_LENGTH)) 415 return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; 416#endif 417 if (in_mem_const(addr, size, L2_START, L2_LENGTH)) 418 return BFIN_MEM_ACCESS_CORE; 419 420 if (addr >= SYSMMR_BASE) 421 return BFIN_MEM_ACCESS_CORE_ONLY; 422 423 switch (in_async(addr, size)) { 424 case 0: return -EFAULT; 425 case 1: return BFIN_MEM_ACCESS_CORE; 426 case 2: /* fall through */; 427 } 428 429 if (in_mem_const(addr, size, BOOT_ROM_START, BOOT_ROM_LENGTH)) 430 return BFIN_MEM_ACCESS_CORE; 431 if (in_mem_const(addr, size, L1_ROM_START, L1_ROM_LENGTH)) 432 return BFIN_MEM_ACCESS_DMA; 433 434 return -EFAULT; 435} 436 437#if defined(CONFIG_ACCESS_CHECK) 438#ifdef CONFIG_ACCESS_OK_L1 439__attribute__((l1_text)) 440#endif 441/* Return 1 if access to memory range is OK, 0 otherwise */ 442int _access_ok(unsigned long addr, unsigned long size) 443{ 444 int aret; 445 446 if (size == 0) 447 return 1; 448 /* Check that things do not wrap around */ 449 if (addr > ULONG_MAX - size) 450 return 0; 451 if (segment_eq(get_fs(), KERNEL_DS)) 452 return 1; 453#ifdef CONFIG_MTD_UCLINUX 454 if (1) 455#else 456 if (0) 457#endif 458 { 459 if (in_mem(addr, size, memory_start, memory_end)) 460 return 1; 461 if (in_mem(addr, size, memory_mtd_end, physical_mem_end)) 462 return 1; 463# ifndef CONFIG_ROMFS_ON_MTD 464 if (0) 465# endif 466 /* For XIP, allow user space to use pointers within the ROMFS. */ 467 if (in_mem(addr, size, memory_mtd_start, memory_mtd_end)) 468 return 1; 469 } else { 470 if (in_mem(addr, size, memory_start, physical_mem_end)) 471 return 1; 472 } 473 474 if (in_mem(addr, size, (unsigned long)__init_begin, (unsigned long)__init_end)) 475 return 1; 476 477 if (in_mem_const(addr, size, L1_CODE_START, L1_CODE_LENGTH)) 478 return 1; 479 if (in_mem_const_off(addr, size, _etext_l1 - _stext_l1, L1_CODE_START, L1_CODE_LENGTH)) 480 return 1; 481 if (in_mem_const_off(addr, size, _ebss_l1 - _sdata_l1, L1_DATA_A_START, L1_DATA_A_LENGTH)) 482 return 1; 483 if (in_mem_const_off(addr, size, _ebss_b_l1 - _sdata_b_l1, L1_DATA_B_START, L1_DATA_B_LENGTH)) 484 return 1; 485#ifdef COREB_L1_CODE_START 486 if (in_mem_const(addr, size, COREB_L1_CODE_START, COREB_L1_CODE_LENGTH)) 487 return 1; 488 if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH)) 489 return 1; 490 if (in_mem_const(addr, size, COREB_L1_DATA_A_START, COREB_L1_DATA_A_LENGTH)) 491 return 1; 492 if (in_mem_const(addr, size, COREB_L1_DATA_B_START, COREB_L1_DATA_B_LENGTH)) 493 return 1; 494#endif 495 496 aret = in_async(addr, size); 497 if (aret < 2) 498 return aret; 499 500 if (in_mem_const_off(addr, size, _ebss_l2 - _stext_l2, L2_START, L2_LENGTH)) 501 return 1; 502 503 if (in_mem_const(addr, size, BOOT_ROM_START, BOOT_ROM_LENGTH)) 504 return 1; 505 if (in_mem_const(addr, size, L1_ROM_START, L1_ROM_LENGTH)) 506 return 1; 507 508 return 0; 509} 510EXPORT_SYMBOL(_access_ok); 511#endif /* CONFIG_ACCESS_CHECK */ 512