Skip to content

Commit 889ca0b

Browse files
committed
Initial commit.
0 parents  commit 889ca0b

8 files changed

Lines changed: 1333 additions & 0 deletions

File tree

include/s3k/s3k.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef S3K_H
2+
#define S3K_H
3+
4+
#include "s3k/syscall.h"
5+
#include "s3k/types.h"
6+
#include "s3k/util.h"
7+
8+
#endif /* S3K_H */

include/s3k/syscall.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#pragma once
2+
#include "s3k/types.h"
3+
4+
uint64_t s3k_get_pid(void);
5+
uint64_t s3k_get_time(void);
6+
uint64_t s3k_get_timeout(void);
7+
uint64_t s3k_reg_read(s3k_reg_t reg);
8+
uint64_t s3k_reg_write(s3k_reg_t reg, uint64_t val);
9+
void s3k_sync();
10+
void s3k_sync_mem();
11+
void s3k_sleep(uint64_t time);
12+
s3k_err_t s3k_cap_read(s3k_cidx_t idx, s3k_cap_t *cap);
13+
s3k_err_t s3k_cap_move(s3k_cidx_t src, s3k_cidx_t dst);
14+
s3k_err_t s3k_cap_delete(s3k_cidx_t idx);
15+
s3k_err_t s3k_cap_revoke(s3k_cidx_t idx);
16+
s3k_err_t s3k_cap_derive(s3k_cidx_t src, s3k_cidx_t dst, s3k_cap_t new_cap);
17+
s3k_err_t s3k_pmp_load(s3k_cidx_t pmp_idx, s3k_pmp_slot_t pmp_slot);
18+
s3k_err_t s3k_pmp_unload(s3k_cidx_t pmp_idx);
19+
s3k_err_t s3k_mon_suspend(s3k_cidx_t mon_idx, s3k_pid_t pid);
20+
s3k_err_t s3k_mon_resume(s3k_cidx_t mon_idx, s3k_pid_t pid);
21+
s3k_err_t s3k_mon_state_get(s3k_cidx_t mon_idx, s3k_pid_t pid,
22+
s3k_state_t *state);
23+
s3k_err_t s3k_mon_yield(s3k_cidx_t mon_idx, s3k_pid_t pid);
24+
s3k_err_t s3k_mon_reg_read(s3k_cidx_t mon_idx, s3k_pid_t pid, s3k_reg_t reg,
25+
uint64_t *val);
26+
s3k_err_t s3k_mon_reg_write(s3k_cidx_t mon_idx, s3k_pid_t pid, s3k_reg_t reg,
27+
uint64_t val);
28+
s3k_err_t s3k_mon_cap_read(s3k_cidx_t mon_idx, s3k_pid_t pid, s3k_cidx_t idx,
29+
s3k_cap_t *cap);
30+
s3k_err_t s3k_mon_cap_send(s3k_cidx_t mon_idx, s3k_cidx_t src_idx,
31+
s3k_pid_t dst_pid, s3k_cidx_t dst_idx);
32+
s3k_err_t s3k_mon_pmp_load(s3k_cidx_t mon_idx, s3k_pid_t pid,
33+
s3k_cidx_t pmp_idx, s3k_pmp_slot_t pmp_slot);
34+
s3k_err_t s3k_mon_pmp_unload(s3k_cidx_t mon_idx, s3k_pid_t pid,
35+
s3k_cidx_t pmp_idx);
36+
s3k_err_t s3k_sock_send(s3k_cidx_t sock_idx, const s3k_msg_t *msg);
37+
s3k_reply_t s3k_sock_recv(s3k_cidx_t sock_idx, s3k_cidx_t cap_cidx);
38+
s3k_reply_t s3k_sock_sendrecv(s3k_cidx_t sock_idx, const s3k_msg_t *msg);
39+
40+
s3k_err_t s3k_try_cap_move(s3k_cidx_t src, s3k_cidx_t dst);
41+
s3k_err_t s3k_try_cap_delete(s3k_cidx_t idx);
42+
s3k_err_t s3k_try_cap_revoke(s3k_cidx_t idx);
43+
s3k_err_t s3k_try_cap_derive(s3k_cidx_t src, s3k_cidx_t dst, s3k_cap_t new_cap);
44+
s3k_err_t s3k_try_pmp_load(s3k_cidx_t pmp_idx, s3k_pmp_slot_t pmp_slot);
45+
s3k_err_t s3k_try_pmp_unload(s3k_cidx_t pmp_idx);
46+
s3k_err_t s3k_try_mon_suspend(s3k_cidx_t mon_idx, s3k_pid_t pid);
47+
s3k_err_t s3k_try_mon_resume(s3k_cidx_t mon_idx, s3k_pid_t pid);
48+
s3k_err_t s3k_try_mon_state_get(s3k_cidx_t mon_idx, s3k_pid_t pid,
49+
s3k_state_t *state);
50+
s3k_err_t s3k_try_mon_yield(s3k_cidx_t mon_idx, s3k_pid_t pid);
51+
s3k_err_t s3k_try_mon_reg_read(s3k_cidx_t mon_idx, s3k_pid_t pid, s3k_reg_t reg,
52+
uint64_t *val);
53+
s3k_err_t s3k_try_mon_reg_write(s3k_cidx_t mon_idx, s3k_pid_t pid,
54+
s3k_reg_t reg, uint64_t val);
55+
s3k_err_t s3k_try_mon_cap_read(s3k_cidx_t mon_idx, s3k_pid_t pid,
56+
s3k_cidx_t idx, s3k_cap_t *cap);
57+
s3k_err_t s3k_try_mon_cap_send(s3k_cidx_t mon_idx, s3k_cidx_t src_idx,
58+
s3k_pid_t dst_pid, s3k_cidx_t dst_idx);
59+
s3k_err_t s3k_try_mon_pmp_load(s3k_cidx_t mon_idx, s3k_pid_t pid,
60+
s3k_cidx_t pmp_idx, s3k_pmp_slot_t pmp_slot);
61+
s3k_err_t s3k_try_mon_pmp_unload(s3k_cidx_t mon_idx, s3k_pid_t pid,
62+
s3k_cidx_t pmp_idx);
63+
s3k_err_t s3k_try_sock_send(s3k_cidx_t sock_idx, const s3k_msg_t *msg);
64+
s3k_reply_t s3k_try_sock_recv(s3k_cidx_t sock_idx, s3k_cidx_t cap_cidx);
65+
s3k_reply_t s3k_try_sock_sendrecv(s3k_cidx_t sock_idx, const s3k_msg_t *msg);

