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