Changeset d5b37b6 in mainline
- Timestamp:
- 2025-04-17T15:14:03Z (5 days ago)
- Branches:
- master
- Children:
- 690ad20
- Parents:
- 571cc2d
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-11 17:35:09)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-17 15:14:03)
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/abi/syscall.h
r571cc2d rd5b37b6 110 110 SYS_DEBUG_CONSOLE, 111 111 112 SYS_KLOG 112 SYS_KLOG, 113 SYS_KIO_READ, 113 114 } syscall_t; 114 115 -
kernel/generic/include/console/console.h
r571cc2d rd5b37b6 36 36 #define KERN_CONSOLE_H_ 37 37 38 #include <typedefs.h>39 #include <print.h>40 38 #include <console/chardev.h> 41 39 #include <synch/spinlock.h> … … 69 67 extern irq_spinlock_t kio_lock; 70 68 69 extern sysarg_t sys_kio_read(uspace_addr_t buf, size_t size, size_t at); 71 70 extern sys_errno_t sys_kio(int cmd, uspace_addr_t buf, size_t size); 72 71 -
kernel/generic/src/console/console.c
r571cc2d rd5b37b6 2 2 * Copyright (c) 2003 Josef Cejka 3 3 * Copyright (c) 2005 Jakub Jermar 4 * Copyright (c) 2025 Jiří Zárevúcky 4 5 * All rights reserved. 5 6 * … … 35 36 36 37 #include <abi/kio.h> 37 #include <arch.h>38 #include <assert.h>39 #include <atomic.h>40 38 #include <console/chardev.h> 41 39 #include <console/console.h> 42 #include <ddi/ddi.h>43 #include <ddi/irq.h>44 40 #include <errno.h> 45 41 #include <ipc/event.h> 46 #include <ipc/irq.h>47 #include <mm/frame.h> /* SIZE2FRAMES */48 42 #include <panic.h> 49 43 #include <preemption.h> 50 #include <proc/t hread.h>44 #include <proc/task.h> 51 45 #include <putchar.h> 52 46 #include <stdatomic.h> 53 47 #include <stdio.h> 54 48 #include <stdlib.h> /* malloc */ 55 #include <str.h>56 49 #include <synch/mutex.h> 57 50 #include <synch/spinlock.h> 58 #include <synch/waitq.h>59 51 #include <syscall/copy.h> 60 52 #include <sysinfo/sysinfo.h> 61 #include <typedefs.h>62 53 63 54 #define KIO_PAGES 8 … … 65 56 66 57 /** Kernel log cyclic buffer */ 67 char32_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));58 static char32_t kio[KIO_LENGTH]; 68 59 69 60 /** Kernel log initialized */ … … 87 78 /** Kernel log spinlock */ 88 79 IRQ_SPINLOCK_INITIALIZE(kio_lock); 89 90 /** Physical memory area used for kio buffer */91 static parea_t kio_parea;92 80 93 81 static indev_t stdin_sink; … … 187 175 188 176 /** Initialize kernel logging facility 189 *190 * The shared area contains kernel cyclic buffer. Userspace application may191 * be notified on new data with indication of position and size192 * of the data within the circular buffer.193 *194 177 */ 195 178 void kio_init(void) 196 179 { 197 void *faddr = (void *) KA2PA(kio);198 199 assert((uintptr_t) faddr % FRAME_SIZE == 0);200 201 ddi_parea_init(&kio_parea);202 kio_parea.pbase = (uintptr_t) faddr;203 kio_parea.frames = SIZE2FRAMES(sizeof(kio));204 kio_parea.unpriv = false;205 kio_parea.mapped = false;206 ddi_parea_register(&kio_parea);207 208 sysinfo_set_item_val("kio.faddr", NULL, (sysarg_t) faddr);209 sysinfo_set_item_val("kio.pages", NULL, KIO_PAGES);210 211 180 event_set_unmask_callback(EVENT_KIO, kio_update); 212 181 atomic_store(&kio_inited, true); … … 332 301 if (ch == '\n') 333 302 kio_update(NULL); 303 } 304 305 /** Reads up to `size` characters from kio buffer starting at character `at`. 306 * 307 * @param size Maximum number of characters that can be stored in buffer. 308 * Values greater than KIO_LENGTH are silently treated as KIO_LENGTH 309 * for the purposes of calculating the return value. 310 * @return Number of characters read. Can be more than `size`. 311 * In that case, `size` characters are written to user buffer 312 * and the extra amount is the number of characters missed. 313 */ 314 sysarg_t sys_kio_read(uspace_addr_t buf, size_t size, size_t at) 315 { 316 errno_t rc; 317 size_t missed = 0; 318 319 irq_spinlock_lock(&kio_lock, true); 320 321 if (at == kio_written) { 322 irq_spinlock_unlock(&kio_lock, true); 323 return 0; 324 } 325 326 size_t readable_chars = kio_written - at; 327 if (readable_chars > KIO_LENGTH) { 328 missed = readable_chars - KIO_LENGTH; 329 readable_chars = KIO_LENGTH; 330 } 331 332 size_t actual_read = min(readable_chars, size); 333 size_t offset = (kio_written - readable_chars) % KIO_LENGTH; 334 335 if (offset + actual_read > KIO_LENGTH) { 336 size_t first = KIO_LENGTH - offset; 337 size_t last = actual_read - first; 338 size_t first_bytes = first * sizeof(kio[0]); 339 size_t last_bytes = last * sizeof(kio[0]); 340 341 rc = copy_to_uspace(buf, &kio[offset], first_bytes); 342 if (rc == EOK) 343 rc = copy_to_uspace(buf + first_bytes, &kio[0], last_bytes); 344 } else { 345 rc = copy_to_uspace(buf, &kio[offset], actual_read * sizeof(kio[0])); 346 } 347 348 irq_spinlock_unlock(&kio_lock, true); 349 350 if (rc != EOK) { 351 log(LF_OTHER, LVL_WARN, 352 "[%s(%" PRIu64 ")] Terminating due to invalid memory buffer" 353 " in SYS_KIO_READ.\n", TASK->name, TASK->taskid); 354 task_kill_self(true); 355 } 356 357 return actual_read + missed; 334 358 } 335 359 -
kernel/generic/src/syscall/syscall.c
r571cc2d rd5b37b6 137 137 138 138 [SYS_KLOG] = (syshandler_t) sys_klog, 139 [SYS_KIO_READ] = (syshandler_t) sys_kio_read, 139 140 }; 140 141 -
uspace/app/kio/kio.c
r571cc2d rd5b37b6 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2025 Jiří Zárevúcky 3 4 * All rights reserved. 4 5 * … … 34 35 */ 35 36 37 #include <_bits/decls.h> 38 #include <libarch/config.h> 36 39 #include <stdio.h> 37 40 #include <async.h> … … 47 50 #include <adt/prodcons.h> 48 51 #include <tinput.h> 52 #include <uchar.h> 49 53 #include <vfs/vfs.h> 50 54 … … 61 65 static prodcons_t pc; 62 66 63 /* Pointer to kio area */64 static char32_t *kio = (char32_t *) AS_AREA_ANY;65 static size_t kio_length;66 67 67 /* Notification mutex */ 68 68 static FIBRIL_MUTEX_INITIALIZE(mtx); 69 69 70 static size_t last_notification; 70 #define READ_BUFFER_SIZE (PAGE_SIZE / sizeof(char32_t)) 71 72 static size_t current_at; 73 static char32_t read_buffer[READ_BUFFER_SIZE]; 71 74 72 75 /** Klog producer … … 151 154 static void kio_notification_handler(ipc_call_t *call, void *arg) 152 155 { 156 size_t kio_written = (size_t) ipc_get_arg1(call); 157 153 158 /* 154 159 * Make sure we process only a single notification … … 159 164 fibril_mutex_lock(&mtx); 160 165 161 size_t kio_written = (size_t) ipc_get_arg1(call); 162 163 /* This works just fine even when kio_written overflows. */ 164 size_t new_chars = kio_written - last_notification; 165 last_notification = kio_written; 166 167 if (new_chars > kio_length) { 168 /* We missed some data. */ 169 // TODO: Send a message with the number of lost bytes to the consumer. 170 new_chars = kio_length; 171 } 172 173 size_t offset = (kio_written - new_chars) % kio_length; 174 175 /* Copy data from the ring buffer */ 176 if (offset + new_chars > kio_length) { 177 size_t split = kio_length - offset; 178 179 producer(split, kio + offset); 180 producer(new_chars - split, kio); 181 } else { 182 producer(new_chars, kio + offset); 166 while (current_at != kio_written) { 167 size_t read = kio_read(read_buffer, READ_BUFFER_SIZE, current_at); 168 if (read == 0) 169 break; 170 171 current_at += read; 172 173 if (read > READ_BUFFER_SIZE) { 174 /* We missed some data. */ 175 // TODO: Send a message with the number of lost characters to the consumer. 176 read = READ_BUFFER_SIZE; 177 } 178 179 producer(read, read_buffer); 183 180 } 184 181 … … 189 186 int main(int argc, char *argv[]) 190 187 { 191 size_t pages;192 errno_t rc = sysinfo_get_value("kio.pages", &pages);193 if (rc != EOK) {194 fprintf(stderr, "%s: Unable to get number of kio pages\n",195 NAME);196 return rc;197 }198 199 uintptr_t faddr;200 rc = sysinfo_get_value("kio.faddr", &faddr);201 if (rc != EOK) {202 fprintf(stderr, "%s: Unable to get kio physical address\n",203 NAME);204 return rc;205 }206 207 size_t size = pages * PAGE_SIZE;208 kio_length = size / sizeof(char32_t);209 210 rc = physmem_map(faddr, pages, AS_AREA_READ | AS_AREA_CACHEABLE,211 (void *) &kio);212 if (rc != EOK) {213 fprintf(stderr, "%s: Unable to map kio\n", NAME);214 return rc;215 }216 217 188 prodcons_initialize(&pc); 218 rc = async_event_subscribe(EVENT_KIO, kio_notification_handler, NULL);189 errno_t rc = async_event_subscribe(EVENT_KIO, kio_notification_handler, NULL); 219 190 if (rc != EOK) { 220 191 fprintf(stderr, "%s: Unable to register kio notifications\n", -
uspace/app/trace/syscalls.c
r571cc2d rd5b37b6 115 115 [SYS_DEBUG_CONSOLE] = { "debug_console", 0, V_ERRNO }, 116 116 117 [SYS_KLOG] = { "klog", 5, V_ERRNO } 117 [SYS_KLOG] = { "klog", 5, V_ERRNO }, 118 [SYS_KIO_READ] = { "kio_read", 3, V_INTEGER }, 118 119 }; 119 120 -
uspace/lib/c/generic/io/kio.c
r571cc2d rd5b37b6 34 34 */ 35 35 36 #include <abi/syscall.h> 36 37 #include <stddef.h> 37 38 #include <libc.h> … … 112 113 } 113 114 115 size_t kio_read(char32_t *buf, size_t n, size_t at) 116 { 117 return __SYSCALL3(SYS_KIO_READ, (sysarg_t) buf, n, at); 118 } 119 114 120 /** Print formatted text to kio. 115 121 * -
uspace/lib/c/include/io/kio.h
r571cc2d rd5b37b6 36 36 #define _LIBC_IO_KIO_H_ 37 37 38 #include <stddef.h>39 #include <stdarg.h>40 #include <io/verify.h>41 38 #include <_bits/errno.h> 42 39 #include <_bits/size_t.h> 40 #include <io/verify.h> 41 #include <stdarg.h> 42 #include <stddef.h> 43 #include <uchar.h> 43 44 44 45 extern void __kio_init(void); … … 50 51 _HELENOS_PRINTF_ATTRIBUTE(1, 2); 51 52 extern int kio_vprintf(const char *, va_list); 53 54 extern size_t kio_read(char32_t *buf, size_t n, size_t at); 52 55 53 56 /*
Note:
See TracChangeset
for help on using the changeset viewer.