250
239
lwi r30, r1, PTO+PT_R30; \
251
240
lwi r31, r1, PTO+PT_R31; /* Restore cur task reg */
243
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \
244
/* See if already in kernel mode.*/ \
246
andi r1, r1, MSR_UMS; \
248
/* Kernel-mode state save. */ \
249
/* Reload kernel stack-ptr. */ \
250
lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
251
/* FIXME: I can add these two lines to one */ \
252
/* tophys(r1,r1); */ \
253
/* addik r1, r1, -STATE_SAVE_SIZE; */ \
254
addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \
257
swi r1, r1, PTO+PT_MODE; \
258
1: /* User-mode state save. */ \
259
lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\
261
lwi r1, r1, TS_THREAD_INFO; /* get the thread info */ \
262
/* MS these three instructions can be added to one */ \
263
/* addik r1, r1, THREAD_SIZE; */ \
264
/* tophys(r1,r1); */ \
265
/* addik r1, r1, -STATE_SAVE_SIZE; */ \
266
addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \
268
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
269
swi r11, r1, PTO+PT_R1; /* Store user SP. */ \
270
swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ \
271
/* MS: I am clearing UMS even in case when I come from kernel space */ \
273
2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
352
370
add r12, r12, r12; /* convert num -> ptr */
353
371
add r12, r12, r12;
355
374
/* Trac syscalls and stored them to r0_ram */
356
375
lwi r3, r12, 0x400 + r0_ram
358
377
swi r3, r12, 0x400 + r0_ram
360
380
# Find and jump into the syscall handler.
361
381
lwi r12, r12, sys_call_table
362
382
/* where the trap should return need -8 to adjust for rtsd r15, 8 */
363
la r15, r0, ret_from_trap-8
383
addi r15, r0, ret_from_trap-8
366
386
/* The syscall number is invalid, return an error. */
388
rtsd r15, 8; /* looks like a normal subroutine return */
368
389
addi r3, r0, -ENOSYS;
369
rtsd r15,8; /* looks like a normal subroutine return */
373
391
/* Entry point used to return from a syscall/trap */
374
392
/* We re-enable BIP bit before state restore */
375
393
C_ENTRY(ret_from_trap):
376
set_bip; /* Ints masked for state restore*/
377
lwi r11, r1, PTO+PT_MODE;
394
swi r3, r1, PTO + PT_R3
395
swi r4, r1, PTO + PT_R4
397
lwi r11, r1, PTO + PT_MODE;
378
398
/* See if returning to kernel mode, if so, skip resched &c. */
381
400
/* We're returning to user mode, so check for various conditions that
382
401
* trigger rescheduling. */
383
# FIXME: Restructure all these flag checks.
384
add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
385
lwi r11, r11, TS_THREAD_INFO; /* get thread info */
402
/* FIXME: Restructure all these flag checks. */
403
lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
386
404
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
387
405
andi r11, r11, _TIF_WORK_SYSCALL_MASK
390
swi r3, r1, PTO + PT_R3
391
swi r4, r1, PTO + PT_R4
392
408
brlid r15, do_syscall_trace_leave
393
409
addik r5, r1, PTO + PT_R0
394
lwi r3, r1, PTO + PT_R3
395
lwi r4, r1, PTO + PT_R4
398
411
/* We're returning to user mode, so check for various conditions that
399
412
* trigger rescheduling. */
400
/* Get current task ptr into r11 */
401
add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
402
lwi r11, r11, TS_THREAD_INFO; /* get thread info */
413
/* get thread info from current task */
414
lwi r11, CURRENT_TASK, TS_THREAD_INFO;
403
415
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
404
416
andi r11, r11, _TIF_NEED_RESCHED;
407
swi r3, r1, PTO + PT_R3; /* store syscall result */
408
swi r4, r1, PTO + PT_R4;
409
419
bralid r15, schedule; /* Call scheduler */
410
420
nop; /* delay slot */
411
lwi r3, r1, PTO + PT_R3; /* restore syscall result */
412
lwi r4, r1, PTO + PT_R4;
414
422
/* Maybe handle a signal */
415
5: add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
416
lwi r11, r11, TS_THREAD_INFO; /* get thread info */
423
5: /* get thread info from current task*/
424
lwi r11, CURRENT_TASK, TS_THREAD_INFO;
417
425
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
418
426
andi r11, r11, _TIF_SIGPENDING;
419
427
beqi r11, 1f; /* Signals to handle, handle them */
421
swi r3, r1, PTO + PT_R3; /* store syscall result */
422
swi r4, r1, PTO + PT_R4;
423
la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
424
add r6, r0, r0; /* Arg 2: sigset_t *oldset */
429
addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
425
430
addi r7, r0, 1; /* Arg 3: int in_syscall */
426
431
bralid r15, do_signal; /* Handle any signals */
428
lwi r3, r1, PTO + PT_R3; /* restore syscall result */
429
lwi r4, r1, PTO + PT_R4;
432
add r6, r0, r0; /* Arg 2: sigset_t *oldset */
431
434
/* Finally, return to user state. */
432
1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */
433
add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
434
swi r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
435
1: set_bip; /* Ints masked for state restore */
436
swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
473
475
bralid r15, schedule_tail; /* ...which is schedule_tail's arg */
474
476
add r3, r5, r0; /* switch_thread returns the prev task */
475
477
/* ( in the delay slot ) */
478
brid ret_from_trap; /* Do normal trap return */
476
479
add r3, r0, r0; /* Child's fork call should return 0. */
477
brid ret_from_trap; /* Do normal trap return */
480
481
C_ENTRY(sys_vfork):
481
482
brid microblaze_vfork /* Do real work (tail-call) */
484
485
C_ENTRY(sys_clone):
485
486
bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */
486
lwi r6, r1, PTO+PT_R1; /* If so, use paret's stack ptr */
487
1: la r7, r1, PTO; /* Arg 2: parent context */
487
lwi r6, r1, PTO + PT_R1; /* If so, use paret's stack ptr */
488
1: addik r7, r1, PTO; /* Arg 2: parent context */
488
489
add r8, r0, r0; /* Arg 3: (unused) */
489
490
add r9, r0, r0; /* Arg 4: (unused) */
491
brid do_fork /* Do real work (tail-call) */
490
492
add r10, r0, r0; /* Arg 5: (unused) */
491
brid do_fork /* Do real work (tail-call) */
494
494
C_ENTRY(sys_execve):
495
la r8, r1, PTO; /* add user context as 4th arg */
496
495
brid microblaze_execve; /* Do real work (tail-call).*/
499
C_ENTRY(sys_rt_sigsuspend_wrapper):
500
swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
501
swi r4, r1, PTO+PT_R4;
502
la r7, r1, PTO; /* add user context as 3rd arg */
503
brlid r15, sys_rt_sigsuspend; /* Do real work.*/
505
lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
506
lwi r4, r1, PTO+PT_R4;
507
bri ret_from_trap /* fall through will not work here due to align */
496
addik r8, r1, PTO; /* add user context as 4th arg */
510
498
C_ENTRY(sys_rt_sigreturn_wrapper):
511
swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
512
swi r4, r1, PTO+PT_R4;
513
la r5, r1, PTO; /* add user context as 1st arg */
514
brlid r15, sys_rt_sigreturn /* Do real work */
516
lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
517
lwi r4, r1, PTO+PT_R4;
518
bri ret_from_trap /* fall through will not work here due to align */
499
brid sys_rt_sigreturn /* Do real work */
500
addik r5, r1, PTO; /* add user context as 1st arg */
522
503
* HW EXCEPTION rutine start
526
swi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* Save r11 */ \
527
set_bip; /*equalize initial state for all possible entries*/\
531
/* See if already in kernel mode.*/ \
532
lwi r11, r0, TOPHYS(PER_CPU(KM)); \
533
beqi r11, 1f; /* Jump ahead if coming from user */\
534
/* Kernel-mode state save. */ \
535
/* Reload kernel stack-ptr. */ \
536
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
538
swi r11, r1, (PT_R1-PT_SIZE); /* Save original SP. */ \
539
lwi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* restore r11 */\
540
addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */\
541
/* store return registers separately because \
542
* this macros is use for others exceptions */ \
543
swi r3, r1, PTO + PT_R3; \
544
swi r4, r1, PTO + PT_R4; \
546
/* PC, before IRQ/trap - this is one instruction above */ \
547
swi r17, r1, PTO+PT_PC; \
549
addi r11, r0, 1; /* Was in kernel-mode. */ \
550
swi r11, r1, PTO+PT_MODE; \
552
nop; /* Fill delay slot */ \
553
1: /* User-mode state save. */ \
554
lwi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* restore r11 */\
555
lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\
557
lwi r1, r1, TS_THREAD_INFO; /* get the thread info */ \
558
addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */\
561
addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */\
562
/* store return registers separately because this macros \
563
* is use for others exceptions */ \
564
swi r3, r1, PTO + PT_R3; \
565
swi r4, r1, PTO + PT_R4; \
567
/* PC, before IRQ/trap - this is one instruction above FIXME*/ \
568
swi r17, r1, PTO+PT_PC; \
570
swi r0, r1, PTO+PT_MODE; /* Was in user-mode. */ \
571
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
572
swi r11, r1, PTO+PT_R1; /* Store user SP. */ \
574
swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode.*/\
575
2: lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\
576
/* Save away the syscall number. */ \
577
swi r0, r1, PTO+PT_R0; \
580
505
C_ENTRY(full_exception_trap):
581
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
582
506
/* adjust exception address for privileged instruction
583
507
* for finding where is it */
584
508
addik r17, r17, -4
585
509
SAVE_STATE /* Save registers */
510
/* PC, before IRQ/trap - this is one instruction above */
511
swi r17, r1, PTO+PT_PC;
586
513
/* FIXME this can be store directly in PT_ESR reg.
587
514
* I tested it but there is a fault */
588
515
/* where the trap should return need -8 to adjust for rtsd r15, 8 */
589
la r15, r0, ret_from_exc - 8
590
la r5, r1, PTO /* parameter struct pt_regs * regs */
516
addik r15, r0, ret_from_exc - 8
593
518
mfs r7, rfsr; /* save FSR */
595
519
mts rfsr, r0; /* Clear sticky fsr */
597
la r12, r0, full_exception
520
rted r0, full_exception
521
addik r5, r1, PTO /* parameter struct pt_regs * regs */
603
524
* Unaligned data trap.
644
573
/* data and intruction trap - which is choose is resolved int fault.c */
645
574
C_ENTRY(page_fault_data_trap):
646
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
647
575
SAVE_STATE /* Save registers.*/
576
/* PC, before IRQ/trap - this is one instruction above */
577
swi r17, r1, PTO+PT_PC;
648
579
/* where the trap should return need -8 to adjust for rtsd r15, 8 */
649
la r15, r0, ret_from_exc-8
650
la r5, r1, PTO /* parameter struct pt_regs * regs */
580
addik r15, r0, ret_from_exc-8
651
581
mfs r6, rear /* parameter unsigned long address */
653
582
mfs r7, resr /* parameter unsigned long error_code */
655
la r12, r0, do_page_fault
657
rtbd r12, 0; /* interrupts enabled */
583
rted r0, do_page_fault
584
addik r5, r1, PTO /* parameter struct pt_regs * regs */
660
586
C_ENTRY(page_fault_instr_trap):
661
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
662
587
SAVE_STATE /* Save registers.*/
588
/* PC, before IRQ/trap - this is one instruction above */
589
swi r17, r1, PTO+PT_PC;
663
591
/* where the trap should return need -8 to adjust for rtsd r15, 8 */
664
la r15, r0, ret_from_exc-8
665
la r5, r1, PTO /* parameter struct pt_regs * regs */
592
addik r15, r0, ret_from_exc-8
666
593
mfs r6, rear /* parameter unsigned long address */
668
594
ori r7, r0, 0 /* parameter unsigned long error_code */
669
la r12, r0, do_page_fault
671
rtbd r12, 0; /* interrupts enabled */
595
rted r0, do_page_fault
596
addik r5, r1, PTO /* parameter struct pt_regs * regs */
674
598
/* Entry point used to return from an exception. */
675
599
C_ENTRY(ret_from_exc):
676
set_bip; /* Ints masked for state restore*/
677
lwi r11, r1, PTO+PT_MODE;
600
lwi r11, r1, PTO + PT_MODE;
678
601
bnei r11, 2f; /* See if returning to kernel mode, */
679
602
/* ... if so, skip resched &c. */
681
604
/* We're returning to user mode, so check for various conditions that
682
605
trigger rescheduling. */
683
/* Get current task ptr into r11 */
684
add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
685
lwi r11, r11, TS_THREAD_INFO; /* get thread info */
606
lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
686
607
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
687
608
andi r11, r11, _TIF_NEED_RESCHED;
708
628
* traps), but signal handlers may want to examine or change the
709
629
* complete register state. Here we save anything not saved by
710
630
* the normal entry sequence, so that it may be safely restored
711
* (in a possibly modified form) after do_signal returns.
712
* store return registers separately because this macros is use
713
* for others exceptions */
714
swi r3, r1, PTO + PT_R3;
715
swi r4, r1, PTO + PT_R4;
716
la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
717
add r6, r0, r0; /* Arg 2: sigset_t *oldset */
631
* (in a possibly modified form) after do_signal returns. */
632
addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
718
633
addi r7, r0, 0; /* Arg 3: int in_syscall */
719
634
bralid r15, do_signal; /* Handle any signals */
721
lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
722
lwi r4, r1, PTO+PT_R4;
635
add r6, r0, r0; /* Arg 2: sigset_t *oldset */
724
637
/* Finally, return to user state. */
725
1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */
726
add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
727
swi r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
638
1: set_bip; /* Ints masked for state restore */
639
swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
731
lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
732
lwi r4, r1, PTO+PT_R4;
734
644
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */
736
646
lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */
738
648
/* Return to kernel state. */
649
2: set_bip; /* Ints masked for state restore */
741
lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
742
lwi r4, r1, PTO+PT_R4;
744
653
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */
763
672
/* MS: we are in physical address */
764
673
/* Save registers, switch to proper stack, convert SP to virtual.*/
765
674
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP))
766
swi r11, r0, TOPHYS(PER_CPU(R11_SAVE));
767
675
/* MS: See if already in kernel mode. */
768
lwi r11, r0, TOPHYS(PER_CPU(KM));
769
beqi r11, 1f; /* MS: Jump ahead if coming from user */
771
681
/* Kernel-mode state save. */
773
tophys(r1,r11); /* MS: I have in r1 physical address where stack is */
774
/* MS: Save original SP - position PT_R1 to next stack frame 4 *1 - 152*/
775
swi r11, r1, (PT_R1 - PT_SIZE);
776
/* MS: restore r11 because of saving in SAVE_REGS */
777
lwi r11, r0, TOPHYS(PER_CPU(R11_SAVE));
682
lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP))
683
tophys(r1,r1); /* MS: I have in r1 physical address where stack is */
778
684
/* save registers */
779
685
/* MS: Make room on the stack -> activation record */
780
686
addik r1, r1, -STATE_SAVE_SIZE;
781
/* MS: store return registers separately because
782
* this macros is use for others exceptions */
783
swi r3, r1, PTO + PT_R3;
784
swi r4, r1, PTO + PT_R4;
787
addi r11, r0, 1; /* MS: Was in kernel-mode. */
788
swi r11, r1, PTO + PT_MODE; /* MS: and save it */
790
nop; /* MS: Fill delay slot */
689
swi r1, r1, PTO + PT_MODE; /* 0 - user mode, 1 - kernel mode */
793
691
/* User-mode state save. */
794
/* MS: restore r11 -> FIXME move before SAVE_REG */
795
lwi r11, r0, TOPHYS(PER_CPU(R11_SAVE));
796
692
/* MS: get the saved current */
797
693
lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
853
738
/* Disable interrupts, we are now committed to the state restore */
855
swi r0, r0, PER_CPU(KM); /* MS: Now officially in user state. */
856
add r11, r0, CURRENT_TASK;
857
swi r11, r0, PER_CPU(CURRENT_SAVE);
740
swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE);
860
lwi r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */
861
lwi r4, r1, PTO + PT_R4;
863
744
addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */
864
745
lwi r1, r1, PT_R1 - PT_SIZE;
866
747
/* MS: Return to kernel state. */
867
2: VM_OFF /* MS: turn off MMU */
749
#ifdef CONFIG_PREEMPT
750
lwi r11, CURRENT_TASK, TS_THREAD_INFO;
751
/* MS: get preempt_count from thread info */
752
lwi r5, r11, TI_PREEMPT_COUNT;
755
lwi r5, r11, TI_FLAGS; /* get flags in thread info */
756
andi r5, r5, _TIF_NEED_RESCHED;
757
beqi r5, restore /* if zero jump over */
760
/* interrupts are off that's why I am calling preempt_chedule_irq */
761
bralid r15, preempt_schedule_irq
763
lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
764
lwi r5, r11, TI_FLAGS; /* get flags in thread info */
765
andi r5, r5, _TIF_NEED_RESCHED;
766
bnei r5, preempt /* if non zero jump to resched */
769
VM_OFF /* MS: turn off MMU */
869
lwi r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */
870
lwi r4, r1, PTO + PT_R4;
872
772
addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */
881
* We enter dbtrap in "BIP" (breakpoint) mode.
882
* So we exit the breakpoint mode with an 'rtbd' and proceed with the
884
* however, wait to save state first
780
* Debug trap for KGDB. Enter to _debug_exception by brki r16, 0x18
781
* and call handling function with saved pt_regs
886
783
C_ENTRY(_debug_exception):
887
784
/* BIP bit is set on entry, no interrupts can occur */
888
785
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP))
890
swi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* Save r11 */
891
set_bip; /*equalize initial state for all possible entries*/
894
lwi r11, r0, TOPHYS(PER_CPU(KM));/* See if already in kernel mode.*/
895
beqi r11, 1f; /* Jump ahead if coming from user */
896
/* Kernel-mode state save. */
897
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
899
swi r11, r1, (PT_R1-PT_SIZE); /* Save original SP. */
900
lwi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* restore r11 */
791
/* MS: Kernel-mode state save - kgdb */
792
lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
902
addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
903
swi r3, r1, PTO + PT_R3;
904
swi r4, r1, PTO + PT_R4;
794
/* BIP bit is set on entry, no interrupts can occur */
795
addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
907
addi r11, r0, 1; /* Was in kernel-mode. */
908
swi r11, r1, PTO + PT_MODE;
910
nop; /* Fill delay slot */
911
1: /* User-mode state save. */
912
lwi r11, r0, TOPHYS(r0_ram + PTO + PT_R11); /* restore r11 */
913
lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
797
/* save all regs to pt_reg structure */
798
swi r0, r1, PTO+PT_R0; /* R0 must be saved too */
799
swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */
800
swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */
801
/* save special purpose registers to pt_regs */
803
swi r11, r1, PTO+PT_EAR;
805
swi r11, r1, PTO+PT_ESR;
807
swi r11, r1, PTO+PT_FSR;
809
/* stack pointer is in physical address at it is decrease
810
* by STATE_SAVE_SIZE but we need to get correct R1 value */
811
addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + STATE_SAVE_SIZE;
812
swi r11, r1, PTO+PT_R1
813
/* MS: r31 - current pointer isn't changed */
816
addi r5, r1, PTO /* pass pt_reg address as the first arg */
817
la r15, r0, dbtrap_call; /* return address */
818
rtbd r0, microblaze_kgdb_break
821
/* MS: Place handler for brki from kernel space if KGDB is OFF.
822
* It is very unlikely that another brki instruction is called. */
825
/* MS: User-mode state save - gdb */
826
1: lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
915
828
lwi r1, r1, TS_THREAD_INFO; /* get the thread info */
916
829
addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */
919
832
addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
920
swi r3, r1, PTO + PT_R3;
921
swi r4, r1, PTO + PT_R4;
924
swi r0, r1, PTO+PT_MODE; /* Was in user-mode. */
834
swi r16, r1, PTO+PT_PC; /* Save LP */
835
swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
925
836
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
926
837
swi r11, r1, PTO+PT_R1; /* Store user SP. */
928
swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode. */
929
2: lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
930
/* Save away the syscall number. */
931
swi r0, r1, PTO+PT_R0;
838
lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
934
addi r5, r0, SIGTRAP /* send the trap signal */
935
add r6, r0, CURRENT_TASK; /* Get current task ptr into r11 */
936
addk r7, r0, r0 /* 3rd param zero */
939
la r11, r0, send_sig;
940
la r15, r0, dbtrap_call;
941
dbtrap_call: rtbd r11, 0;
842
addik r15, r0, dbtrap_call;
843
dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
844
rtbd r0, sw_exception
944
set_bip; /* Ints masked for state restore*/
945
lwi r11, r1, PTO+PT_MODE;
847
/* MS: The first instruction for the second part of the gdb/kgdb */
848
set_bip; /* Ints masked for state restore */
849
lwi r11, r1, PTO + PT_MODE;
851
/* MS: Return to user space - gdb */
948
852
/* Get current task ptr into r11 */
949
add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
950
lwi r11, r11, TS_THREAD_INFO; /* get thread info */
853
lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
951
854
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
952
855
andi r11, r11, _TIF_NEED_RESCHED;
955
/* Call the scheduler before returning from a syscall/trap. */
858
/* Call the scheduler before returning from a syscall/trap. */
957
859
bralid r15, schedule; /* Call scheduler */
958
860
nop; /* delay slot */
959
/* XXX Is PT_DTRACE handling needed here? */
960
/* XXX m68knommu also checks TASK_STATE & TASK_COUNTER here. */
962
862
/* Maybe handle a signal */
963
5: add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
964
lwi r11, r11, TS_THREAD_INFO; /* get thread info */
863
5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
965
864
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
966
865
andi r11, r11, _TIF_SIGPENDING;
967
866
beqi r11, 1f; /* Signals to handle, handle them */
969
/* Handle a signal return; Pending signals should be in r18. */
970
/* Not all registers are saved by the normal trap/interrupt entry
971
points (for instance, call-saved registers (because the normal
972
C-compiler calling sequence in the kernel makes sure they're
973
preserved), and call-clobbered registers in the case of
974
traps), but signal handlers may want to examine or change the
975
complete register state. Here we save anything not saved by
976
the normal entry sequence, so that it may be safely restored
977
(in a possibly modified form) after do_signal returns. */
979
la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
980
add r6, r0, r0; /* Arg 2: sigset_t *oldset */
868
addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
981
869
addi r7, r0, 0; /* Arg 3: int in_syscall */
982
870
bralid r15, do_signal; /* Handle any signals */
871
add r6, r0, r0; /* Arg 2: sigset_t *oldset */
986
873
/* Finally, return to user state. */
987
1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */
988
add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
989
swi r11, r0, PER_CPU(CURRENT_SAVE); /* save current */
874
1: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
993
lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
994
lwi r4, r1, PTO+PT_R4;
877
/* MS: Restore all regs */
996
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */
999
lwi r1, r1, PT_R1 - PT_SIZE;
1000
/* Restore user stack pointer. */
1003
/* Return to kernel state. */
879
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */
880
lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
881
DBTRAP_return_user: /* MS: Make global symbol for debugging */
882
rtbd r16, 0; /* MS: Instructions to return from a debug trap */
885
/* MS: Return to kernel state - kgdb */
1006
lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
1007
lwi r4, r1, PTO+PT_R4;
888
/* MS: Restore all regs */
1009
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */
890
lwi r14, r1, PTO+PT_R14;
891
lwi r16, r1, PTO+PT_PC;
892
addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
1013
DBTRAP_return: /* Make global symbol for debugging */
1014
rtbd r14, 0; /* Instructions to return from an IRQ */
894
DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
895
rtbd r16, 0; /* MS: Instructions to return from a debug trap */
1019
899
ENTRY(_switch_to)
1020
900
/* prepare return value */
901
addk r3, r0, CURRENT_TASK
1023
903
/* save registers in cpu_context */
1024
904
/* use r11 and r12, volatile registers, as temp register */