1/*
2 * Copyright 2021, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#ifndef _VIRTIO_H_
8#define _VIRTIO_H_
9
10
11#include <virtio_defs.h>
12#include <util/DoublyLinkedList.h>
13
14
15struct VirtioResources {
16	VirtioRegs* volatile regs;
17	size_t regsSize;
18	int32_t irq;
19};
20
21enum IOState {
22	ioStateInactive,
23	ioStatePending,
24	ioStateDone,
25	ioStateFailed,
26};
27
28enum IOOperation {
29	ioOpRead,
30	ioOpWrite,
31};
32
33struct IORequest {
34	IOState state;
35	IOOperation op;
36	void* buf;
37	size_t len;
38	IORequest* next;
39
40	IORequest(IOOperation op, void* buf, size_t len): state(ioStateInactive),
41		op(op), buf(buf), len(len), next(NULL) {}
42};
43
44class VirtioDevice : public DoublyLinkedListLinkImpl<VirtioDevice> {
45private:
46	VirtioRegs* volatile fRegs;
47	size_t fQueueLen;
48	VirtioDesc* volatile fDescs;
49	VirtioAvail* volatile fAvail;
50	VirtioUsed* volatile fUsed;
51	uint32_t* fFreeDescs;
52	uint32_t fLastUsed;
53	IORequest** fReqs;
54
55	int32_t AllocDesc();
56	void FreeDesc(int32_t idx);
57
58public:
59	VirtioDevice(const VirtioResources& devRes);
60	~VirtioDevice();
61	inline VirtioRegs* volatile Regs() {return fRegs;}
62	void ScheduleIO(IORequest** reqs, uint32 cnt);
63	void ScheduleIO(IORequest* req);
64	IORequest* ConsumeIO();
65	IORequest* WaitIO();
66};
67
68
69void virtio_init();
70void virtio_fini();
71void virtio_register(addr_t base, size_t len, uint32 irq);
72
73VirtioResources* ThisVirtioDev(uint32 deviceId, int n);
74
75int virtio_input_get_key();
76int virtio_input_wait_for_key();
77
78#endif	// _VIRTIO_H_
79