aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r--arch/blackfin/kernel/kgdb.c297
-rw-r--r--arch/blackfin/kernel/process.c151
-rw-r--r--arch/blackfin/kernel/traps.c60
3 files changed, 234 insertions, 274 deletions
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
index da28f796ad78..cce79d05b90b 100644
--- a/arch/blackfin/kernel/kgdb.c
+++ b/arch/blackfin/kernel/kgdb.c
@@ -34,15 +34,6 @@ int gdb_bfin_vector = -1;
34#error change the definition of slavecpulocks 34#error change the definition of slavecpulocks
35#endif 35#endif
36 36
37#define IN_MEM(addr, size, l1_addr, l1_size) \
38({ \
39 unsigned long __addr = (unsigned long)(addr); \
40 (l1_size && __addr >= l1_addr && __addr + (size) <= l1_addr + l1_size); \
41})
42#define ASYNC_BANK_SIZE \
43 (ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
44 ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE)
45
46void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) 37void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
47{ 38{
48 gdb_regs[BFIN_R0] = regs->r0; 39 gdb_regs[BFIN_R0] = regs->r0;
@@ -463,41 +454,88 @@ static int hex(char ch)
463 454
464static int validate_memory_access_address(unsigned long addr, int size) 455static int validate_memory_access_address(unsigned long addr, int size)
465{ 456{
466 int cpu = raw_smp_processor_id(); 457 if (size < 0 || addr == 0)
467
468 if (size < 0)
469 return -EFAULT; 458 return -EFAULT;
470 if (addr >= 0x1000 && (addr + size) <= physical_mem_end) 459 return bfin_mem_access_type(addr, size);
471 return 0; 460}
472 if (addr >= SYSMMR_BASE) 461
473 return 0; 462static int bfin_probe_kernel_read(char *dst, char *src, int size)
474 if (IN_MEM(addr, size, ASYNC_BANK0_BASE, ASYNC_BANK_SIZE)) 463{
475 return 0; 464 unsigned long lsrc = (unsigned long)src;
476 if (cpu == 0) { 465 int mem_type;
477 if (IN_MEM(addr, size, L1_SCRATCH_START, L1_SCRATCH_LENGTH)) 466
478 return 0; 467 mem_type = validate_memory_access_address(lsrc, size);
479 if (IN_MEM(addr, size, L1_CODE_START, L1_CODE_LENGTH)) 468 if (mem_type < 0)
480 return 0; 469 return mem_type;
481 if (IN_MEM(addr, size, L1_DATA_A_START, L1_DATA_A_LENGTH)) 470
482 return 0; 471 if (lsrc >= SYSMMR_BASE) {
483 if (IN_MEM(addr, size, L1_DATA_B_START, L1_DATA_B_LENGTH)) 472 if (size == 2 && lsrc % 2 == 0) {
484 return 0; 473 u16 mmr = bfin_read16(src);
485#ifdef CONFIG_SMP 474 memcpy(dst, &mmr, sizeof(mmr));
486 } else if (cpu == 1) {
487 if (IN_MEM(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH))
488 return 0; 475 return 0;
489 if (IN_MEM(addr, size, COREB_L1_CODE_START, L1_CODE_LENGTH)) 476 } else if (size == 4 && lsrc % 4 == 0) {
477 u32 mmr = bfin_read32(src);
478 memcpy(dst, &mmr, sizeof(mmr));
490 return 0; 479 return 0;
491 if (IN_MEM(addr, size, COREB_L1_DATA_A_START, L1_DATA_A_LENGTH)) 480 }
481 } else {
482 switch (mem_type) {
483 case BFIN_MEM_ACCESS_CORE:
484 case BFIN_MEM_ACCESS_CORE_ONLY:
485 return probe_kernel_read(dst, src, size);
486 /* XXX: should support IDMA here with SMP */
487 case BFIN_MEM_ACCESS_DMA:
488 if (dma_memcpy(dst, src, size))
489 return 0;
490 break;
491 case BFIN_MEM_ACCESS_ITEST:
492 if (isram_memcpy(dst, src, size))
493 return 0;
494 break;
495 }
496 }
497
498 return -EFAULT;
499}
500
501static int bfin_probe_kernel_write(char *dst, char *src, int size)
502{
503 unsigned long ldst = (unsigned long)dst;
504 int mem_type;
505
506 mem_type = validate_memory_access_address(ldst, size);
507 if (mem_type < 0)
508 return mem_type;
509
510 if (ldst >= SYSMMR_BASE) {
511 if (size == 2 && ldst % 2 == 0) {
512 u16 mmr;
513 memcpy(&mmr, src, sizeof(mmr));
514 bfin_write16(dst, mmr);
492 return 0; 515 return 0;
493 if (IN_MEM(addr, size, COREB_L1_DATA_B_START, L1_DATA_B_LENGTH)) 516 } else if (size == 4 && ldst % 4 == 0) {
517 u32 mmr;
518 memcpy(&mmr, src, sizeof(mmr));
519 bfin_write32(dst, mmr);
494 return 0; 520 return 0;
495#endif 521 }
522 } else {
523 switch (mem_type) {
524 case BFIN_MEM_ACCESS_CORE:
525 case BFIN_MEM_ACCESS_CORE_ONLY:
526 return probe_kernel_write(dst, src, size);
527 /* XXX: should support IDMA here with SMP */
528 case BFIN_MEM_ACCESS_DMA:
529 if (dma_memcpy(dst, src, size))
530 return 0;
531 break;
532 case BFIN_MEM_ACCESS_ITEST:
533 if (isram_memcpy(dst, src, size))
534 return 0;
535 break;
536 }
496 } 537 }
497 538
498 if (IN_MEM(addr, size, L2_START, L2_LENGTH))
499 return 0;
500
501 return -EFAULT; 539 return -EFAULT;
502} 540}
503 541
@@ -509,14 +547,6 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
509{ 547{
510 char *tmp; 548 char *tmp;
511 int err; 549 int err;
512 unsigned char *pch;
513 unsigned short mmr16;
514 unsigned long mmr32;
515 int cpu = raw_smp_processor_id();
516
517 err = validate_memory_access_address((unsigned long)mem, count);
518 if (err)
519 return err;
520 550
521 /* 551 /*
522 * We use the upper half of buf as an intermediate buffer for the 552 * We use the upper half of buf as an intermediate buffer for the
@@ -524,44 +554,7 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
524 */ 554 */
525 tmp = buf + count; 555 tmp = buf + count;
526 556
527 if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/ 557 err = bfin_probe_kernel_read(tmp, mem, count);
528 switch (count) {
529 case 2:
530 if ((unsigned int)mem % 2 == 0) {
531 mmr16 = *(unsigned short *)mem;
532 pch = (unsigned char *)&mmr16;
533 *tmp++ = *pch++;
534 *tmp++ = *pch++;
535 tmp -= 2;
536 } else
537 err = -EFAULT;
538 break;
539 case 4:
540 if ((unsigned int)mem % 4 == 0) {
541 mmr32 = *(unsigned long *)mem;
542 pch = (unsigned char *)&mmr32;
543 *tmp++ = *pch++;
544 *tmp++ = *pch++;
545 *tmp++ = *pch++;
546 *tmp++ = *pch++;
547 tmp -= 4;
548 } else
549 err = -EFAULT;
550 break;
551 default:
552 err = -EFAULT;
553 }
554 } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
555#ifdef CONFIG_SMP
556 || (cpu == 1 && IN_MEM(mem, count, COREB_L1_CODE_START, L1_CODE_LENGTH))
557#endif
558 ) {
559 /* access L1 instruction SRAM*/
560 if (dma_memcpy(tmp, mem, count) == NULL)
561 err = -EFAULT;
562 } else
563 err = probe_kernel_read(tmp, mem, count);
564
565 if (!err) { 558 if (!err) {
566 while (count > 0) { 559 while (count > 0) {
567 buf = pack_hex_byte(buf, *tmp); 560 buf = pack_hex_byte(buf, *tmp);
@@ -582,13 +575,8 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
582 */ 575 */
583int kgdb_ebin2mem(char *buf, char *mem, int count) 576int kgdb_ebin2mem(char *buf, char *mem, int count)
584{ 577{
585 char *tmp_old; 578 char *tmp_old, *tmp_new;
586 char *tmp_new;
587 unsigned short *mmr16;
588 unsigned long *mmr32;
589 int err;
590 int size; 579 int size;
591 int cpu = raw_smp_processor_id();
592 580
593 tmp_old = tmp_new = buf; 581 tmp_old = tmp_new = buf;
594 582
@@ -601,41 +589,7 @@ int kgdb_ebin2mem(char *buf, char *mem, int count)
601 tmp_old++; 589 tmp_old++;
602 } 590 }
603 591
604 err = validate_memory_access_address((unsigned long)mem, size); 592 return bfin_probe_kernel_write(mem, buf, count);
605 if (err)
606 return err;
607
608 if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/
609 switch (size) {
610 case 2:
611 if ((unsigned int)mem % 2 == 0) {
612 mmr16 = (unsigned short *)buf;
613 *(unsigned short *)mem = *mmr16;
614 } else
615 err = -EFAULT;
616 break;
617 case 4:
618 if ((unsigned int)mem % 4 == 0) {
619 mmr32 = (unsigned long *)buf;
620 *(unsigned long *)mem = *mmr32;
621 } else
622 err = -EFAULT;
623 break;
624 default:
625 err = -EFAULT;
626 }
627 } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
628#ifdef CONFIG_SMP
629 || (cpu == 1 && IN_MEM(mem, count, COREB_L1_CODE_START, L1_CODE_LENGTH))
630#endif
631 ) {
632 /* access L1 instruction SRAM */
633 if (dma_memcpy(mem, buf, size) == NULL)
634 err = -EFAULT;
635 } else
636 err = probe_kernel_write(mem, buf, size);
637
638 return err;
639} 593}
640 594
641/* 595/*
@@ -645,16 +599,7 @@ int kgdb_ebin2mem(char *buf, char *mem, int count)
645 */ 599 */
646int kgdb_hex2mem(char *buf, char *mem, int count) 600int kgdb_hex2mem(char *buf, char *mem, int count)
647{ 601{
648 char *tmp_raw; 602 char *tmp_raw, *tmp_hex;
649 char *tmp_hex;
650 unsigned short *mmr16;
651 unsigned long *mmr32;
652 int err;
653 int cpu = raw_smp_processor_id();
654
655 err = validate_memory_access_address((unsigned long)mem, count);
656 if (err)
657 return err;
658 603
659 /* 604 /*
660 * We use the upper half of buf as an intermediate buffer for the 605 * We use the upper half of buf as an intermediate buffer for the
@@ -669,39 +614,18 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
669 *tmp_raw |= hex(*tmp_hex--) << 4; 614 *tmp_raw |= hex(*tmp_hex--) << 4;
670 } 615 }
671 616
672 if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/ 617 return bfin_probe_kernel_write(mem, tmp_raw, count);
673 switch (count) {
674 case 2:
675 if ((unsigned int)mem % 2 == 0) {
676 mmr16 = (unsigned short *)tmp_raw;
677 *(unsigned short *)mem = *mmr16;
678 } else
679 err = -EFAULT;
680 break;
681 case 4:
682 if ((unsigned int)mem % 4 == 0) {
683 mmr32 = (unsigned long *)tmp_raw;
684 *(unsigned long *)mem = *mmr32;
685 } else
686 err = -EFAULT;
687 break;
688 default:
689 err = -EFAULT;
690 }
691 } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
692#ifdef CONFIG_SMP
693 || (cpu == 1 && IN_MEM(mem, count, COREB_L1_CODE_START, L1_CODE_LENGTH))
694#endif
695 ) {
696 /* access L1 instruction SRAM */
697 if (dma_memcpy(mem, tmp_raw, count) == NULL)
698 err = -EFAULT;
699 } else
700 err = probe_kernel_write(mem, tmp_raw, count);
701
702 return err;
703} 618}
704 619
620#define IN_MEM(addr, size, l1_addr, l1_size) \
621({ \
622 unsigned long __addr = (unsigned long)(addr); \
623 (l1_size && __addr >= l1_addr && __addr + (size) <= l1_addr + l1_size); \
624})
625#define ASYNC_BANK_SIZE \
626 (ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
627 ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE)
628
705int kgdb_validate_break_address(unsigned long addr) 629int kgdb_validate_break_address(unsigned long addr)
706{ 630{
707 int cpu = raw_smp_processor_id(); 631 int cpu = raw_smp_processor_id();
@@ -724,46 +648,17 @@ int kgdb_validate_break_address(unsigned long addr)
724 648
725int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) 649int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
726{ 650{
727 int err; 651 int err = bfin_probe_kernel_read(saved_instr, (char *)addr,
728 int cpu = raw_smp_processor_id(); 652 BREAK_INSTR_SIZE);
729 653 if (err)
730 if ((cpu == 0 && IN_MEM(addr, BREAK_INSTR_SIZE, L1_CODE_START, L1_CODE_LENGTH)) 654 return err;
731#ifdef CONFIG_SMP 655 return bfin_probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr,
732 || (cpu == 1 && IN_MEM(addr, BREAK_INSTR_SIZE, COREB_L1_CODE_START, L1_CODE_LENGTH)) 656 BREAK_INSTR_SIZE);
733#endif
734 ) {
735 /* access L1 instruction SRAM */
736 if (dma_memcpy(saved_instr, (void *)addr, BREAK_INSTR_SIZE)
737 == NULL)
738 return -EFAULT;
739
740 if (dma_memcpy((void *)addr, arch_kgdb_ops.gdb_bpt_instr,
741 BREAK_INSTR_SIZE) == NULL)
742 return -EFAULT;
743
744 return 0;
745 } else {
746 err = probe_kernel_read(saved_instr, (char *)addr,
747 BREAK_INSTR_SIZE);
748 if (err)
749 return err;
750
751 return probe_kernel_write((char *)addr,
752 arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
753 }
754} 657}
755 658
756int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) 659int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)
757{ 660{
758 if (IN_MEM(addr, BREAK_INSTR_SIZE, L1_CODE_START, L1_CODE_LENGTH)) { 661 return bfin_probe_kernel_write((char *)addr, bundle, BREAK_INSTR_SIZE);
759 /* access L1 instruction SRAM */
760 if (dma_memcpy((void *)addr, bundle, BREAK_INSTR_SIZE) == NULL)
761 return -EFAULT;
762
763 return 0;
764 } else
765 return probe_kernel_write((char *)addr,
766 (char *)bundle, BREAK_INSTR_SIZE);
767} 662}
768 663
769int kgdb_arch_init(void) 664int kgdb_arch_init(void)
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 3e1d86e456f6..79cad0ac5892 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -344,6 +344,87 @@ void finish_atomic_sections (struct pt_regs *regs)
344 } 344 }
345} 345}
346 346
347static inline
348int in_mem(unsigned long addr, unsigned long size,
349 unsigned long start, unsigned long end)
350{
351 return addr >= start && addr + size <= end;
352}
353static inline
354int in_mem_const_off(unsigned long addr, unsigned long size, unsigned long off,
355 unsigned long const_addr, unsigned long const_size)
356{
357 return const_size &&
358 in_mem(addr, size, const_addr + off, const_addr + const_size);
359}
360static inline
361int in_mem_const(unsigned long addr, unsigned long size,
362 unsigned long const_addr, unsigned long const_size)
363{
364 return in_mem_const_off(addr, 0, size, const_addr, const_size);
365}
366#define IN_ASYNC(bnum, bctlnum) \
367({ \
368 (bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? -EFAULT : \
369 bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? -EFAULT : \
370 BFIN_MEM_ACCESS_CORE; \
371})
372
373int bfin_mem_access_type(unsigned long addr, unsigned long size)
374{
375 int cpu = raw_smp_processor_id();
376
377 /* Check that things do not wrap around */
378 if (addr > ULONG_MAX - size)
379 return -EFAULT;
380
381 if (in_mem(addr, size, FIXED_CODE_START, physical_mem_end))
382 return BFIN_MEM_ACCESS_CORE;
383
384 if (in_mem_const(addr, size, L1_CODE_START, L1_CODE_LENGTH))
385 return cpu == 0 ? BFIN_MEM_ACCESS_ITEST : BFIN_MEM_ACCESS_IDMA;
386 if (in_mem_const(addr, size, L1_SCRATCH_START, L1_SCRATCH_LENGTH))
387 return cpu == 0 ? BFIN_MEM_ACCESS_CORE_ONLY : -EFAULT;
388 if (in_mem_const(addr, size, L1_DATA_A_START, L1_DATA_A_LENGTH))
389 return cpu == 0 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA;
390 if (in_mem_const(addr, size, L1_DATA_B_START, L1_DATA_B_LENGTH))
391 return cpu == 0 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA;
392#ifdef COREB_L1_CODE_START
393 if (in_mem_const(addr, size, COREB_L1_CODE_START, L1_CODE_LENGTH))
394 return cpu == 1 ? BFIN_MEM_ACCESS_ITEST : BFIN_MEM_ACCESS_IDMA;
395 if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH))
396 return cpu == 1 ? BFIN_MEM_ACCESS_CORE_ONLY : -EFAULT;
397 if (in_mem_const(addr, size, COREB_L1_DATA_A_START, L1_DATA_A_LENGTH))
398 return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA;
399 if (in_mem_const(addr, size, COREB_L1_DATA_B_START, L1_DATA_B_LENGTH))
400 return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA;
401#endif
402 if (in_mem_const(addr, size, L2_START, L2_LENGTH))
403 return BFIN_MEM_ACCESS_CORE;
404
405 if (addr >= SYSMMR_BASE)
406 return BFIN_MEM_ACCESS_CORE_ONLY;
407
408 /* We can't read EBIU banks that aren't enabled or we end up hanging
409 * on the access to the async space.
410 */
411 if (in_mem_const(addr, size, ASYNC_BANK0_BASE, ASYNC_BANK0_SIZE))
412 return IN_ASYNC(0, 0);
413 if (in_mem_const(addr, size, ASYNC_BANK1_BASE, ASYNC_BANK1_SIZE))
414 return IN_ASYNC(1, 0);
415 if (in_mem_const(addr, size, ASYNC_BANK2_BASE, ASYNC_BANK2_SIZE))
416 return IN_ASYNC(2, 1);
417 if (in_mem_const(addr, size, ASYNC_BANK3_BASE, ASYNC_BANK3_SIZE))
418 return IN_ASYNC(3, 1);
419
420 if (in_mem_const(addr, size, BOOT_ROM_START, BOOT_ROM_LENGTH))
421 return BFIN_MEM_ACCESS_CORE;
422 if (in_mem_const(addr, size, L1_ROM_START, L1_ROM_LENGTH))
423 return BFIN_MEM_ACCESS_DMA;
424
425 return -EFAULT;
426}
427
347#if defined(CONFIG_ACCESS_CHECK) 428#if defined(CONFIG_ACCESS_CHECK)
348#ifdef CONFIG_ACCESS_OK_L1 429#ifdef CONFIG_ACCESS_OK_L1
349__attribute__((l1_text)) 430__attribute__((l1_text))
@@ -353,51 +434,61 @@ int _access_ok(unsigned long addr, unsigned long size)
353{ 434{
354 if (size == 0) 435 if (size == 0)
355 return 1; 436 return 1;
356 if (addr > (addr + size)) 437 /* Check that things do not wrap around */
438 if (addr > ULONG_MAX - size)
357 return 0; 439 return 0;
358 if (segment_eq(get_fs(), KERNEL_DS)) 440 if (segment_eq(get_fs(), KERNEL_DS))
359 return 1; 441 return 1;
360#ifdef CONFIG_MTD_UCLINUX 442#ifdef CONFIG_MTD_UCLINUX
361 if (addr >= memory_start && (addr + size) <= memory_end) 443 if (1)
362 return 1; 444#else
363 if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end) 445 if (0)
446#endif
447 {
448 if (in_mem(addr, size, memory_start, memory_end))
449 return 1;
450 if (in_mem(addr, size, memory_mtd_end, physical_mem_end))
451 return 1;
452# ifndef CONFIG_ROMFS_ON_MTD
453 if (0)
454# endif
455 /* For XIP, allow user space to use pointers within the ROMFS. */
456 if (in_mem(addr, size, memory_mtd_start, memory_mtd_end))
457 return 1;
458 } else {
459 if (in_mem(addr, size, memory_start, physical_mem_end))
460 return 1;
461 }
462
463 if (in_mem(addr, size, (unsigned long)__init_begin, (unsigned long)__init_end))
364 return 1; 464 return 1;
365 465
366#ifdef CONFIG_ROMFS_ON_MTD 466 if (in_mem_const(addr, size, L1_CODE_START, L1_CODE_LENGTH))
367 /* For XIP, allow user space to use pointers within the ROMFS. */
368 if (addr >= memory_mtd_start && (addr + size) <= memory_mtd_end)
369 return 1; 467 return 1;
370#endif 468 if (in_mem_const_off(addr, size, _etext_l1 - _stext_l1, L1_CODE_START, L1_CODE_LENGTH))
371#else
372 if (addr >= memory_start && (addr + size) <= physical_mem_end)
373 return 1; 469 return 1;
374#endif 470 if (in_mem_const_off(addr, size, _ebss_l1 - _sdata_l1, L1_DATA_A_START, L1_DATA_A_LENGTH))
375 if (addr >= (unsigned long)__init_begin &&
376 addr + size <= (unsigned long)__init_end)
377 return 1; 471 return 1;
378 if (addr >= get_l1_scratch_start() 472 if (in_mem_const_off(addr, size, _ebss_b_l1 - _sdata_b_l1, L1_DATA_B_START, L1_DATA_B_LENGTH))
379 && addr + size <= get_l1_scratch_start() + L1_SCRATCH_LENGTH)
380 return 1; 473 return 1;
381#if L1_CODE_LENGTH != 0 474#ifdef COREB_L1_CODE_START
382 if (addr >= get_l1_code_start() + (_etext_l1 - _stext_l1) 475 if (in_mem_const(addr, size, COREB_L1_CODE_START, L1_CODE_LENGTH))
383 && addr + size <= get_l1_code_start() + L1_CODE_LENGTH)
384 return 1; 476 return 1;
385#endif 477 if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH))
386#if L1_DATA_A_LENGTH != 0
387 if (addr >= get_l1_data_a_start() + (_ebss_l1 - _sdata_l1)
388 && addr + size <= get_l1_data_a_start() + L1_DATA_A_LENGTH)
389 return 1; 478 return 1;
390#endif 479 if (in_mem_const(addr, size, COREB_L1_DATA_A_START, L1_DATA_A_LENGTH))
391#if L1_DATA_B_LENGTH != 0
392 if (addr >= get_l1_data_b_start() + (_ebss_b_l1 - _sdata_b_l1)
393 && addr + size <= get_l1_data_b_start() + L1_DATA_B_LENGTH)
394 return 1; 480 return 1;
395#endif 481 if (in_mem_const(addr, size, COREB_L1_DATA_B_START, L1_DATA_B_LENGTH))
396#if L2_LENGTH != 0
397 if (addr >= L2_START + (_ebss_l2 - _stext_l2)
398 && addr + size <= L2_START + L2_LENGTH)
399 return 1; 482 return 1;
400#endif 483#endif
484 if (in_mem_const_off(addr, size, _ebss_l2 - _stext_l2, L2_START, L2_LENGTH))
485 return 1;
486
487 if (in_mem_const(addr, size, BOOT_ROM_START, BOOT_ROM_LENGTH))
488 return 1;
489 if (in_mem_const(addr, size, L1_ROM_START, L1_ROM_LENGTH))
490 return 1;
491
401 return 0; 492 return 0;
402} 493}
403EXPORT_SYMBOL(_access_ok); 494EXPORT_SYMBOL(_access_ok);
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index d279552fe9b0..8eeb457ce5d5 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -37,6 +37,7 @@
37#include <asm/traps.h> 37#include <asm/traps.h>
38#include <asm/cacheflush.h> 38#include <asm/cacheflush.h>
39#include <asm/cplb.h> 39#include <asm/cplb.h>
40#include <asm/dma.h>
40#include <asm/blackfin.h> 41#include <asm/blackfin.h>
41#include <asm/irq_handler.h> 42#include <asm/irq_handler.h>
42#include <linux/irq.h> 43#include <linux/irq.h>
@@ -636,57 +637,30 @@ asmlinkage void trap_c(struct pt_regs *fp)
636 */ 637 */
637static bool get_instruction(unsigned short *val, unsigned short *address) 638static bool get_instruction(unsigned short *val, unsigned short *address)
638{ 639{
639 640 unsigned long addr = (unsigned long)address;
640 unsigned long addr;
641
642 addr = (unsigned long)address;
643 641
644 /* Check for odd addresses */ 642 /* Check for odd addresses */
645 if (addr & 0x1) 643 if (addr & 0x1)
646 return false; 644 return false;
647 645
648 /* Check that things do not wrap around */ 646 /* MMR region will never have instructions */
649 if (addr > (addr + 2)) 647 if (addr >= SYSMMR_BASE)
650 return false; 648 return false;
651 649
652 /* 650 switch (bfin_mem_access_type(addr, 2)) {
653 * Since we are in exception context, we need to do a little address checking 651 case BFIN_MEM_ACCESS_CORE:
654 * We need to make sure we are only accessing valid memory, and 652 case BFIN_MEM_ACCESS_CORE_ONLY:
655 * we don't read something in the async space that can hang forever 653 *val = *address;
656 */ 654 return true;
657 if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) || 655 case BFIN_MEM_ACCESS_DMA:
658#if L2_LENGTH != 0 656 dma_memcpy(val, address, 2);
659 (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) || 657 return true;
660#endif 658 case BFIN_MEM_ACCESS_ITEST:
661 (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) || 659 isram_memcpy(val, address, 2);
662#if L1_DATA_A_LENGTH != 0 660 return true;
663 (addr >= L1_DATA_A_START && (addr + 2) <= (L1_DATA_A_START + L1_DATA_A_LENGTH)) || 661 default: /* invalid access */
664#endif 662 return false;
665#if L1_DATA_B_LENGTH != 0
666 (addr >= L1_DATA_B_START && (addr + 2) <= (L1_DATA_B_START + L1_DATA_B_LENGTH)) ||
667#endif
668 (addr >= L1_SCRATCH_START && (addr + 2) <= (L1_SCRATCH_START + L1_SCRATCH_LENGTH)) ||
669 (!(bfin_read_EBIU_AMBCTL0() & B0RDYEN) &&
670 addr >= ASYNC_BANK0_BASE && (addr + 2) <= (ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE)) ||
671 (!(bfin_read_EBIU_AMBCTL0() & B1RDYEN) &&
672 addr >= ASYNC_BANK1_BASE && (addr + 2) <= (ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE)) ||
673 (!(bfin_read_EBIU_AMBCTL1() & B2RDYEN) &&
674 addr >= ASYNC_BANK2_BASE && (addr + 2) <= (ASYNC_BANK2_BASE + ASYNC_BANK1_SIZE)) ||
675 (!(bfin_read_EBIU_AMBCTL1() & B3RDYEN) &&
676 addr >= ASYNC_BANK3_BASE && (addr + 2) <= (ASYNC_BANK3_BASE + ASYNC_BANK1_SIZE))) {
677 *val = *address;
678 return true;
679 } 663 }
680
681#if L1_CODE_LENGTH != 0
682 if (addr >= L1_CODE_START && (addr + 2) <= (L1_CODE_START + L1_CODE_LENGTH)) {
683 isram_memcpy(val, address, 2);
684 return true;
685 }
686#endif
687
688
689 return false;
690} 664}
691 665
692/* 666/*