PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
fb.c
Go to the documentation of this file.
2
3#include <kernel/fs/devfs.h>
4#include <kernel/fs/file.h>
5#include <kernel/fs/vfs.h>
6#include <kernel/log/log.h>
8
9#include <assert.h>
10#include <stdatomic.h>
11#include <stdio.h>
12#include <stdlib.h>
13
14static atomic_uint64_t newId = ATOMIC_VAR_INIT(0);
15
16static dentry_t* dir = NULL;
17
18static size_t fb_name_read(file_t* file, void* buffer, size_t count, size_t* offset)
19{
20 fb_t* fb = file->vnode->data;
21 assert(fb != NULL);
22
23 uint64_t length = strlen(fb->name);
24 return BUFFER_READ(buffer, count, offset, fb->name, length);
25}
26
29};
30
31static size_t fb_data_read(file_t* file, void* buffer, size_t count, size_t* offset)
32{
33 fb_t* fb = file->vnode->data;
34 assert(fb != NULL);
35
36 if (fb->ops->read == NULL)
37 {
38 errno = EINVAL;
39 return ERR;
40 }
41
42 return fb->ops->read(fb, buffer, count, offset);
43}
44
45static size_t fb_data_write(file_t* file, const void* buffer, size_t count, size_t* offset)
46{
47 fb_t* fb = file->vnode->data;
48 assert(fb != NULL);
49
50 if (fb->ops->write == NULL)
51 {
52 errno = EINVAL;
53 return ERR;
54 }
55
56 return fb->ops->write(fb, buffer, count, offset);
57}
58
59static void* fb_data_mmap(file_t* file, void* addr, size_t length, size_t* offset, pml_flags_t flags)
60{
61 fb_t* fb = file->vnode->data;
62 assert(fb != NULL);
63
64 if (fb->ops->mmap == NULL)
65 {
66 errno = EINVAL;
67 return NULL;
68 }
69
70 return fb->ops->mmap(fb, addr, length, offset, flags);
71}
72
75 .write = fb_data_write,
76 .mmap = fb_data_mmap,
77};
78
79static size_t fb_info_read(file_t* file, void* buffer, size_t count, size_t* offset)
80{
81 fb_t* fb = file->vnode->data;
82 assert(fb != NULL);
83
84 if (fb->ops->info == NULL)
85 {
86 errno = EINVAL;
87 return ERR;
88 }
89
90 fb_info_t info = {0};
91 if (fb->ops->info(fb, &info) == ERR)
92 {
93 return ERR;
94 }
95
96 char string[256];
97 int length =
98 snprintf(string, sizeof(string), "%llu %llu %llu %s", info.width, info.height, info.pitch, info.format);
99 if (length < 0)
100 {
101 errno = EIO;
102 return ERR;
103 }
104
105 if ((size_t)length >= sizeof(string))
106 {
108 return ERR;
109 }
110
111 return BUFFER_READ(buffer, count, offset, string, (size_t)length);
112}
113
116};
117
118static void fb_dir_cleanup(vnode_t* vnode)
119{
120 fb_t* fb = vnode->data;
121
122 if (fb->ops->cleanup != NULL)
123 {
124 fb->ops->cleanup(fb);
125 }
126
127 free(fb);
128}
129
133
134fb_t* fb_new(const char* name, const fb_ops_t* ops, void* data)
135{
136 if (name == NULL || ops == NULL)
137 {
138 errno = EINVAL;
139 return NULL;
140 }
141
142 if (dir == NULL)
143 {
144 dir = devfs_dir_new(NULL, "fb", NULL, NULL);
145 if (dir == NULL)
146 {
147 return NULL;
148 }
149 }
150
151 fb_t* fb = malloc(sizeof(fb_t));
152 if (fb == NULL)
153 {
154 errno = ENOMEM;
155 return NULL;
156 }
157 strncpy(fb->name, name, sizeof(fb->name));
158 fb->name[sizeof(fb->name) - 1] = '\0';
159 fb->ops = ops;
160 fb->data = data;
161 fb->dir = NULL;
162 list_init(&fb->files);
163
164 char id[MAX_NAME];
165 if (snprintf(id, MAX_NAME, "%llu", atomic_fetch_add(&newId, 1)) < 0)
166 {
167 free(fb);
168 errno = EIO;
169 return NULL;
170 }
171
173 if (fb->dir == NULL)
174 {
175 free(fb);
176 return NULL;
177 }
178
180 {
181 .name = "name",
182 .vnodeOps = NULL,
183 .fileOps = &nameOps,
184 .data = fb,
185 },
186 {
187 .name = "info",
188 .vnodeOps = NULL,
189 .fileOps = &infoOps,
190 .data = fb,
191 },
192 {
193 .name = "data",
194 .vnodeOps = NULL,
195 .fileOps = &dataOps,
196 .data = fb,
197 },
198 {
199 .name = NULL,
200 },
201 };
202
203 if (devfs_files_new(&fb->files, fb->dir, files) == ERR)
204 {
205 UNREF(fb->dir);
206 free(fb);
207 return NULL;
208 }
209
210 LOG_INFO("new framebuffer device `%s` with id '%s'\n", fb->name, id);
211 return fb;
212}
213
215{
216 if (fb == NULL)
217 {
218 return;
219 }
220
221 UNREF(fb->dir);
223}
#define MAX_NAME
Maximum length of names.
Definition MAX_NAME.h:11
#define assert(expression)
Definition assert.h:29
EFI_PHYSICAL_ADDRESS buffer
Definition main.c:237
static fd_t data
Definition dwm.c:21
static dentry_t * dir
Definition fb.c:16
static atomic_uint64_t newId
Definition fb.c:14
static void * fb_data_mmap(file_t *file, void *addr, size_t length, size_t *offset, pml_flags_t flags)
Definition fb.c:59
static size_t fb_name_read(file_t *file, void *buffer, size_t count, size_t *offset)
Definition fb.c:18
static size_t fb_info_read(file_t *file, void *buffer, size_t count, size_t *offset)
Definition fb.c:79
static file_ops_t dataOps
Definition fb.c:73
static file_ops_t nameOps
Definition fb.c:27
static file_ops_t infoOps
Definition fb.c:114
static size_t fb_data_read(file_t *file, void *buffer, size_t count, size_t *offset)
Definition fb.c:31
static vnode_ops_t dirVnodeOps
Definition fb.c:130
static size_t fb_data_write(file_t *file, const void *buffer, size_t count, size_t *offset)
Definition fb.c:45
static void fb_dir_cleanup(vnode_t *vnode)
Definition fb.c:118
fb_t * fb_new(const char *name, const fb_ops_t *ops, void *data)
Allocate and initialize a new framebuffer.
Definition fb.c:134
void fb_free(fb_t *fb)
Frees a framebuffer.
Definition fb.c:214
static fb_ops_t ops
Definition gop.c:80
static fb_t * fb
Definition gop.c:28
uint64_t devfs_files_new(list_t *out, dentry_t *parent, const devfs_file_desc_t *descs)
Create multiple files in a devfs directory.
Definition devfs.c:195
void devfs_files_free(list_t *files)
Free all files in a list created by devfs_files_new().
Definition devfs.c:250
dentry_t * devfs_dir_new(dentry_t *parent, const char *name, const vnode_ops_t *vnodeOps, void *data)
Create a new directory inside a mounted devfs instance.
Definition devfs.c:82
#define LOG_INFO(format,...)
Definition log.h:91
#define UNREF(ptr)
Decrement reference count.
Definition ref.h:109
#define BUFFER_READ(buffer, count, offset, src, size)
Helper macros for implementing file operations dealing with simple buffers.
Definition vfs.h:209
#define EINVAL
Invalid argument.
Definition errno.h:142
#define ENOMEM
Out of memory.
Definition errno.h:92
#define EIO
I/O error.
Definition errno.h:57
#define EOVERFLOW
Value too large for defined data type.
Definition errno.h:402
#define errno
Error number variable.
Definition errno.h:27
static void list_init(list_t *list)
Initializes a list.
Definition list.h:185
#define NULL
Pointer error value.
Definition NULL.h:25
#define ERR
Integer error value.
Definition ERR.h:17
static uint64_t offset
Definition screen.c:19
static list_t files
Definition file.c:9
static const path_flag_t flags[]
Definition path.c:47
static atomic_long count
Definition main.c:11
#define ATOMIC_VAR_INIT(value)
Definition stdatomic.h:74
#define atomic_fetch_add(object, operand)
Definition stdatomic.h:283
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC int snprintf(char *_RESTRICT s, size_t n, const char *_RESTRICT format,...)
Definition snprintf.c:3
_PUBLIC void * malloc(size_t size)
Definition malloc.c:5
_PUBLIC void free(void *ptr)
Definition free.c:11
_PUBLIC char * strncpy(char *_RESTRICT s1, const char *_RESTRICT s2, size_t n)
Definition strncpy.c:3
_PUBLIC size_t strlen(const char *s)
Definition strlen.c:3
Directory entry structure.
Definition dentry.h:155
Descriptor for batch file creation.
Definition devfs.h:73
Framebuffer information.
Definition fb.h:51
char format[MAX_PATH]
Definition fb.h:55
size_t height
Definition fb.h:53
size_t pitch
Definition fb.h:54
size_t width
Definition fb.h:52
Framebuffer operations.
Definition fb.h:63
size_t(* write)(fb_t *fb, const void *buffer, size_t count, size_t *offset)
Definition fb.h:66
void(* cleanup)(fb_t *fb)
Definition fb.h:68
size_t(* read)(fb_t *fb, void *buffer, size_t count, size_t *offset)
Definition fb.h:65
void *(* mmap)(fb_t *fb, void *address, size_t length, size_t *offset, pml_flags_t flags)
Definition fb.h:67
uint64_t(* info)(fb_t *fb, fb_info_t *info)
Definition fb.h:64
Framebuffer structure.
Definition fb.h:76
void * data
Definition fb.h:79
dentry_t * dir
Definition fb.h:80
char name[MAX_PATH]
Definition fb.h:77
const fb_ops_t * ops
Definition fb.h:78
list_t files
Definition fb.h:81
File operations structure.
Definition file.h:54
size_t(* read)(file_t *file, void *buffer, size_t count, size_t *offset)
Definition file.h:58
File structure.
Definition file.h:39
vnode_t * vnode
Definition file.h:43
A entry in a page table without a specified address or callback ID.
vnode operations structure.
Definition vnode.h:69
void(* cleanup)(vnode_t *vnode)
Cleanup function called when the vnode is being freed.
Definition vnode.h:138
vnode structure.
Definition vnode.h:48
void * data
Filesystem defined data.
Definition vnode.h:52