18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * entry.S -- non-mmu 68000 interrupt and exception entry points 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 1991, 1992 Linus Torvalds 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 78c2ecf20Sopenharmony_ci * License. See the file README.legal in the main directory of this archive 88c2ecf20Sopenharmony_ci * for more details. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Linux/m68k support by Hamish Macdonald 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/linkage.h> 148c2ecf20Sopenharmony_ci#include <asm/thread_info.h> 158c2ecf20Sopenharmony_ci#include <asm/unistd.h> 168c2ecf20Sopenharmony_ci#include <asm/errno.h> 178c2ecf20Sopenharmony_ci#include <asm/setup.h> 188c2ecf20Sopenharmony_ci#include <asm/segment.h> 198c2ecf20Sopenharmony_ci#include <asm/traps.h> 208c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h> 218c2ecf20Sopenharmony_ci#include <asm/entry.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci.text 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci.globl system_call 268c2ecf20Sopenharmony_ci.globl resume 278c2ecf20Sopenharmony_ci.globl ret_from_exception 288c2ecf20Sopenharmony_ci.globl ret_from_signal 298c2ecf20Sopenharmony_ci.globl sys_call_table 308c2ecf20Sopenharmony_ci.globl bad_interrupt 318c2ecf20Sopenharmony_ci.globl inthandler1 328c2ecf20Sopenharmony_ci.globl inthandler2 338c2ecf20Sopenharmony_ci.globl inthandler3 348c2ecf20Sopenharmony_ci.globl inthandler4 358c2ecf20Sopenharmony_ci.globl inthandler5 368c2ecf20Sopenharmony_ci.globl inthandler6 378c2ecf20Sopenharmony_ci.globl inthandler7 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cibadsys: 408c2ecf20Sopenharmony_ci movel #-ENOSYS,%sp@(PT_OFF_D0) 418c2ecf20Sopenharmony_ci jra ret_from_exception 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cido_trace: 448c2ecf20Sopenharmony_ci movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/ 458c2ecf20Sopenharmony_ci subql #4,%sp 468c2ecf20Sopenharmony_ci SAVE_SWITCH_STACK 478c2ecf20Sopenharmony_ci jbsr syscall_trace_enter 488c2ecf20Sopenharmony_ci RESTORE_SWITCH_STACK 498c2ecf20Sopenharmony_ci addql #4,%sp 508c2ecf20Sopenharmony_ci addql #1,%d0 518c2ecf20Sopenharmony_ci jeq ret_from_exception 528c2ecf20Sopenharmony_ci movel %sp@(PT_OFF_ORIG_D0),%d1 538c2ecf20Sopenharmony_ci movel #-ENOSYS,%d0 548c2ecf20Sopenharmony_ci cmpl #NR_syscalls,%d1 558c2ecf20Sopenharmony_ci jcc 1f 568c2ecf20Sopenharmony_ci lsl #2,%d1 578c2ecf20Sopenharmony_ci lea sys_call_table, %a0 588c2ecf20Sopenharmony_ci jbsr %a0@(%d1) 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */ 618c2ecf20Sopenharmony_ci subql #4,%sp /* dummy return address */ 628c2ecf20Sopenharmony_ci SAVE_SWITCH_STACK 638c2ecf20Sopenharmony_ci jbsr syscall_trace_leave 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ciret_from_signal: 668c2ecf20Sopenharmony_ci RESTORE_SWITCH_STACK 678c2ecf20Sopenharmony_ci addql #4,%sp 688c2ecf20Sopenharmony_ci jra ret_from_exception 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ciENTRY(system_call) 718c2ecf20Sopenharmony_ci SAVE_ALL_SYS 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci /* save top of frame*/ 748c2ecf20Sopenharmony_ci pea %sp@ 758c2ecf20Sopenharmony_ci jbsr set_esp0 768c2ecf20Sopenharmony_ci addql #4,%sp 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci movel %sp@(PT_OFF_ORIG_D0),%d0 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci movel %sp,%d1 /* get thread_info pointer */ 818c2ecf20Sopenharmony_ci andl #-THREAD_SIZE,%d1 828c2ecf20Sopenharmony_ci movel %d1,%a2 838c2ecf20Sopenharmony_ci btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8) 848c2ecf20Sopenharmony_ci jne do_trace 858c2ecf20Sopenharmony_ci cmpl #NR_syscalls,%d0 868c2ecf20Sopenharmony_ci jcc badsys 878c2ecf20Sopenharmony_ci lsl #2,%d0 888c2ecf20Sopenharmony_ci lea sys_call_table,%a0 898c2ecf20Sopenharmony_ci movel %a0@(%d0), %a0 908c2ecf20Sopenharmony_ci jbsr %a0@ 918c2ecf20Sopenharmony_ci movel %d0,%sp@(PT_OFF_D0) /* save the return value*/ 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ciret_from_exception: 948c2ecf20Sopenharmony_ci btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/ 958c2ecf20Sopenharmony_ci jeq Luser_return /* if so, skip resched, signals*/ 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ciLkernel_return: 988c2ecf20Sopenharmony_ci RESTORE_ALL 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ciLuser_return: 1018c2ecf20Sopenharmony_ci /* only allow interrupts when we are really the last one on the*/ 1028c2ecf20Sopenharmony_ci /* kernel stack, otherwise stack overflow can occur during*/ 1038c2ecf20Sopenharmony_ci /* heavy interrupt load*/ 1048c2ecf20Sopenharmony_ci andw #ALLOWINT,%sr 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci movel %sp,%d1 /* get thread_info pointer */ 1078c2ecf20Sopenharmony_ci andl #-THREAD_SIZE,%d1 1088c2ecf20Sopenharmony_ci movel %d1,%a2 1098c2ecf20Sopenharmony_ci1: 1108c2ecf20Sopenharmony_ci move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ 1118c2ecf20Sopenharmony_ci jne Lwork_to_do 1128c2ecf20Sopenharmony_ci RESTORE_ALL 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ciLwork_to_do: 1158c2ecf20Sopenharmony_ci movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */ 1168c2ecf20Sopenharmony_ci btst #TIF_NEED_RESCHED,%d1 1178c2ecf20Sopenharmony_ci jne reschedule 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ciLsignal_return: 1208c2ecf20Sopenharmony_ci subql #4,%sp /* dummy return address*/ 1218c2ecf20Sopenharmony_ci SAVE_SWITCH_STACK 1228c2ecf20Sopenharmony_ci pea %sp@(SWITCH_STACK_SIZE) 1238c2ecf20Sopenharmony_ci bsrw do_notify_resume 1248c2ecf20Sopenharmony_ci addql #4,%sp 1258c2ecf20Sopenharmony_ci RESTORE_SWITCH_STACK 1268c2ecf20Sopenharmony_ci addql #4,%sp 1278c2ecf20Sopenharmony_ci jra 1b 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci/* 1308c2ecf20Sopenharmony_ci * This is the main interrupt handler, responsible for calling process_int() 1318c2ecf20Sopenharmony_ci */ 1328c2ecf20Sopenharmony_ciinthandler1: 1338c2ecf20Sopenharmony_ci SAVE_ALL_INT 1348c2ecf20Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 1358c2ecf20Sopenharmony_ci and #0x3ff, %d0 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci movel %sp,%sp@- 1388c2ecf20Sopenharmony_ci movel #65,%sp@- /* put vector # on stack*/ 1398c2ecf20Sopenharmony_ci jbsr process_int /* process the IRQ*/ 1408c2ecf20Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 1418c2ecf20Sopenharmony_ci bra ret_from_exception 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ciinthandler2: 1448c2ecf20Sopenharmony_ci SAVE_ALL_INT 1458c2ecf20Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 1468c2ecf20Sopenharmony_ci and #0x3ff, %d0 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci movel %sp,%sp@- 1498c2ecf20Sopenharmony_ci movel #66,%sp@- /* put vector # on stack*/ 1508c2ecf20Sopenharmony_ci jbsr process_int /* process the IRQ*/ 1518c2ecf20Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 1528c2ecf20Sopenharmony_ci bra ret_from_exception 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ciinthandler3: 1558c2ecf20Sopenharmony_ci SAVE_ALL_INT 1568c2ecf20Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 1578c2ecf20Sopenharmony_ci and #0x3ff, %d0 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci movel %sp,%sp@- 1608c2ecf20Sopenharmony_ci movel #67,%sp@- /* put vector # on stack*/ 1618c2ecf20Sopenharmony_ci jbsr process_int /* process the IRQ*/ 1628c2ecf20Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 1638c2ecf20Sopenharmony_ci bra ret_from_exception 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ciinthandler4: 1668c2ecf20Sopenharmony_ci SAVE_ALL_INT 1678c2ecf20Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 1688c2ecf20Sopenharmony_ci and #0x3ff, %d0 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci movel %sp,%sp@- 1718c2ecf20Sopenharmony_ci movel #68,%sp@- /* put vector # on stack*/ 1728c2ecf20Sopenharmony_ci jbsr process_int /* process the IRQ*/ 1738c2ecf20Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 1748c2ecf20Sopenharmony_ci bra ret_from_exception 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ciinthandler5: 1778c2ecf20Sopenharmony_ci SAVE_ALL_INT 1788c2ecf20Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 1798c2ecf20Sopenharmony_ci and #0x3ff, %d0 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci movel %sp,%sp@- 1828c2ecf20Sopenharmony_ci movel #69,%sp@- /* put vector # on stack*/ 1838c2ecf20Sopenharmony_ci jbsr process_int /* process the IRQ*/ 1848c2ecf20Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 1858c2ecf20Sopenharmony_ci bra ret_from_exception 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ciinthandler6: 1888c2ecf20Sopenharmony_ci SAVE_ALL_INT 1898c2ecf20Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 1908c2ecf20Sopenharmony_ci and #0x3ff, %d0 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci movel %sp,%sp@- 1938c2ecf20Sopenharmony_ci movel #70,%sp@- /* put vector # on stack*/ 1948c2ecf20Sopenharmony_ci jbsr process_int /* process the IRQ*/ 1958c2ecf20Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 1968c2ecf20Sopenharmony_ci bra ret_from_exception 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ciinthandler7: 1998c2ecf20Sopenharmony_ci SAVE_ALL_INT 2008c2ecf20Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 2018c2ecf20Sopenharmony_ci and #0x3ff, %d0 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci movel %sp,%sp@- 2048c2ecf20Sopenharmony_ci movel #71,%sp@- /* put vector # on stack*/ 2058c2ecf20Sopenharmony_ci jbsr process_int /* process the IRQ*/ 2068c2ecf20Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 2078c2ecf20Sopenharmony_ci bra ret_from_exception 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ciinthandler: 2108c2ecf20Sopenharmony_ci SAVE_ALL_INT 2118c2ecf20Sopenharmony_ci movew %sp@(PT_OFF_FORMATVEC), %d0 2128c2ecf20Sopenharmony_ci and #0x3ff, %d0 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci movel %sp,%sp@- 2158c2ecf20Sopenharmony_ci movel %d0,%sp@- /* put vector # on stack*/ 2168c2ecf20Sopenharmony_ci jbsr process_int /* process the IRQ*/ 2178c2ecf20Sopenharmony_ci3: addql #8,%sp /* pop parameters off stack*/ 2188c2ecf20Sopenharmony_ci bra ret_from_exception 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci/* 2218c2ecf20Sopenharmony_ci * Handler for uninitialized and spurious interrupts. 2228c2ecf20Sopenharmony_ci */ 2238c2ecf20Sopenharmony_ciENTRY(bad_interrupt) 2248c2ecf20Sopenharmony_ci addql #1,irq_err_count 2258c2ecf20Sopenharmony_ci rte 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci/* 2288c2ecf20Sopenharmony_ci * Beware - when entering resume, prev (the current task) is 2298c2ecf20Sopenharmony_ci * in a0, next (the new task) is in a1, so don't change these 2308c2ecf20Sopenharmony_ci * registers until their contents are no longer needed. 2318c2ecf20Sopenharmony_ci */ 2328c2ecf20Sopenharmony_ciENTRY(resume) 2338c2ecf20Sopenharmony_ci movel %a0,%d1 /* save prev thread in d1 */ 2348c2ecf20Sopenharmony_ci movew %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */ 2358c2ecf20Sopenharmony_ci SAVE_SWITCH_STACK 2368c2ecf20Sopenharmony_ci movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */ 2378c2ecf20Sopenharmony_ci movel %usp,%a3 /* save usp */ 2388c2ecf20Sopenharmony_ci movel %a3,%a0@(TASK_THREAD+THREAD_USP) 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci movel %a1@(TASK_THREAD+THREAD_USP),%a3 /* restore user stack */ 2418c2ecf20Sopenharmony_ci movel %a3,%usp 2428c2ecf20Sopenharmony_ci movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */ 2438c2ecf20Sopenharmony_ci RESTORE_SWITCH_STACK 2448c2ecf20Sopenharmony_ci movew %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */ 2458c2ecf20Sopenharmony_ci rts 2468c2ecf20Sopenharmony_ci 247