Skip to content

Commit 48a3d81

Browse files
committed
everywhere: New IPC framework and IRQ delivery.
1 parent ab53b6a commit 48a3d81

24 files changed

Lines changed: 798 additions & 628 deletions

File tree

meta/plugins/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from cutekit import ensure
22

3-
ensure((0, 10, 0))
3+
ensure((0, 11, 0))
44

55
from . import start, tools # noqa E402, F401: Needed for side effect

src/kernel/hjert-api/api.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ struct Object {
4848
_drop(_cap).unwrap();
4949
}
5050

51+
Res<Hj::Cap> dup(Hj::Cap dest) {
52+
Hj::Cap out;
53+
try$(Hj::_dup(dest, &out, _cap));
54+
return Ok(out);
55+
}
56+
5157
Res<> drop() {
5258
try$(_drop(_cap));
5359
_cap = {};
@@ -258,6 +264,28 @@ struct Channel : Object {
258264
}
259265
};
260266

267+
struct Pipe : Object {
268+
using Props = PipeProps;
269+
270+
using Object::Object;
271+
272+
static Res<Pipe> create(Cap dest, usize bufLen) {
273+
return create<Pipe>(dest, bufLen);
274+
}
275+
276+
Res<usize> write(Bytes buf) {
277+
usize bufLen = buf.len();
278+
try$(_write(_cap, buf.buf(), &bufLen));
279+
return Ok(bufLen);
280+
}
281+
282+
Res<usize> read(MutBytes buf) {
283+
usize bufLen = buf.len();
284+
try$(_read(_cap, buf.buf(), &bufLen));
285+
return Ok(bufLen);
286+
}
287+
};
288+
261289
struct Irq : Object {
262290
using Props = IrqProps;
263291

@@ -266,6 +294,14 @@ struct Irq : Object {
266294
static Res<Irq> create(Cap dest, usize irq) {
267295
return create<Irq>(dest, irq);
268296
}
297+
298+
Res<> eoi() {
299+
return _eoi(cap());
300+
}
301+
302+
Res<> bind(Cap pipeCap) {
303+
return _bind(cap(), pipeCap);
304+
}
269305
};
270306

271307
struct Listener : Object {

src/kernel/hjert-api/syscalls.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,20 @@ Res<> _poll(Cap cap, Event* ev, usize evCap, usize* evLen, Instant until) {
140140
return _syscall(Syscall::POLL, cap.raw(), (Arg)ev, evCap, (usize)evLen, until.val());
141141
}
142142

143-
Res<> _write(Cap cap, u8 const* buf, usize bufLen) {
144-
return _syscall(Syscall::WRITE, cap.raw(), (Arg)buf, bufLen);
143+
Res<> _write(Cap cap, u8 const* buf, usize* bufLen) {
144+
return _syscall(Syscall::WRITE, cap.raw(), (Arg)buf, (Arg)bufLen);
145145
}
146146

147147
Res<> _read(Cap cap, u8* buf, usize* bufLen) {
148148
return _syscall(Syscall::READ, cap.raw(), (Arg)buf, (Arg)bufLen);
149149
}
150150

151+
Res<> _bind(Cap cap, Cap pipeCap) {
152+
return _syscall(Syscall::BIND, cap.raw(), pipeCap.raw());
153+
}
154+
155+
Res<> _eoi(Cap cap) {
156+
return _syscall(Syscall::EOI, cap.raw());
157+
}
158+
151159
} // namespace Hj

src/kernel/hjert-api/syscalls.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,12 @@ Res<> _listen(Cap cap, Cap target, Flags<Sigs> set, Flags<Sigs> unset);
4040

4141
Res<> _poll(Cap cap, Event* ev, usize evCap, usize* evLen, Instant until);
4242

43+
Res<> _write(Cap cap, u8 const* buf, usize* bufLen);
44+
45+
Res<> _read(Cap cap, u8* buf, usize* bufLen);
46+
47+
Res<> _bind(Cap cap, Cap pipeCap);
48+
49+
Res<> _eoi(Cap cap);
50+
4351
} // namespace Hj

src/kernel/hjert-api/types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ static inline char const* toStr(Type type) {
6161
SYSCALL(LISTEN) \
6262
SYSCALL(POLL) \
6363
SYSCALL(READ) \
64-
SYSCALL(WRITE)
64+
SYSCALL(WRITE) \
65+
SYSCALL(BIND) \
66+
SYSCALL(EOI)
6567

6668
// clang-format off
6769

src/kernel/hjert-core/irq.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ Res<Arc<Irq>> Irq::create(usize irq) {
1111
return Ok(makeArc<Irq>(irq));
1212
}
1313

14-
void Irq::trigger(usize irqNum) {
14+
void Irq::dispatch(usize irqNum) {
1515
LockScope _{_irqsLock};
1616
for (auto* irq : _irqs) {
17-
if (irq->_irq == irqNum) {
18-
irq->signal(Hj::Sigs::TRIGGERED, Hj::Sigs::NONE);
19-
}
17+
if (irq->_irq == irqNum)
18+
irq->trigger();
2019
}
2120
}
2221

@@ -30,4 +29,23 @@ Irq::~Irq() {
3029
_irqs.removeAll(this);
3130
}
3231

32+
void Irq::trigger() {
33+
ObjectLockScope _{*this};
34+
_signalUnlock(Hj::Sigs::TRIGGERED, Hj::Sigs::NONE);
35+
if (_eoi and _pipe) {
36+
if ((*_pipe)->write({reinterpret_cast<u8*>(&_irq), sizeof(u64)}))
37+
_eoi = false;
38+
}
39+
}
40+
41+
void Irq::bind(Arc<Pipe> pipe) {
42+
ObjectLockScope _{*this};
43+
_pipe = pipe;
44+
}
45+
46+
void Irq::eoi() {
47+
ObjectLockScope _{*this};
48+
_eoi = true;
49+
}
50+
3351
} // namespace Hjert::Core

src/kernel/hjert-core/irq.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
#pragma once
22

33
#include "object.h"
4+
#include "pipe.h"
45

56
namespace Hjert::Core {
67

78
struct Irq : BaseObject<Irq, Hj::Type::IRQ> {
89
usize _irq;
10+
bool _eoi = true;
11+
Opt<Arc<Pipe>> _pipe;
912

1013
static Res<Arc<Irq>> create(usize irq);
1114

12-
static void trigger(usize irq);
15+
static void dispatch(usize irq);
1316

1417
Irq(usize irq);
1518

1619
~Irq() override;
20+
21+
void trigger();
22+
23+
void bind(Arc<Pipe> pipe);
24+
25+
void eoi();
1726
};
1827

1928
} // namespace Hjert::Core

src/kernel/hjert-core/syscalls.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,19 @@ Res<> doRead(Task& self, Hj::Cap cap, UserSlice<MutBytes> buf, User<Hj::Arg> buf
292292
);
293293
}
294294

295+
Res<> doBind(Task& self, Hj::Cap cap, Hj::Cap pipeCap) {
296+
auto irq = try$(self.domain().get<Irq>(cap));
297+
auto pipe = try$(self.domain().get<Pipe>(pipeCap));
298+
irq->bind(pipe);
299+
return Ok();
300+
}
301+
302+
Res<> doEoi(Task& self, Hj::Cap cap) {
303+
auto irq = try$(self.domain().get<Irq>(cap));
304+
irq->eoi();
305+
return Ok();
306+
}
307+
295308
Res<> dispatchSyscall(Task& self, Hj::Syscall id, Hj::Args args) {
296309
switch (id) {
297310
case Hj::Syscall::NOW:
@@ -385,6 +398,21 @@ Res<> dispatchSyscall(Task& self, Hj::Syscall id, Hj::Args args) {
385398
);
386399
}
387400

401+
case Hj::Syscall::BIND: {
402+
return doBind(
403+
self,
404+
Hj::Cap{args[0]},
405+
Hj::Cap{args[1]}
406+
);
407+
}
408+
409+
case Hj::Syscall::EOI: {
410+
return doEoi(
411+
self,
412+
Hj::Cap{args[0]}
413+
);
414+
}
415+
388416
default:
389417
return Error::invalidInput("invalid syscall id");
390418
}

src/kernel/hjert-x86_64/arch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ extern "C" void _intDispatch(usize sp) {
200200
if (irq == 0)
201201
switchTask(1_ms, frame);
202202
else
203-
Core::Irq::trigger(irq);
203+
Core::Irq::dispatch(irq);
204204

205205
_pic.ack(frame.intNo)
206206
.unwrap("pic ack failed");

src/libs/karm-app/skift/app.cpp

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module Karm.App;
77
import Karm.Core;
88
import Karm.Gfx;
99
import Karm.Sys;
10+
import Karm.Ref;
1011
import Strata.Protos;
1112
import Karm.Logger;
1213

@@ -58,22 +59,20 @@ struct SkiftWindow : Window {
5859
};
5960

6061
struct SkiftApplication : Application {
61-
Rc<Sys::Endpoint> _endpoint;
62-
Sys::Port _shell;
62+
Sys::IpcClient _shell;
6363
Map<usize, SkiftWindow*> _windows;
6464
bool _exited = false;
6565

66-
explicit SkiftApplication(Rc<Sys::Endpoint> endpoint, Sys::Port shell)
67-
: _endpoint(endpoint), _shell(shell) {}
66+
explicit SkiftApplication(Sys::IpcClient shell)
67+
: _shell(std::move(shell)) {}
6868

6969
void detachWindow(Strata::IShell::WindowId id) {
70-
(void)_endpoint->send(_shell, Strata::IShell::WindowDestroy{id});
70+
(void)_shell.notify(Strata::IShell::WindowDestroy{id});
7171
_windows.del((usize)id);
7272
}
7373

7474
Async::Task<Rc<Window>> createWindowAsync(WindowProps const& props, Async::CancellationToken ct) override {
75-
auto [id, actual] = co_trya$(_endpoint->callAsync(
76-
_shell,
75+
auto [id, actual] = co_trya$(_shell.callAsync(
7776
Strata::IShell::WindowCreate{
7877
props.size,
7978
App::formFactor
@@ -85,8 +84,7 @@ struct SkiftApplication : Application {
8584

8685
auto surface = co_try$(Strata::Protos::Surface::create(actual.size));
8786

88-
co_trya$(_endpoint->callAsync(
89-
_shell,
87+
co_trya$(_shell.callAsync(
9088
Strata::IShell::WindowAttach{
9189
id,
9290
surface,
@@ -100,7 +98,7 @@ struct SkiftApplication : Application {
10098
co_return Ok(window);
10199
}
102100

103-
Res<> _handleWindowEvent(Sys::Message& message, Rc<Handler> handler) {
101+
Res<> _handleWindowEvent(Sys::IpcMessage& message, Rc<Handler> handler) {
104102
auto [windowId, payload] = try$(message.unpack<Strata::IShell::WindowEvent>());
105103
payload.visit([&]<typename E>(E const& event) {
106104
using T = Meta::RemoveConstVolatileRef<E>;
@@ -114,7 +112,7 @@ struct SkiftApplication : Application {
114112
return Ok();
115113
}
116114

117-
Res<> _handleWindowUpdate(Sys::Message& message, Rc<Handler> handler) {
115+
Res<> _handleWindowUpdate(Sys::IpcMessage& message, Rc<Handler> handler) {
118116
auto [windowId, props] = try$(message.unpack<Strata::IShell::WindowUpdate>());
119117
auto* window = try$(_windows.tryGet(windowId).okOr(Error::invalidInput("no such window")));
120118
// FIXME: We should probably have a separated hello message that pass stuff like color scheme and form factor
@@ -127,7 +125,7 @@ struct SkiftApplication : Application {
127125
}
128126

129127
Res<> _pollMessages(Rc<Handler> handler) {
130-
while (auto maybeMessage = _endpoint->tryRecv()) {
128+
while (auto maybeMessage = _shell.poll()) {
131129
auto& message = maybeMessage.unwrap();
132130
if (message.is<Strata::IShell::WindowEvent>())
133131
try$(_handleWindowEvent(message, handler));
@@ -153,8 +151,7 @@ struct SkiftApplication : Application {
153151

154152
auto newSurface = co_try$(Strata::Protos::Surface::create(size));
155153

156-
co_trya$(_endpoint->callAsync(
157-
_shell,
154+
co_trya$(_shell.callAsync(
158155
Strata::IShell::WindowAttach{
159156
id,
160157
newSurface,
@@ -188,8 +185,7 @@ struct SkiftApplication : Application {
188185
if (not window->_dirty)
189186
continue;
190187

191-
co_trya$(_endpoint->callAsync(
192-
_shell,
188+
co_trya$(_shell.callAsync(
193189
Strata::IShell::WindowFlip{
194190
id,
195191
window->bound(),
@@ -220,30 +216,16 @@ void SkiftWindow::releaseSurface(Slice<Math::Recti>) {
220216

221217
void SkiftWindow::drag(DragEvent e) {
222218
if (e.type == DragEvent::START)
223-
(void)_application._endpoint->send(_application._shell, Strata::IShell::WindowMove{_id});
219+
(void)_application._shell.notify(Strata::IShell::WindowMove{_id});
224220
}
225221

226222
void SkiftWindow::snap(Snap s) {
227-
(void)_application._endpoint->send(_application._shell, Strata::IShell::WindowSnap{_id, s});
223+
(void)_application._shell.notify(Strata::IShell::WindowSnap{_id, s});
228224
}
229225

230-
Async::Task<Rc<Application>> createAppAsync(Sys::Context& ctx, ApplicationProps const&, Async::CancellationToken ct) {
231-
auto endpoint = makeRc<Sys::Endpoint>(
232-
std::move(Sys::useChannel(ctx).con)
233-
);
234-
235-
auto maybeShellPort = co_await endpoint->callAsync(
236-
Sys::Port::BUS,
237-
Strata::IBus::Locate{
238-
"strata-shell"s,
239-
},
240-
ct
241-
);
242-
243-
if (not maybeShellPort)
244-
co_return maybeShellPort.none();
245-
246-
co_return Ok(makeRc<SkiftApplication>(endpoint, maybeShellPort.unwrap()));
226+
Async::Task<Rc<Application>> createAppAsync(Sys::Context&, ApplicationProps const&, Async::CancellationToken ct) {
227+
auto shell = co_trya$(Sys::IpcClient::connectAsync("ipc://strata-shell"_url, ct));
228+
co_return Ok(makeRc<SkiftApplication>(std::move(shell)));
247229
}
248230

249231
} // namespace Karm::App::_Embed

0 commit comments

Comments
 (0)