include/s3k/types.h

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
#pragma once
2+
3+
#include <stdbool.h>
4+
#include <stddef.h>
5+
#include <stdint.h>
6+
7+
// Min logarithmic size of a memory slice
8+
#define S3K_MIN_BLOCK_SIZE 12
9+
// Max logarithmic size of a memory slice
10+
#define S3K_MAX_BLOCK_SIZE 27
11+
12+
typedef uint64_t s3k_napot_t;
13+
typedef uint64_t s3k_addr_t;
14+
typedef uint64_t s3k_state_t;
15+
typedef uint16_t s3k_block_t;
16+
typedef uint16_t s3k_chan_t;
17+
typedef uint16_t s3k_time_slot_t;
18+
typedef uint16_t s3k_pid_t;
19+
typedef uint16_t s3k_cidx_t;
20+
typedef uint8_t s3k_hart_t;
21+
typedef uint8_t s3k_tag_t;
22+
typedef uint8_t s3k_rwx_t;
23+
typedef uint8_t s3k_pmp_slot_t;
24+
25+
typedef enum {
26+
S3K_SUCCESS = 0,
27+
S3K_ERR_EMPTY,
28+
S3K_ERR_SRC_EMPTY,
29+
S3K_ERR_DST_OCCUPIED,
30+
S3K_ERR_INVALID_INDEX,
31+
S3K_ERR_INVALID_DERIVATION,
32+
S3K_ERR_INVALID_MONITOR,
33+
S3K_ERR_INVALID_PID,
34+
S3K_ERR_INVALID_STATE,
35+
S3K_ERR_INVALID_PMP,
36+
S3K_ERR_INVALID_SLOT,
37+
S3K_ERR_INVALID_SOCKET,
38+
S3K_ERR_INVALID_SYSCALL,
39+
S3K_ERR_INVALID_REGISTER,
40+
S3K_ERR_INVALID_CAPABILITY,
41+
S3K_ERR_NO_RECEIVER,
42+
S3K_ERR_PREEMPTED,
43+
S3K_ERR_TIMEOUT,
44+
S3K_ERR_SUSPENDED,
45+
} s3k_err_t;
46+
47+
typedef enum {
48+
S3K_PSF_BUSY = 0x1,
49+
S3K_PSF_BLOCKED = 0x2,
50+
S3K_PSF_SUSPENDED = 0x4,
51+
} s3k_state_flag_t;
52+
53+
typedef enum {
54+
S3K_MEM_NONE = 0,
55+
S3K_MEM_R = 0x1,
56+
S3K_MEM_W = 0x2,
57+
S3K_MEM_X = 0x4,
58+
S3K_MEM_RW = S3K_MEM_R | S3K_MEM_W,
59+
S3K_MEM_RX = S3K_MEM_R | S3K_MEM_X,
60+
S3K_MEM_RWX = S3K_MEM_R | S3K_MEM_W | S3K_MEM_X,
61+
} s3k_mem_perm_t;
62+
63+
// IPC Modes
64+
typedef enum {
65+
S3K_IPC_NOYIELD = 0x0, // Non-Yielding Synchronous
66+
S3K_IPC_YIELD = 0x1, // Yielding Synchronous
67+
// S3K_IPC_ASYNC = 2, // Asynchronous
68+
} s3k_ipc_mode_t;
69+
70+
// IPC Permissions
71+
typedef enum {
72+
S3K_IPC_SDATA = 0x1, // Server can send data
73+
S3K_IPC_SCAP = 0x2, // Server can send capabilities
74+
S3K_IPC_CDATA = 0x4, // Client can send data
75+
S3K_IPC_CCAP = 0x8, // Client can send capabilities
76+
} s3k_ipc_perm_t;
77+
78+
// Capability types
79+
typedef enum s3k_capty {
80+
S3K_CAPTY_NONE = 0, ///< No capability.
81+
S3K_CAPTY_TIME = 1, ///< Time Slice capability.
82+
S3K_CAPTY_MEMORY = 2, ///< Memory Slice capability.
83+
S3K_CAPTY_PMP = 3, ///< PMP Frame capability.
84+
S3K_CAPTY_MONITOR = 4, ///< Monitor capability.
85+
S3K_CAPTY_CHANNEL = 5, ///< IPC Channel capability.
86+
S3K_CAPTY_SOCKET = 6, ///< IPC Socket capability.
87+
} s3k_capty_t;
88+
89+
/// Capability description
90+
typedef union s3k_cap {
91+
s3k_capty_t type : 4;
92+
93+
uint64_t raw;
94+
95+
struct {
96+
s3k_capty_t type : 4;
97+
uint16_t _padding : 4;
98+
s3k_hart_t hart;
99+
s3k_time_slot_t bgn;
100+
s3k_time_slot_t mrk;
101+
s3k_time_slot_t end;
102+
} time;
103+
104+
struct {
105+
s3k_capty_t type : 4;
106+
s3k_rwx_t rwx : 3;
107+
bool lck : 1;
108+
s3k_tag_t tag;
109+
s3k_block_t bgn;
110+
s3k_block_t mrk;
111+
s3k_block_t end;
112+
} mem;
113+
114+
struct {
115+
s3k_capty_t type : 4;
116+
s3k_rwx_t rwx : 3;
117+
bool used : 1;
118+
s3k_pmp_slot_t slot;
119+
s3k_napot_t addr : 48;
120+
} pmp;
121+
122+
struct {
123+
s3k_capty_t type : 4;
124+
uint16_t _padding : 12;
125+
s3k_pid_t bgn;
126+
s3k_pid_t mrk;
127+
s3k_pid_t end;
128+
} mon;
129+
130+
struct {
131+
s3k_capty_t type : 4;
132+
uint16_t _padding : 12;
133+
s3k_chan_t bgn;
134+
s3k_chan_t mrk;
135+
s3k_chan_t end;
136+
} chan;
137+
138+
struct {
139+
s3k_capty_t type : 4;
140+
s3k_ipc_mode_t mode : 4;
141+
s3k_ipc_perm_t perm : 8;
142+
s3k_chan_t chan;
143+
uint32_t tag;
144+
} sock;
145+
} s3k_cap_t;
146+
147+
_Static_assert(sizeof(s3k_cap_t) == 8, "s3k_cap_t has the wrong size");
148+
149+
typedef enum {
150+
S3K_REG_PC,
151+
S3K_REG_RA,
152+
S3K_REG_SP,
153+
S3K_REG_GP,
154+
S3K_REG_TP,
155+
S3K_REG_T0,
156+
S3K_REG_T1,
157+
S3K_REG_T2,
158+
S3K_REG_S0,
159+
S3K_REG_S1,
160+
S3K_REG_A0,
161+
S3K_REG_A1,
162+
S3K_REG_A2,
163+
S3K_REG_A3,
164+
S3K_REG_A4,
165+
S3K_REG_A5,
166+
S3K_REG_A6,
167+
S3K_REG_A7,
168+
S3K_REG_S2,
169+
S3K_REG_S3,
170+
S3K_REG_S4,
171+
S3K_REG_S5,
172+
S3K_REG_S6,
173+
S3K_REG_S7,
174+
S3K_REG_S8,
175+
S3K_REG_S9,
176+
S3K_REG_S10,
177+
S3K_REG_S11,
178+
S3K_REG_T3,
179+
S3K_REG_T4,
180+
S3K_REG_T5,
181+
S3K_REG_T6,
182+
S3K_REG_TPC,
183+
S3K_REG_TSP,
184+
S3K_REG_EPC,
185+
S3K_REG_ESP,
186+
S3K_REG_ECAUSE,
187+
S3K_REG_EVAL,
188+
S3K_REG_SERVTIME,
189+
/* Special value for number of registers */
190+
S3K_REG_CNT,
191+
} s3k_reg_t;
192+
193+
typedef struct {
194+
s3k_cidx_t cap_idx;
195+
bool send_cap;
196+
uint64_t data[4];
197+
} s3k_msg_t;
198+
199+
typedef struct {
200+
s3k_err_t err;
201+
uint32_t tag;
202+
s3k_cap_t cap;
203+
uint64_t data[4];
204+
} s3k_reply_t;

