Changes in kernel/generic/src/console/console.c [6afc9d7:11527051] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/console/console.c
r6afc9d7 r11527051 52 52 #include <errno.h> 53 53 #include <str.h> 54 #include <abi/kio.h> 55 #include <mm/frame.h> /* SIZE2FRAMES */ 56 #include <mm/slab.h> /* malloc */ 57 58 #define KIO_PAGES 8 59 #define KIO_LENGTH (KIO_PAGES * PAGE_SIZE / sizeof(wchar_t)) 54 #include <abi/klog.h> 55 56 #define KLOG_PAGES 8 57 #define KLOG_LENGTH (KLOG_PAGES * PAGE_SIZE / sizeof(wchar_t)) 60 58 61 59 /** Kernel log cyclic buffer */ 62 wchar_t k io[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));60 wchar_t klog[KLOG_LENGTH] __attribute__((aligned(PAGE_SIZE))); 63 61 64 62 /** Kernel log initialized */ 65 static atomic_t k io_inited = {false};63 static atomic_t klog_inited = {false}; 66 64 67 65 /** First kernel log characters */ 68 static size_t k io_start = 0;66 static size_t klog_start = 0; 69 67 70 68 /** Number of valid kernel log characters */ 71 static size_t k io_len = 0;69 static size_t klog_len = 0; 72 70 73 71 /** Number of stored (not printed) kernel log characters */ 74 static size_t k io_stored = 0;72 static size_t klog_stored = 0; 75 73 76 74 /** Number of stored kernel log characters for uspace */ 77 static size_t k io_uspace = 0;75 static size_t klog_uspace = 0; 78 76 79 77 /** Kernel log spinlock */ 80 SPINLOCK_ INITIALIZE_NAME(kio_lock, "kio_lock");81 82 /** Physical memory area used for k iobuffer */83 static parea_t k io_parea;78 SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "klog_lock"); 79 80 /** Physical memory area used for klog buffer */ 81 static parea_t klog_parea; 84 82 85 83 static indev_t stdin_sink; 86 84 static outdev_t stdout_source; 87 85 88 static void stdin_signal(indev_t *, indev_signal_t);89 90 86 static indev_operations_t stdin_ops = { 91 .poll = NULL, 92 .signal = stdin_signal 87 .poll = NULL 93 88 }; 94 89 95 90 static void stdout_write(outdev_t *, wchar_t); 96 91 static void stdout_redraw(outdev_t *); 97 static void stdout_scroll_up(outdev_t *);98 static void stdout_scroll_down(outdev_t *);99 92 100 93 static outdev_operations_t stdout_ops = { 101 94 .write = stdout_write, 102 .redraw = stdout_redraw, 103 .scroll_up = stdout_scroll_up, 104 .scroll_down = stdout_scroll_down 95 .redraw = stdout_redraw 105 96 }; 106 97 … … 122 113 } 123 114 124 static void stdin_signal(indev_t *indev, indev_signal_t signal)125 {126 switch (signal) {127 case INDEV_SIGNAL_SCROLL_UP:128 if (stdout != NULL)129 stdout_scroll_up(stdout);130 break;131 case INDEV_SIGNAL_SCROLL_DOWN:132 if (stdout != NULL)133 stdout_scroll_down(stdout);134 break;135 }136 }137 138 115 void stdout_wire(outdev_t *outdev) 139 116 { … … 148 125 static void stdout_write(outdev_t *dev, wchar_t ch) 149 126 { 150 list_foreach(dev->list, link, outdev_t, sink) { 127 list_foreach(dev->list, cur) { 128 outdev_t *sink = list_get_instance(cur, outdev_t, link); 151 129 if ((sink) && (sink->op->write)) 152 130 sink->op->write(sink, ch); … … 156 134 static void stdout_redraw(outdev_t *dev) 157 135 { 158 list_foreach(dev->list, link, outdev_t, sink) { 136 list_foreach(dev->list, cur) { 137 outdev_t *sink = list_get_instance(cur, outdev_t, link); 159 138 if ((sink) && (sink->op->redraw)) 160 139 sink->op->redraw(sink); 161 }162 }163 164 static void stdout_scroll_up(outdev_t *dev)165 {166 list_foreach(dev->list, link, outdev_t, sink) {167 if ((sink) && (sink->op->scroll_up))168 sink->op->scroll_up(sink);169 }170 }171 172 static void stdout_scroll_down(outdev_t *dev)173 {174 list_foreach(dev->list, link, outdev_t, sink) {175 if ((sink) && (sink->op->scroll_down))176 sink->op->scroll_down(sink);177 140 } 178 141 } … … 185 148 * 186 149 */ 187 void k io_init(void)188 { 189 void *faddr = (void *) KA2PA(k io);150 void klog_init(void) 151 { 152 void *faddr = (void *) KA2PA(klog); 190 153 191 154 ASSERT((uintptr_t) faddr % FRAME_SIZE == 0); 192 155 193 k io_parea.pbase = (uintptr_t) faddr;194 k io_parea.frames = SIZE2FRAMES(sizeof(kio));195 k io_parea.unpriv = false;196 k io_parea.mapped = false;197 ddi_parea_register(&k io_parea);198 199 sysinfo_set_item_val("k io.faddr", NULL, (sysarg_t) faddr);200 sysinfo_set_item_val("k io.pages", NULL, KIO_PAGES);201 202 event_set_unmask_callback(EVENT_K IO, kio_update);203 atomic_set(&k io_inited, true);156 klog_parea.pbase = (uintptr_t) faddr; 157 klog_parea.frames = SIZE2FRAMES(sizeof(klog)); 158 klog_parea.unpriv = false; 159 klog_parea.mapped = false; 160 ddi_parea_register(&klog_parea); 161 162 sysinfo_set_item_val("klog.faddr", NULL, (sysarg_t) faddr); 163 sysinfo_set_item_val("klog.pages", NULL, KLOG_PAGES); 164 165 event_set_unmask_callback(EVENT_KLOG, klog_update); 166 atomic_set(&klog_inited, true); 204 167 } 205 168 206 169 void grab_console(void) 207 170 { 208 event_notify_1(EVENT_KCONSOLE, false, true);209 171 bool prev = console_override; 210 172 … … 224 186 { 225 187 console_override = false; 226 event_notify_1(EVENT_KCONSOLE, false, false);227 188 } 228 189 229 190 /** Activate kernel console override */ 230 sysarg_t sys_debug_ console(void)191 sysarg_t sys_debug_activate_console(void) 231 192 { 232 193 #ifdef CONFIG_KCONSOLE … … 270 231 } 271 232 } 272 273 233 if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) { 274 234 putchar(ch); … … 289 249 } 290 250 291 void k io_update(void *event)292 { 293 if (!atomic_get(&k io_inited))251 void klog_update(void *event) 252 { 253 if (!atomic_get(&klog_inited)) 294 254 return; 295 255 296 spinlock_lock(&kio_lock); 297 298 if (kio_uspace > 0) { 299 if (event_notify_3(EVENT_KIO, true, kio_start, kio_len, 300 kio_uspace) == EOK) 301 kio_uspace = 0; 302 } 303 304 spinlock_unlock(&kio_lock); 305 } 306 307 /** Flush characters that are stored in the output buffer 308 * 309 */ 310 void kio_flush(void) 256 spinlock_lock(&klog_lock); 257 258 if (klog_uspace > 0) { 259 if (event_notify_3(EVENT_KLOG, true, klog_start, klog_len, 260 klog_uspace) == EOK) 261 klog_uspace = 0; 262 } 263 264 spinlock_unlock(&klog_lock); 265 } 266 267 void putchar(const wchar_t ch) 311 268 { 312 269 bool ordy = ((stdout) && (stdout->op->write)); 313 270 314 if (!ordy) 315 return; 316 317 spinlock_lock(&kio_lock); 318 319 /* Print characters that weren't printed earlier */ 320 while (kio_stored > 0) { 321 wchar_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH]; 322 kio_stored--; 323 271 spinlock_lock(&klog_lock); 272 273 /* Print charaters stored in kernel log */ 274 if (ordy) { 275 while (klog_stored > 0) { 276 wchar_t tmp = klog[(klog_start + klog_len - klog_stored) % KLOG_LENGTH]; 277 klog_stored--; 278 279 /* 280 * We need to give up the spinlock for 281 * the physical operation of writting out 282 * the character. 283 */ 284 spinlock_unlock(&klog_lock); 285 stdout->op->write(stdout, tmp); 286 spinlock_lock(&klog_lock); 287 } 288 } 289 290 /* Store character in the cyclic kernel log */ 291 klog[(klog_start + klog_len) % KLOG_LENGTH] = ch; 292 if (klog_len < KLOG_LENGTH) 293 klog_len++; 294 else 295 klog_start = (klog_start + 1) % KLOG_LENGTH; 296 297 if (!ordy) { 298 if (klog_stored < klog_len) 299 klog_stored++; 300 } 301 302 /* The character is stored for uspace */ 303 if (klog_uspace < klog_len) 304 klog_uspace++; 305 306 spinlock_unlock(&klog_lock); 307 308 if (ordy) { 324 309 /* 325 * We need to give up the spinlock for 326 * the physical operation of writing out 327 * the character. 310 * Output the character. In this case 311 * it should be no longer buffered. 328 312 */ 329 spinlock_unlock(&kio_lock); 330 stdout->op->write(stdout, tmp); 331 spinlock_lock(&kio_lock); 332 } 333 334 spinlock_unlock(&kio_lock); 335 } 336 337 /** Put a character into the output buffer. 338 * 339 * The caller is required to hold kio_lock 340 */ 341 void kio_push_char(const wchar_t ch) 342 { 343 kio[(kio_start + kio_len) % KIO_LENGTH] = ch; 344 if (kio_len < KIO_LENGTH) 345 kio_len++; 346 else 347 kio_start = (kio_start + 1) % KIO_LENGTH; 348 349 if (kio_stored < kio_len) 350 kio_stored++; 351 352 /* The character is stored for uspace */ 353 if (kio_uspace < kio_len) 354 kio_uspace++; 355 } 356 357 void putchar(const wchar_t ch) 358 { 359 bool ordy = ((stdout) && (stdout->op->write)); 360 361 spinlock_lock(&kio_lock); 362 kio_push_char(ch); 363 spinlock_unlock(&kio_lock); 364 365 /* Output stored characters */ 366 kio_flush(); 367 368 if (!ordy) { 313 stdout->op->write(stdout, ch); 314 } else { 369 315 /* 370 316 * No standard output routine defined yet. … … 382 328 /* Force notification on newline */ 383 329 if (ch == '\n') 384 k io_update(NULL);330 klog_update(NULL); 385 331 } 386 332 … … 390 336 * 391 337 */ 392 sysarg_t sys_k io(int cmd, const void *buf, size_t size)338 sysarg_t sys_klog(int cmd, const void *buf, size_t size) 393 339 { 394 340 char *data; … … 396 342 397 343 switch (cmd) { 398 case K IO_UPDATE:399 k io_update(NULL);344 case KLOG_UPDATE: 345 klog_update(NULL); 400 346 return EOK; 401 case K IO_WRITE:402 case K IO_COMMAND:347 case KLOG_WRITE: 348 case KLOG_COMMAND: 403 349 break; 404 350 default: … … 422 368 423 369 switch (cmd) { 424 case K IO_WRITE:370 case KLOG_WRITE: 425 371 printf("%s", data); 426 372 break; 427 case K IO_COMMAND:373 case KLOG_COMMAND: 428 374 if (!stdin) 429 375 break; … … 437 383 } 438 384 439 return EOK;385 return size; 440 386 } 441 387
Note:
See TracChangeset
for help on using the changeset viewer.