-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkine.h
More file actions
186 lines (146 loc) · 4.9 KB
/
kine.h
File metadata and controls
186 lines (146 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef KINE_H
#define KINE_H
#include <pthread.h>
#include <stddef.h>
#include <stdint.h>
#define ARRSZE(X) (sizeof(X) / sizeof(*(X)))
#define XSTR(S) STR(S)
#define STR(S) #S
#define container_of(ptr, type, member) \
((type *)(((void *)(ptr)) - offsetof(type, member)))
struct ring {
uint8_t buf[256];
uint8_t a, z;
};
#define RING_INITIALIZER { .a = -1 }
typedef uint32_t palette_t[256];
typedef uint32_t framebuffer_t[320 * 200];
struct render_state {
void (*set_palette)(struct render_state*, const palette_t*, size_t);
void (*swap_frontbuffer)(struct render_state*, const framebuffer_t*);
};
extern const palette_t libvga_default_palette;
struct k_state_t {
pthread_mutex_t lock;
int video_mode;
int quit;
int32_t key;
struct render_state* render_state;
struct ring keys;
/* unlocked */
uint32_t brk; /* only accessed by k_thread */
uint32_t starttime; /* only read */
int fds[64];
};
void render_state_set(struct k_state_t* k, struct render_state* render_state);
struct config_t {
int root;
int strace, coredump, k_on_main_thread;
uintptr_t base, sp, brk;
union {
uint32_t limit;
struct {
uint32_t __zeros:12;
uint32_t limit_as_pages:20;
};
};
};
void k_lock(struct k_state_t*);
void k_unlock(struct k_state_t*);
static inline void k_unlock_ref(struct k_state_t** ptr) {
k_unlock(*ptr);
}
#define K_LOCK_SCOPPED(Lck, State) \
struct k_state_t *Lck __attribute__((cleanup(k_unlock_ref))) = \
({ struct k_state_t *val_ = (State); k_lock(val_); val_; })
extern struct config_t config;
extern struct k_state_t k_state;
typedef void (*entry_t)(void);
void k_prepare(void);
__attribute((noreturn))
void k_start(entry_t entry);
#define SEGMENT_CODE 1
#define SEGMENT_DATA 2
#define SEGMENT_LINUX_GS 12
#define SEGMENT_LDT (1 << 2)
#define SEGMENT_GDT 0
#define SEGMENT_RPL3 (0x3)
#define SEG_REG(Segment, Table, Rpl) \
((SEGMENT_##Segment << 3) | SEGMENT_##Table | SEGMENT_RPL##Rpl)
static inline int ring_push(struct ring* rb, uint8_t c) {
if ((rb->z + 1) % ARRSZE(rb->buf) == rb->a)
return -1;
rb->buf[rb->z++] = c;
return 0;
}
static inline int ring_pop(struct ring* rb, uint8_t* c) {
if ((rb->a + 1) % ARRSZE(rb->buf) == rb->z)
return -1;
*c = rb->buf[++rb->a];
return 0;
}
int32_t syscall_dispatch(uint32_t sysnr, uint32_t arg1, uint32_t arg2, uint32_t arg3);
uint32_t getms(void);
# define XCONCAT(X, Y) X##Y
# define CONCAT(X, Y) XCONCAT(X, Y)
#define UNIQUE_ID(Name) CONCAT(Name, __COUNTER__)
#define DEFINE_MODULE(Class, Name, Value) \
__attribute__((used, section("module_" #Class "_names"))) \
static const char* const UNIQUE_ID(Class##_name) = #Name; \
__attribute__((used, section("module_" #Class "_values"))) \
static module_##Class##_value_t UNIQUE_ID(Class##_value) = Value; \
struct module_class {
size_t (*size)(void);
const char* const* names;
};
#define DEFINE_MODULE_CLASS(Class, Type) \
typedef Type module_##Class##_value_t; \
extern const char* const __start_module_##Class##_names, \
* const __stop_module_##Class##_names; \
extern module_##Class##_value_t __start_module_##Class##_values, \
__stop_module_##Class##_values; \
static inline size_t module_##Class##_size(void) { \
return &__stop_module_##Class##_names - &__start_module_##Class##_names; \
} \
static inline module_##Class##_value_t* module_##Class##_get_values(void) { \
return &__start_module_##Class##_values; \
} \
static inline module_##Class##_value_t* module_##Class##_get(size_t i) { \
return module_##Class##_get_values() + i; \
} \
__attribute__((unused)) \
static struct module_class module_##Class = { \
.size = module_##Class##_size, \
.names = &__start_module_##Class##_names, \
}; \
static inline module_##Class##_value_t* module_##Class##_find(const char* name) { \
extern int strcmp(const char *s1, const char *s2); \
for (size_t i = 0; i < module_##Class##_size(); i++) \
if (!strcmp(name, module_##Class.names[i])) \
return module_##Class##_get(i); \
return NULL; \
} \
typedef void* (*renderer_t)(struct k_state_t*);
DEFINE_MODULE_CLASS(renderer, const renderer_t);
#define DEFINE_RENDERER(Name, Value) DEFINE_MODULE(renderer, Name, Value)
#define K_THREAD_FAILED_INIT ((void*)1)
typedef void* (*k_thread_t)(void* entry);
DEFINE_MODULE_CLASS(mode, const k_thread_t);
#define DEFINE_MODE(Name, Value) DEFINE_MODULE(mode, Name, Value)
#define FLAG_KEY_RELEASED 0x80
#endif