include/s3k/util.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#pragma once
2+
#include "s3k/types.h"
3+
4+
s3k_cap_t s3k_mk_time(s3k_hart_t hart, s3k_time_slot_t bgn,
5+
s3k_time_slot_t end);
6+
s3k_cap_t s3k_mk_memory(s3k_addr_t bgn, s3k_addr_t end, s3k_rwx_t rwx);
7+
s3k_cap_t s3k_mk_pmp(s3k_napot_t napot_addr, s3k_rwx_t rwx);
8+
s3k_cap_t s3k_mk_monitor(s3k_pid_t bgn, s3k_pid_t end);
9+
s3k_cap_t s3k_mk_channel(s3k_chan_t bgn, s3k_chan_t end);
10+
s3k_cap_t s3k_mk_socket(s3k_chan_t chan, s3k_ipc_mode_t mode,
11+
s3k_ipc_perm_t perm, uint32_t tag);
12+
13+
bool s3k_is_valid(s3k_cap_t a);
14+
bool s3k_is_parent(s3k_cap_t a, s3k_cap_t b);
15+
bool s3k_is_derivable(s3k_cap_t a, s3k_cap_t b);
16+
17+
void s3k_napot_decode(s3k_napot_t napot_addr, s3k_addr_t *base,
18+
s3k_addr_t *size);
19+
s3k_napot_t s3k_napot_encode(s3k_addr_t base, s3k_addr_t size);
20+
21+
static inline bool s3k_is_ready(s3k_state_t state)
22+
{
23+
return state == 0;
24+
}
25+
26+
static inline bool s3k_is_busy(s3k_state_t state)
27+
{
28+
return state & S3K_PSF_BUSY;
29+
}
30+
31+
static inline bool s3k_is_blocked(s3k_state_t state, s3k_chan_t *chan)
32+
{
33+
*chan = state >> 32;
34+
return state & S3K_PSF_BLOCKED;
35+
}
36+
37+
static inline bool s3k_is_suspended(s3k_state_t state)
38+
{
39+
return state == S3K_PSF_SUSPENDED;
40+
}

meson.build

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
project('libs3k', 'c', version : '1.0')
2+
subdir('src')
3+
incdirs = include_directories('include')
4+
s3k_lib = static_library('s3k', sources, include_directories : incdirs)
5+
s3k_dep = declare_dependency(link_with : s3k_lib, include_directories : incdirs)

src/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sources = files('s3k.c', 'syscall.c')

0 commit comments

Comments
 (0)