1 /*
2  * Copyright (c) 2021 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #include <arch/m68k.h>
9 #include <inttypes.h>
10 #include <lk/debug.h>
11 #include <lk/trace.h>
12 #include <kernel/thread.h>
13 #include <target.h>
14 
15 #define LOCAL_TRACE 0
16 
17 typedef struct m68k_iframe {
18     uint32_t d[8];
19     uint32_t a[7];
20     uint16_t sr;
21     uint16_t pc_high;
22     uint16_t pc_low;
23     uint16_t format : 4;
24     uint16_t vector_offset : 12;
25 } m68k_iframe_t;
26 
dump_iframe(const m68k_iframe_t * iframe)27 void dump_iframe(const m68k_iframe_t *iframe) {
28     printf("pc 0x%08x sr 0x%04x format %#x vector %#x\n", iframe->pc_low | iframe->pc_high << 16, iframe->sr,
29             iframe->format, iframe->vector_offset / 4);
30     printf("d0 0x%08x d1 0x%08x d2 0x%08x d3 0x%08x\n", iframe->d[0], iframe->d[1], iframe->d[2], iframe->d[3]);
31     printf("d4 0x%08x d5 0x%08x d6 0x%08x d7 0x%08x\n", iframe->d[4], iframe->d[5], iframe->d[6], iframe->d[7]);
32     printf("a0 0x%08x a1 0x%08x a2 0x%08x a3 0x%08x\n", iframe->a[0], iframe->a[1], iframe->a[2], iframe->a[3]);
33     printf("a4 0x%08x a5 0x%08x a6 0x%08x\n", iframe->a[4], iframe->a[5], iframe->a[6]);
34 }
35 
m68k_exception(m68k_iframe_t * frame)36 void m68k_exception(m68k_iframe_t *frame) {
37     uint8_t code = frame->vector_offset / 4;
38 
39     LTRACEF("frame %p, code %#hhx\n", frame, code);
40 
41     dump_iframe(frame);
42 
43     printf("more stack:\n");
44     hexdump8(frame, 256);
45 
46     panic("unimplemented exception %#hhx\n", code);
47 }
48 
m68k_trap_exception(m68k_iframe_t * frame)49 void m68k_trap_exception(m68k_iframe_t *frame) {
50     panic("unhandled trap exception!\n");
51 }
52 
m68k_null_trap(m68k_iframe_t * frame)53 void m68k_null_trap(m68k_iframe_t *frame) {
54     panic("unhandled null trap exception!");
55 }
56 
57 // defined in platform interrupt controller
58 extern enum handler_return m68k_platform_irq(uint8_t irq);
59 
m68k_irq(m68k_iframe_t * frame)60 void m68k_irq(m68k_iframe_t *frame) {
61     uint8_t code = frame->vector_offset / 4;
62 
63     LTRACEF("frame %p, code %#hhx\n", frame, code);
64 
65     THREAD_STATS_INC(interrupts);
66 
67     if (unlikely(code == 0)) {
68         // spurious interrupt
69         return;
70     }
71 
72     target_set_debug_led(1, true);
73 
74     enum handler_return ret = m68k_platform_irq(code);
75 
76     target_set_debug_led(1, false);
77 
78     if (ret == INT_RESCHEDULE) {
79         thread_preempt();
80     }
81 }
82