Commit | Line | Data |
---|---|---|
98fa08a5 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
d16005f8 | 2 | /* |
98fa08a5 | 3 | * Copyright (C) 2016-2021 Paul Cercueil <paul@crapouillou.net> |
d16005f8 PC |
4 | */ |
5 | ||
6 | #ifndef __LIGHTREC_H__ | |
7 | #define __LIGHTREC_H__ | |
8 | ||
9 | #ifdef __cplusplus | |
10 | #define _Bool bool | |
11 | extern "C" { | |
12 | #endif | |
13 | ||
14 | #include <stddef.h> | |
15 | #include <stdint.h> | |
16 | ||
17 | #ifdef _WIN32 | |
18 | # ifdef lightrec_EXPORTS | |
19 | # define __api __declspec(dllexport) | |
20 | # elif !defined(LIGHTREC_STATIC) | |
21 | # define __api __declspec(dllimport) | |
22 | # else | |
23 | # define __api | |
24 | # endif | |
25 | #elif __GNUC__ >= 4 | |
26 | # define __api __attribute__((visibility ("default"))) | |
27 | #else | |
28 | # define __api | |
29 | #endif | |
30 | ||
cb72ea13 PC |
31 | #ifndef __cnst |
32 | # ifdef __GNUC__ | |
33 | # define __cnst __attribute__((const)) | |
34 | # else | |
35 | # define __cnst | |
36 | # endif | |
37 | #endif | |
38 | #ifndef __pure | |
39 | # ifdef __GNUC__ | |
40 | # define __pure __attribute__((pure)) | |
41 | # else | |
42 | # define __pure | |
43 | # endif | |
44 | #endif | |
45 | ||
d16005f8 PC |
46 | typedef uint64_t u64; |
47 | typedef uint32_t u32; | |
48 | typedef uint16_t u16; | |
49 | typedef uint8_t u8; | |
50 | ||
51 | typedef int64_t s64; | |
52 | typedef int32_t s32; | |
53 | typedef int16_t s16; | |
54 | typedef int8_t s8; | |
55 | ||
56 | struct lightrec_state; | |
57 | struct lightrec_mem_map; | |
58 | ||
59 | /* Exit flags */ | |
60 | #define LIGHTREC_EXIT_NORMAL (0) | |
98fa08a5 | 61 | #define LIGHTREC_EXIT_CHECK_INTERRUPT (1 << 0) |
d16005f8 | 62 | #define LIGHTREC_EXIT_BREAK (1 << 1) |
98fa08a5 | 63 | #define LIGHTREC_EXIT_SYSCALL (1 << 2) |
d16005f8 | 64 | #define LIGHTREC_EXIT_SEGFAULT (1 << 3) |
d8b04acd | 65 | #define LIGHTREC_EXIT_NOMEM (1 << 4) |
e26c79a8 | 66 | #define LIGHTREC_EXIT_UNKNOWN_OP (1 << 5) |
d16005f8 | 67 | |
684432ad PC |
68 | /* Unsafe optimizations flags */ |
69 | #define LIGHTREC_OPT_INV_DMA_ONLY (1 << 0) | |
70 | #define LIGHTREC_OPT_SP_GP_HIT_RAM (1 << 1) | |
71 | ||
d16005f8 PC |
72 | enum psx_map { |
73 | PSX_MAP_KERNEL_USER_RAM, | |
74 | PSX_MAP_BIOS, | |
75 | PSX_MAP_SCRATCH_PAD, | |
76 | PSX_MAP_PARALLEL_PORT, | |
77 | PSX_MAP_HW_REGISTERS, | |
78 | PSX_MAP_CACHE_CONTROL, | |
79 | PSX_MAP_MIRROR1, | |
80 | PSX_MAP_MIRROR2, | |
81 | PSX_MAP_MIRROR3, | |
02487de7 | 82 | PSX_MAP_CODE_BUFFER, |
0e720fb1 | 83 | PSX_MAP_PPORT_MIRROR, |
02487de7 PC |
84 | |
85 | PSX_MAP_UNKNOWN, | |
d16005f8 PC |
86 | }; |
87 | ||
d16005f8 | 88 | struct lightrec_mem_map_ops { |
a59e5536 | 89 | void (*sb)(struct lightrec_state *, u32 opcode, |
2e6c828e | 90 | void *host, u32 addr, u32 data); |
a59e5536 | 91 | void (*sh)(struct lightrec_state *, u32 opcode, |
2e6c828e | 92 | void *host, u32 addr, u32 data); |
a59e5536 | 93 | void (*sw)(struct lightrec_state *, u32 opcode, |
94 | void *host, u32 addr, u32 data); | |
95 | u8 (*lb)(struct lightrec_state *, u32 opcode, void *host, u32 addr); | |
96 | u16 (*lh)(struct lightrec_state *, u32 opcode, void *host, u32 addr); | |
97 | u32 (*lw)(struct lightrec_state *, u32 opcode, void *host, u32 addr); | |
5459088b PC |
98 | u32 (*lwu)(struct lightrec_state *, u32 opcode, void *host, u32 addr); |
99 | void (*swu)(struct lightrec_state *, u32 opcode, | |
100 | void *host, u32 addr, u32 data); | |
d16005f8 PC |
101 | }; |
102 | ||
103 | struct lightrec_mem_map { | |
104 | u32 pc; | |
105 | u32 length; | |
106 | void *address; | |
107 | const struct lightrec_mem_map_ops *ops; | |
108 | const struct lightrec_mem_map *mirror_of; | |
109 | }; | |
110 | ||
98fa08a5 | 111 | struct lightrec_ops { |
fdf33147 | 112 | void (*cop2_notify)(struct lightrec_state *state, u32 op, u32 data); |
98fa08a5 PC |
113 | void (*cop2_op)(struct lightrec_state *state, u32 op); |
114 | void (*enable_ram)(struct lightrec_state *state, _Bool enable); | |
ba3814c1 | 115 | _Bool (*hw_direct)(u32 kaddr, _Bool is_write, u8 size); |
9259d748 | 116 | void (*code_inv)(void *addr, u32 len); |
d16005f8 PC |
117 | }; |
118 | ||
98fa08a5 PC |
119 | struct lightrec_registers { |
120 | u32 gpr[34]; | |
121 | u32 cp0[32]; | |
122 | u32 cp2d[32]; | |
123 | u32 cp2c[32]; | |
d16005f8 PC |
124 | }; |
125 | ||
126 | __api struct lightrec_state *lightrec_init(char *argv0, | |
127 | const struct lightrec_mem_map *map, | |
128 | size_t nb, | |
129 | const struct lightrec_ops *ops); | |
130 | ||
131 | __api void lightrec_destroy(struct lightrec_state *state); | |
132 | ||
133 | __api u32 lightrec_execute(struct lightrec_state *state, | |
134 | u32 pc, u32 target_cycle); | |
ba3814c1 PC |
135 | __api u32 lightrec_run_interpreter(struct lightrec_state *state, |
136 | u32 pc, u32 target_cycle); | |
d16005f8 PC |
137 | |
138 | __api void lightrec_invalidate(struct lightrec_state *state, u32 addr, u32 len); | |
139 | __api void lightrec_invalidate_all(struct lightrec_state *state); | |
d16005f8 PC |
140 | |
141 | __api void lightrec_set_exit_flags(struct lightrec_state *state, u32 flags); | |
142 | __api u32 lightrec_exit_flags(struct lightrec_state *state); | |
143 | ||
684432ad PC |
144 | __api void lightrec_set_unsafe_opt_flags(struct lightrec_state *state, u32 flags); |
145 | ||
cb72ea13 PC |
146 | __api __cnst struct lightrec_registers * |
147 | lightrec_get_registers(struct lightrec_state *state); | |
d16005f8 PC |
148 | |
149 | __api u32 lightrec_current_cycle_count(const struct lightrec_state *state); | |
150 | __api void lightrec_reset_cycle_count(struct lightrec_state *state, u32 cycles); | |
151 | __api void lightrec_set_target_cycle_count(struct lightrec_state *state, | |
152 | u32 cycles); | |
684432ad | 153 | __api void lightrec_set_cycles_per_opcode(struct lightrec_state *state, u32 cycles); |
d16005f8 | 154 | |
d16005f8 PC |
155 | #ifdef __cplusplus |
156 | }; | |
157 | #endif | |
158 | ||
159 | #endif /* __LIGHTREC_H__ */ |