1 /*
2  * Copyright (C) 2016-2020 Paul Cercueil <paul@crapouillou.net>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  */
14 
15 #ifndef __LIGHTREC_H__
16 #define __LIGHTREC_H__
17 
18 #ifdef __cplusplus
19 #define _Bool bool
20 extern "C" {
21 #endif
22 
23 #include <stddef.h>
24 #include <stdint.h>
25 
26 #ifdef _WIN32
27 #   ifdef lightrec_EXPORTS
28 #	define __api __declspec(dllexport)
29 #   elif !defined(LIGHTREC_STATIC)
30 #	define __api __declspec(dllimport)
31 #   else
32 #	define __api
33 #   endif
34 #elif __GNUC__ >= 4
35 #   define __api __attribute__((visibility ("default")))
36 #else
37 #   define __api
38 #endif
39 
40 typedef uint64_t u64;
41 typedef uint32_t u32;
42 typedef uint16_t u16;
43 typedef uint8_t  u8;
44 
45 typedef int64_t s64;
46 typedef int32_t s32;
47 typedef int16_t s16;
48 typedef int8_t  s8;
49 
50 struct lightrec_state;
51 struct lightrec_mem_map;
52 
53 /* Exit flags */
54 #define LIGHTREC_EXIT_NORMAL	(0)
55 #define LIGHTREC_EXIT_SYSCALL	(1 << 0)
56 #define LIGHTREC_EXIT_BREAK	(1 << 1)
57 #define LIGHTREC_EXIT_CHECK_INTERRUPT	(1 << 2)
58 #define LIGHTREC_EXIT_SEGFAULT	(1 << 3)
59 
60 enum psx_map {
61 	PSX_MAP_KERNEL_USER_RAM,
62 	PSX_MAP_BIOS,
63 	PSX_MAP_SCRATCH_PAD,
64 	PSX_MAP_PARALLEL_PORT,
65 	PSX_MAP_HW_REGISTERS,
66 	PSX_MAP_CACHE_CONTROL,
67 	PSX_MAP_MIRROR1,
68 	PSX_MAP_MIRROR2,
69 	PSX_MAP_MIRROR3,
70 };
71 
72 enum mem_type {
73 	MEM_FOR_CODE,
74 	MEM_FOR_MIPS_CODE,
75 	MEM_FOR_IR,
76 	MEM_FOR_LIGHTREC,
77 	MEM_TYPE_END,
78 };
79 
80 struct lightrec_mem_map_ops {
81 	void (*sb)(struct lightrec_state *, u32 opcode,
82 		   void *host, u32 addr, u8 data);
83 	void (*sh)(struct lightrec_state *, u32 opcode,
84 		   void *host, u32 addr, u16 data);
85 	void (*sw)(struct lightrec_state *, u32 opcode,
86 		   void *host, u32 addr, u32 data);
87 	u8 (*lb)(struct lightrec_state *, u32 opcode, void *host, u32 addr);
88 	u16 (*lh)(struct lightrec_state *, u32 opcode, void *host, u32 addr);
89 	u32 (*lw)(struct lightrec_state *, u32 opcode, void *host, u32 addr);
90 };
91 
92 struct lightrec_mem_map {
93 	u32 pc;
94 	u32 length;
95 	void *address;
96 	const struct lightrec_mem_map_ops *ops;
97 	const struct lightrec_mem_map *mirror_of;
98 };
99 
100 struct lightrec_cop_ops {
101 	u32 (*mfc)(struct lightrec_state *state, u32 op, u8 reg);
102 	u32 (*cfc)(struct lightrec_state *state, u32 op, u8 reg);
103 	void (*mtc)(struct lightrec_state *state, u32 op, u8 reg, u32 value);
104 	void (*ctc)(struct lightrec_state *state, u32 op, u8 reg, u32 value);
105 	void (*op)(struct lightrec_state *state, u32 op);
106 };
107 
108 struct lightrec_ops {
109 	struct lightrec_cop_ops cop0_ops;
110 	struct lightrec_cop_ops cop2_ops;
111 };
112 
113 __api struct lightrec_state *lightrec_init(char *argv0,
114 					   const struct lightrec_mem_map *map,
115 					   size_t nb,
116 					   const struct lightrec_ops *ops);
117 
118 __api void lightrec_destroy(struct lightrec_state *state);
119 
120 __api u32 lightrec_execute(struct lightrec_state *state,
121 			   u32 pc, u32 target_cycle);
122 __api u32 lightrec_execute_one(struct lightrec_state *state, u32 pc);
123 __api u32 lightrec_run_interpreter(struct lightrec_state *state, u32 pc);
124 
125 __api void lightrec_invalidate(struct lightrec_state *state, u32 addr, u32 len);
126 __api void lightrec_invalidate_all(struct lightrec_state *state);
127 __api void lightrec_set_invalidate_mode(struct lightrec_state *state,
128 					_Bool dma_only);
129 
130 __api void lightrec_set_exit_flags(struct lightrec_state *state, u32 flags);
131 __api u32 lightrec_exit_flags(struct lightrec_state *state);
132 
133 __api void lightrec_dump_registers(struct lightrec_state *state, u32 regs[34]);
134 __api void lightrec_restore_registers(struct lightrec_state *state,
135 				      u32 regs[34]);
136 
137 __api u32 lightrec_current_cycle_count(const struct lightrec_state *state);
138 __api void lightrec_reset_cycle_count(struct lightrec_state *state, u32 cycles);
139 __api void lightrec_set_target_cycle_count(struct lightrec_state *state,
140 					   u32 cycles);
141 
142 __api unsigned int lightrec_get_mem_usage(enum mem_type type);
143 __api unsigned int lightrec_get_total_mem_usage(void);
144 __api float lightrec_get_average_ipi(void);
145 
146 #ifdef __cplusplus
147 };
148 #endif
149 
150 #endif /* __LIGHTREC_H__ */
151