1 /*
2  * Copyright (c) 2015 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 #pragma once
9 
10 #ifndef ASSEMBLY
11 #include <lk/compiler.h>
12 #include <stdint.h>
13 #include <sys/types.h>
14 
15 #define GEN_CP_REG_FUNCS(regname, regnum, sel) \
16 static inline __ALWAYS_INLINE uint32_t mips_read_##regname(void) { \
17     uint32_t val; \
18     __asm__ volatile("mfc0 %0, $" #regnum ", " #sel : "=r" (val)); \
19     return val; \
20 } \
21 \
22 static inline __ALWAYS_INLINE uint32_t mips_read_##regname##_relaxed(void) { \
23     uint32_t val; \
24     __asm__("mfc0 %0, $" #regnum ", " #sel : "=r" (val)); \
25     return val; \
26 } \
27 \
28 static inline __ALWAYS_INLINE void mips_write_##regname(uint32_t val) { \
29     __asm__ volatile("mtc0 %0, $" #regnum ", " #sel :: "r" (val)); \
30 } \
31 \
32 static inline __ALWAYS_INLINE void mips_write_##regname##_relaxed(uint32_t val) { \
33     __asm__ volatile("mtc0 %0, $" #regnum ", " #sel :: "r" (val)); \
34 }
35 
36 GEN_CP_REG_FUNCS(c0_count, 9, 0)
37 GEN_CP_REG_FUNCS(c0_compare, 11, 0)
38 GEN_CP_REG_FUNCS(c0_status, 12, 0)
39 GEN_CP_REG_FUNCS(c0_intctl, 12, 1)
40 GEN_CP_REG_FUNCS(c0_srsctl, 12, 2)
41 GEN_CP_REG_FUNCS(c0_srsmap1, 12, 3)
42 GEN_CP_REG_FUNCS(c0_view_ipl, 12, 4)
43 GEN_CP_REG_FUNCS(c0_srsmap2, 12, 5)
44 GEN_CP_REG_FUNCS(c0_cause, 13, 0)
45 GEN_CP_REG_FUNCS(c0_epc, 14, 0)
46 GEN_CP_REG_FUNCS(c0_prid, 15, 0)
47 GEN_CP_REG_FUNCS(c0_ebase, 15, 1)
48 GEN_CP_REG_FUNCS(c0_cdmmbase, 15, 2)
49 GEN_CP_REG_FUNCS(c0_config, 16, 0)
50 GEN_CP_REG_FUNCS(c0_config1, 16, 1)
51 GEN_CP_REG_FUNCS(c0_config2, 16, 2)
52 GEN_CP_REG_FUNCS(c0_config3, 16, 3)
53 GEN_CP_REG_FUNCS(c0_config4, 16, 4)
54 GEN_CP_REG_FUNCS(c0_config5, 16, 5)
55 GEN_CP_REG_FUNCS(c0_config6, 16, 6)
56 GEN_CP_REG_FUNCS(c0_config7, 16, 7)
57 GEN_CP_REG_FUNCS(c0_config8, 16, 8)
58 
59 struct mips_iframe {
60     uint32_t at;
61     uint32_t v0;
62     uint32_t v1;
63     uint32_t a0;
64     uint32_t a1;
65     uint32_t a2;
66     uint32_t a3;
67     uint32_t t0;
68     uint32_t t1;
69     uint32_t t2;
70     uint32_t t3;
71     uint32_t t4;
72     uint32_t t5;
73     uint32_t t6;
74     uint32_t t7;
75     uint32_t t8;
76     uint32_t t9;
77     uint32_t gp;
78     uint32_t ra;
79     uint32_t status;
80     uint32_t cause;
81     uint32_t epc;
82 };
83 STATIC_ASSERT(sizeof(struct mips_iframe) == 88);
84 
85 void mips_init_timer(uint32_t freq);
86 enum handler_return mips_timer_irq(void);
87 
88 void mips_enable_irq(uint num);
89 void mips_disable_irq(uint num);
90 
91 #endif // !ASSEMBLY
92 
93 #define VECTORED_OFFSET_SHIFT 32
94 
95