Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[linux-2.6.git] / arch / mn10300 / kernel / entry.S
1 ###############################################################################
2 #
3 # MN10300 Exception and interrupt entry points
4 #
5 # Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
6 # Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
7 # Modified by David Howells (dhowells@redhat.com)
8 #
9 # This program is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU General Public Licence
11 # as published by the Free Software Foundation; either version
12 # 2 of the Licence, or (at your option) any later version.
13 #
14 ###############################################################################
15 #include <linux/sys.h>
16 #include <linux/linkage.h>
17 #include <asm/smp.h>
18 #include <asm/system.h>
19 #include <asm/irqflags.h>
20 #include <asm/thread_info.h>
21 #include <asm/intctl-regs.h>
22 #include <asm/busctl-regs.h>
23 #include <asm/timer-regs.h>
24 #include <unit/leds.h>
25 #include <asm/page.h>
26 #include <asm/pgtable.h>
27 #include <asm/errno.h>
28 #include <asm/asm-offsets.h>
29 #include <asm/frame.inc>
30
31 #ifdef CONFIG_PREEMPT
32 #define preempt_stop            __cli
33 #else
34 #define preempt_stop
35 #define resume_kernel           restore_all
36 #endif
37
38         .macro __cli
39         and     ~EPSW_IM,epsw
40         or      EPSW_IE|MN10300_CLI_LEVEL,epsw
41         nop
42         nop
43         nop
44         .endm
45         .macro __sti
46         or      EPSW_IE|EPSW_IM_7,epsw
47         .endm
48
49
50         .am33_2
51
52 ###############################################################################
53 #
54 # the return path for a forked child
55 # - on entry, D0 holds the address of the previous task to run
56 #
57 ###############################################################################
58 ENTRY(ret_from_fork)
59         call    schedule_tail[],0
60         GET_THREAD_INFO a2
61
62         # return 0 to indicate child process
63         clr     d0
64         mov     d0,(REG_D0,fp)
65         jmp     syscall_exit
66
67 ###############################################################################
68 #
69 # system call handler
70 #
71 ###############################################################################
72 ENTRY(system_call)
73         add     -4,sp
74         SAVE_ALL
75         mov     d0,(REG_ORIG_D0,fp)
76         GET_THREAD_INFO a2
77         cmp     nr_syscalls,d0
78         bcc     syscall_badsys
79         btst    _TIF_SYSCALL_TRACE,(TI_flags,a2)
80         bne     syscall_entry_trace
81 syscall_call:
82         add     d0,d0,a1
83         add     a1,a1
84         mov     (REG_A0,fp),d0
85         mov     (sys_call_table,a1),a0
86         calls   (a0)
87         mov     d0,(REG_D0,fp)
88 syscall_exit:
89         # make sure we don't miss an interrupt setting need_resched or
90         # sigpending between sampling and the rti
91         __cli
92         mov     (TI_flags,a2),d2
93         btst    _TIF_ALLWORK_MASK,d2
94         bne     syscall_exit_work
95 restore_all:
96         RESTORE_ALL
97
98 ###############################################################################
99 #
100 # perform work that needs to be done immediately before resumption and syscall
101 # tracing
102 #
103 ###############################################################################
104         ALIGN
105 syscall_exit_work:
106         btst    _TIF_SYSCALL_TRACE,d2
107         beq     work_pending
108         __sti                           # could let syscall_trace_exit() call
109                                         # schedule() instead
110         mov     fp,d0
111         call    syscall_trace_exit[],0  # do_syscall_trace(regs)
112         jmp     resume_userspace
113
114         ALIGN
115 work_pending:
116         btst    _TIF_NEED_RESCHED,d2
117         beq     work_notifysig
118
119 work_resched:
120         call    schedule[],0
121
122         # make sure we don't miss an interrupt setting need_resched or
123         # sigpending between sampling and the rti
124         __cli
125
126         # is there any work to be done other than syscall tracing?
127         mov     (TI_flags,a2),d2
128         btst    _TIF_WORK_MASK,d2
129         beq     restore_all
130         btst    _TIF_NEED_RESCHED,d2
131         bne     work_resched
132
133         # deal with pending signals and notify-resume requests
134 work_notifysig:
135         mov     fp,d0
136         mov     d2,d1
137         call    do_notify_resume[],0
138         jmp     resume_userspace
139
140         # perform syscall entry tracing
141 syscall_entry_trace:
142         mov     -ENOSYS,d0
143         mov     d0,(REG_D0,fp)
144         mov     fp,d0
145         call    syscall_trace_entry[],0 # returns the syscall number to actually use
146         mov     (REG_D1,fp),d1
147         cmp     nr_syscalls,d0
148         bcs     syscall_call
149         jmp     syscall_exit
150
151 syscall_badsys:
152         mov     -ENOSYS,d0
153         mov     d0,(REG_D0,fp)
154         jmp     resume_userspace
155
156         # userspace resumption stub bypassing syscall exit tracing
157         .globl  ret_from_exception, ret_from_intr
158         ALIGN
159 ret_from_exception:
160         preempt_stop
161 ret_from_intr:
162         GET_THREAD_INFO a2
163         mov     (REG_EPSW,fp),d0        # need to deliver signals before
164                                         # returning to userspace
165         and     EPSW_nSL,d0
166         beq     resume_kernel           # returning to supervisor mode
167
168 ENTRY(resume_userspace)
169         # make sure we don't miss an interrupt setting need_resched or
170         # sigpending between sampling and the rti
171         __cli
172
173         # is there any work to be done on int/exception return?
174         mov     (TI_flags,a2),d2
175         btst    _TIF_WORK_MASK,d2
176         bne     work_pending
177         jmp     restore_all
178
179 #ifdef CONFIG_PREEMPT
180 ENTRY(resume_kernel)
181         __cli
182         mov     (TI_preempt_count,a2),d0        # non-zero preempt_count ?
183         cmp     0,d0
184         bne     restore_all
185
186 need_resched:
187         btst    _TIF_NEED_RESCHED,(TI_flags,a2)
188         beq     restore_all
189         mov     (REG_EPSW,fp),d0
190         and     EPSW_IM,d0
191         cmp     EPSW_IM_7,d0            # interrupts off (exception path) ?
192         bne     restore_all
193         call    preempt_schedule_irq[],0
194         jmp     need_resched
195 #endif
196
197
198 ###############################################################################
199 #
200 # IRQ handler entry point
201 # - intended to be entered at multiple priorities
202 #
203 ###############################################################################
204 ENTRY(irq_handler)
205         add     -4,sp
206         SAVE_ALL
207
208         # it's not a syscall
209         mov     0xffffffff,d0
210         mov     d0,(REG_ORIG_D0,fp)
211
212         mov     fp,d0
213         call    do_IRQ[],0                      # do_IRQ(regs)
214
215         jmp     ret_from_intr
216
217 ###############################################################################
218 #
219 # Monitor Signal handler entry point
220 #
221 ###############################################################################
222 ENTRY(monitor_signal)
223         movbu   (0xae000001),d1
224         cmp     1,d1
225         beq     monsignal
226         ret     [],0
227
228 monsignal:
229         or      EPSW_NMID,epsw
230         mov     d0,a0
231         mov     a0,sp
232         mov     (REG_EPSW,fp),d1
233         and     ~EPSW_nSL,d1
234         mov     d1,(REG_EPSW,fp)
235         movm    (sp),[d2,d3,a2,a3,exreg0,exreg1,exother]
236         mov     (sp),a1
237         mov     a1,usp
238         movm    (sp),[other]
239         add     4,sp
240 here:   jmp     0x8e000008-here+0x8e000008
241
242 ###############################################################################
243 #
244 # Double Fault handler entry point
245 # - note that there will not be a stack, D0/A0 will hold EPSW/PC as were
246 #
247 ###############################################################################
248         .section .bss
249         .balign THREAD_SIZE
250         .space  THREAD_SIZE
251 __df_stack:
252         .previous
253
254 ENTRY(double_fault)
255         mov     a0,(__df_stack-4)       # PC as was
256         mov     d0,(__df_stack-8)       # EPSW as was
257         mn10300_set_dbfleds             # display 'db-f' on the LEDs
258         mov     0xaa55aa55,d0
259         mov     d0,(__df_stack-12)      # no ORIG_D0
260         mov     sp,a0                   # save corrupted SP
261         mov     __df_stack-12,sp        # emergency supervisor stack
262         SAVE_ALL
263         mov     a0,(REG_A0,fp)          # save corrupted SP as A0 (which got
264                                         # clobbered by the CPU)
265         mov     fp,d0
266         calls   do_double_fault
267 double_fault_loop:
268         bra     double_fault_loop
269
270 ###############################################################################
271 #
272 # Bus Error handler entry point
273 # - handle external (async) bus errors separately
274 #
275 ###############################################################################
276 ENTRY(raw_bus_error)
277         add     -4,sp
278         mov     d0,(sp)
279         mov     (BCBERR),d0             # what
280         btst    BCBERR_BEMR_DMA,d0      # see if it was an external bus error
281         beq     __common_exception_aux  # it wasn't
282
283         SAVE_ALL
284         mov     (BCBEAR),d1             # destination of erroneous access
285
286         mov     (REG_ORIG_D0,fp),d2
287         mov     d2,(REG_D0,fp)
288         mov     -1,d2
289         mov     d2,(REG_ORIG_D0,fp)
290
291         add     -4,sp
292         mov     fp,(12,sp)              # frame pointer
293         call    io_bus_error[],0
294         jmp     restore_all
295
296 ###############################################################################
297 #
298 # Miscellaneous exception entry points
299 #
300 ###############################################################################
301 ENTRY(nmi_handler)
302         add     -4,sp
303         mov     d0,(sp)
304         mov     (TBR),d0
305         bra     __common_exception_nonmi
306
307 ENTRY(__common_exception)
308         add     -4,sp
309         mov     d0,(sp)
310
311 __common_exception_aux:
312         mov     (TBR),d0
313         and     ~EPSW_NMID,epsw         # turn NMIs back on if not NMI
314         or      EPSW_IE,epsw
315
316 __common_exception_nonmi:
317         and     0x0000FFFF,d0           # turn the exception code into a vector
318                                         # table index
319
320         btst    0x00000007,d0
321         bne     1f
322         cmp     0x00000400,d0
323         bge     1f
324
325         SAVE_ALL                        # build the stack frame
326
327         mov     (REG_D0,fp),a2          # get the exception number
328         mov     (REG_ORIG_D0,fp),d0
329         mov     d0,(REG_D0,fp)
330         mov     -1,d0
331         mov     d0,(REG_ORIG_D0,fp)
332
333 #ifdef CONFIG_GDBSTUB
334         btst    0x01,(gdbstub_busy)
335         beq     2f
336         and     ~EPSW_IE,epsw
337         mov     fp,d0
338         mov     a2,d1
339         call    gdbstub_exception[],0   # gdbstub itself caused an exception
340         bra     restore_all
341 2:
342 #endif
343
344         mov     fp,d0                   # arg 0: stacked register file
345         mov     a2,d1                   # arg 1: exception number
346         lsr     1,a2
347
348         mov     (exception_table,a2),a2
349         calls   (a2)
350         jmp     ret_from_exception
351
352 1:      pi                              # BUG() equivalent
353
354 ###############################################################################
355 #
356 # Exception handler functions table
357 #
358 ###############################################################################
359         .data
360 ENTRY(exception_table)
361         .rept   0x400>>1
362          .long  uninitialised_exception
363         .endr
364         .previous
365
366 ###############################################################################
367 #
368 # Change an entry in the exception table
369 # - D0 exception code, D1 handler
370 #
371 ###############################################################################
372 ENTRY(set_excp_vector)
373         lsr     1,d0
374         add     exception_table,d0
375         mov     d1,(d0)
376         mov     4,d1
377 #if defined(CONFIG_MN10300_CACHE_WBACK)
378         jmp     mn10300_dcache_flush_inv_range2
379 #else
380         ret     [],0
381 #endif
382
383 ###############################################################################
384 #
385 # System call table
386 #
387 ###############################################################################
388         .data
389 ENTRY(sys_call_table)
390         .long sys_restart_syscall       /* 0 */
391         .long sys_exit
392         .long sys_fork
393         .long sys_read
394         .long sys_write
395         .long sys_open          /* 5 */
396         .long sys_close
397         .long sys_waitpid
398         .long sys_creat
399         .long sys_link
400         .long sys_unlink        /* 10 */
401         .long sys_execve
402         .long sys_chdir
403         .long sys_time
404         .long sys_mknod
405         .long sys_chmod         /* 15 */
406         .long sys_lchown16
407         .long sys_ni_syscall    /* old break syscall holder */
408         .long sys_stat
409         .long sys_lseek
410         .long sys_getpid        /* 20 */
411         .long sys_mount
412         .long sys_oldumount
413         .long sys_setuid16
414         .long sys_getuid16
415         .long sys_stime         /* 25 */
416         .long sys_ptrace
417         .long sys_alarm
418         .long sys_fstat
419         .long sys_pause
420         .long sys_utime         /* 30 */
421         .long sys_ni_syscall    /* old stty syscall holder */
422         .long sys_ni_syscall    /* old gtty syscall holder */
423         .long sys_access
424         .long sys_nice
425         .long sys_ni_syscall    /* 35 - old ftime syscall holder */
426         .long sys_sync
427         .long sys_kill
428         .long sys_rename
429         .long sys_mkdir
430         .long sys_rmdir         /* 40 */
431         .long sys_dup
432         .long sys_pipe
433         .long sys_times
434         .long sys_ni_syscall    /* old prof syscall holder */
435         .long sys_brk           /* 45 */
436         .long sys_setgid16
437         .long sys_getgid16
438         .long sys_signal
439         .long sys_geteuid16
440         .long sys_getegid16     /* 50 */
441         .long sys_acct
442         .long sys_umount        /* recycled never used phys() */
443         .long sys_ni_syscall    /* old lock syscall holder */
444         .long sys_ioctl
445         .long sys_fcntl         /* 55 */
446         .long sys_ni_syscall    /* old mpx syscall holder */
447         .long sys_setpgid
448         .long sys_ni_syscall    /* old ulimit syscall holder */
449         .long sys_ni_syscall    /* old sys_olduname */
450         .long sys_umask         /* 60 */
451         .long sys_chroot
452         .long sys_ustat
453         .long sys_dup2
454         .long sys_getppid
455         .long sys_getpgrp       /* 65 */
456         .long sys_setsid
457         .long sys_sigaction
458         .long sys_sgetmask
459         .long sys_ssetmask
460         .long sys_setreuid16    /* 70 */
461         .long sys_setregid16
462         .long sys_sigsuspend
463         .long sys_sigpending
464         .long sys_sethostname
465         .long sys_setrlimit     /* 75 */
466         .long sys_old_getrlimit
467         .long sys_getrusage
468         .long sys_gettimeofday
469         .long sys_settimeofday
470         .long sys_getgroups16   /* 80 */
471         .long sys_setgroups16
472         .long sys_old_select
473         .long sys_symlink
474         .long sys_lstat
475         .long sys_readlink      /* 85 */
476         .long sys_uselib
477         .long sys_swapon
478         .long sys_reboot
479         .long sys_old_readdir
480         .long old_mmap          /* 90 */
481         .long sys_munmap
482         .long sys_truncate
483         .long sys_ftruncate
484         .long sys_fchmod
485         .long sys_fchown16      /* 95 */
486         .long sys_getpriority
487         .long sys_setpriority
488         .long sys_ni_syscall    /* old profil syscall holder */
489         .long sys_statfs
490         .long sys_fstatfs       /* 100 */
491         .long sys_ni_syscall    /* ioperm */
492         .long sys_socketcall
493         .long sys_syslog
494         .long sys_setitimer
495         .long sys_getitimer     /* 105 */
496         .long sys_newstat
497         .long sys_newlstat
498         .long sys_newfstat
499         .long sys_ni_syscall    /* old sys_uname */
500         .long sys_ni_syscall    /* 110 - iopl */
501         .long sys_vhangup
502         .long sys_ni_syscall    /* old "idle" system call */
503         .long sys_ni_syscall    /* vm86old */
504         .long sys_wait4
505         .long sys_swapoff       /* 115 */
506         .long sys_sysinfo
507         .long sys_ipc
508         .long sys_fsync
509         .long sys_sigreturn
510         .long sys_clone         /* 120 */
511         .long sys_setdomainname
512         .long sys_newuname
513         .long sys_ni_syscall    /* modify_ldt */
514         .long sys_adjtimex
515         .long sys_mprotect      /* 125 */
516         .long sys_sigprocmask
517         .long sys_ni_syscall    /* old "create_module" */
518         .long sys_init_module
519         .long sys_delete_module
520         .long sys_ni_syscall    /* 130: old "get_kernel_syms" */
521         .long sys_quotactl
522         .long sys_getpgid
523         .long sys_fchdir
524         .long sys_bdflush
525         .long sys_sysfs         /* 135 */
526         .long sys_personality
527         .long sys_ni_syscall    /* reserved for afs_syscall */
528         .long sys_setfsuid16
529         .long sys_setfsgid16
530         .long sys_llseek        /* 140 */
531         .long sys_getdents
532         .long sys_select
533         .long sys_flock
534         .long sys_msync
535         .long sys_readv         /* 145 */
536         .long sys_writev
537         .long sys_getsid
538         .long sys_fdatasync
539         .long sys_sysctl
540         .long sys_mlock         /* 150 */
541         .long sys_munlock
542         .long sys_mlockall
543         .long sys_munlockall
544         .long sys_sched_setparam
545         .long sys_sched_getparam   /* 155 */
546         .long sys_sched_setscheduler
547         .long sys_sched_getscheduler
548         .long sys_sched_yield
549         .long sys_sched_get_priority_max
550         .long sys_sched_get_priority_min  /* 160 */
551         .long sys_sched_rr_get_interval
552         .long sys_nanosleep
553         .long sys_mremap
554         .long sys_setresuid16
555         .long sys_getresuid16   /* 165 */
556         .long sys_ni_syscall    /* vm86 */
557         .long sys_ni_syscall    /* Old sys_query_module */
558         .long sys_poll
559         .long sys_nfsservctl
560         .long sys_setresgid16   /* 170 */
561         .long sys_getresgid16
562         .long sys_prctl
563         .long sys_rt_sigreturn
564         .long sys_rt_sigaction
565         .long sys_rt_sigprocmask        /* 175 */
566         .long sys_rt_sigpending
567         .long sys_rt_sigtimedwait
568         .long sys_rt_sigqueueinfo
569         .long sys_rt_sigsuspend
570         .long sys_pread64       /* 180 */
571         .long sys_pwrite64
572         .long sys_chown16
573         .long sys_getcwd
574         .long sys_capget
575         .long sys_capset        /* 185 */
576         .long sys_sigaltstack
577         .long sys_sendfile
578         .long sys_ni_syscall    /* reserved for streams1 */
579         .long sys_ni_syscall    /* reserved for streams2 */
580         .long sys_vfork         /* 190 */
581         .long sys_getrlimit
582         .long sys_mmap_pgoff
583         .long sys_truncate64
584         .long sys_ftruncate64
585         .long sys_stat64        /* 195 */
586         .long sys_lstat64
587         .long sys_fstat64
588         .long sys_lchown
589         .long sys_getuid
590         .long sys_getgid        /* 200 */
591         .long sys_geteuid
592         .long sys_getegid
593         .long sys_setreuid
594         .long sys_setregid
595         .long sys_getgroups     /* 205 */
596         .long sys_setgroups
597         .long sys_fchown
598         .long sys_setresuid
599         .long sys_getresuid
600         .long sys_setresgid     /* 210 */
601         .long sys_getresgid
602         .long sys_chown
603         .long sys_setuid
604         .long sys_setgid
605         .long sys_setfsuid      /* 215 */
606         .long sys_setfsgid
607         .long sys_pivot_root
608         .long sys_mincore
609         .long sys_madvise
610         .long sys_getdents64    /* 220 */
611         .long sys_fcntl64
612         .long sys_ni_syscall    /* reserved for TUX */
613         .long sys_ni_syscall
614         .long sys_gettid
615         .long sys_readahead     /* 225 */
616         .long sys_setxattr
617         .long sys_lsetxattr
618         .long sys_fsetxattr
619         .long sys_getxattr
620         .long sys_lgetxattr     /* 230 */
621         .long sys_fgetxattr
622         .long sys_listxattr
623         .long sys_llistxattr
624         .long sys_flistxattr
625         .long sys_removexattr   /* 235 */
626         .long sys_lremovexattr
627         .long sys_fremovexattr
628         .long sys_tkill
629         .long sys_sendfile64
630         .long sys_futex         /* 240 */
631         .long sys_sched_setaffinity
632         .long sys_sched_getaffinity
633         .long sys_ni_syscall    /* sys_set_thread_area */
634         .long sys_ni_syscall    /* sys_get_thread_area */
635         .long sys_io_setup      /* 245 */
636         .long sys_io_destroy
637         .long sys_io_getevents
638         .long sys_io_submit
639         .long sys_io_cancel
640         .long sys_fadvise64     /* 250 */
641         .long sys_ni_syscall
642         .long sys_exit_group
643         .long sys_lookup_dcookie
644         .long sys_epoll_create
645         .long sys_epoll_ctl     /* 255 */
646         .long sys_epoll_wait
647         .long sys_remap_file_pages
648         .long sys_set_tid_address
649         .long sys_timer_create
650         .long sys_timer_settime         /* 260 */
651         .long sys_timer_gettime
652         .long sys_timer_getoverrun
653         .long sys_timer_delete
654         .long sys_clock_settime
655         .long sys_clock_gettime         /* 265 */
656         .long sys_clock_getres
657         .long sys_clock_nanosleep
658         .long sys_statfs64
659         .long sys_fstatfs64
660         .long sys_tgkill                /* 270 */
661         .long sys_utimes
662         .long sys_fadvise64_64
663         .long sys_ni_syscall    /* sys_vserver */
664         .long sys_mbind
665         .long sys_get_mempolicy         /* 275 */
666         .long sys_set_mempolicy
667         .long sys_mq_open
668         .long sys_mq_unlink
669         .long sys_mq_timedsend
670         .long sys_mq_timedreceive       /* 280 */
671         .long sys_mq_notify
672         .long sys_mq_getsetattr
673         .long sys_kexec_load
674         .long sys_waitid
675         .long sys_ni_syscall            /* 285 */ /* available */
676         .long sys_add_key
677         .long sys_request_key
678         .long sys_keyctl
679         .long sys_cacheflush
680         .long sys_ioprio_set            /* 290 */
681         .long sys_ioprio_get
682         .long sys_inotify_init
683         .long sys_inotify_add_watch
684         .long sys_inotify_rm_watch
685         .long sys_migrate_pages         /* 295 */
686         .long sys_openat
687         .long sys_mkdirat
688         .long sys_mknodat
689         .long sys_fchownat
690         .long sys_futimesat             /* 300 */
691         .long sys_fstatat64
692         .long sys_unlinkat
693         .long sys_renameat
694         .long sys_linkat
695         .long sys_symlinkat             /* 305 */
696         .long sys_readlinkat
697         .long sys_fchmodat
698         .long sys_faccessat
699         .long sys_pselect6
700         .long sys_ppoll                 /* 310 */
701         .long sys_unshare
702         .long sys_set_robust_list
703         .long sys_get_robust_list
704         .long sys_splice
705         .long sys_sync_file_range       /* 315 */
706         .long sys_tee
707         .long sys_vmsplice
708         .long sys_move_pages
709         .long sys_getcpu
710         .long sys_epoll_pwait           /* 320 */
711         .long sys_utimensat
712         .long sys_signalfd
713         .long sys_timerfd_create
714         .long sys_eventfd
715         .long sys_fallocate             /* 325 */
716         .long sys_timerfd_settime
717         .long sys_timerfd_gettime
718         .long sys_signalfd4
719         .long sys_eventfd2
720         .long sys_epoll_create1         /* 330 */
721         .long sys_dup3
722         .long sys_pipe2
723         .long sys_inotify_init1
724         .long sys_preadv
725         .long sys_pwritev               /* 335 */
726         .long sys_rt_tgsigqueueinfo
727         .long sys_perf_event_open
728         .long sys_recvmmsg
729
730
731 nr_syscalls=(.-sys_call_table)/4