Changes in kernel/generic/src/console/console.c [1066041:593e023] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/console/console.c
r1066041 r593e023 52 52 #include <errno.h> 53 53 #include <str.h> 54 #include <mm/frame.h> /* SIZE2FRAMES */ 55 #include <mm/slab.h> /* malloc */ 56 57 #define KLOG_PAGES 8 58 #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)) 59 58 60 59 /** Kernel log cyclic buffer */ 61 wchar_t k log[KLOG_LENGTH] __attribute__((aligned(PAGE_SIZE)));60 wchar_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE))); 62 61 63 62 /** Kernel log initialized */ 64 static atomic_t k log_inited = {false};63 static atomic_t kio_inited = {false}; 65 64 66 65 /** First kernel log characters */ 67 static size_t k log_start = 0;66 static size_t kio_start = 0; 68 67 69 68 /** Number of valid kernel log characters */ 70 static size_t k log_len = 0;69 static size_t kio_len = 0; 71 70 72 71 /** Number of stored (not printed) kernel log characters */ 73 static size_t k log_stored = 0;72 static size_t kio_stored = 0; 74 73 75 74 /** Number of stored kernel log characters for uspace */ 76 static size_t k log_uspace = 0;75 static size_t kio_uspace = 0; 77 76 78 77 /** Kernel log spinlock */ 79 SPINLOCK_ STATIC_INITIALIZE_NAME(klog_lock, "klog_lock");80 81 /** Physical memory area used for k logbuffer */82 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; 83 82 84 83 static indev_t stdin_sink; 85 84 static outdev_t stdout_source; 86 85 86 static void stdin_signal(indev_t *, indev_signal_t); 87 87 88 static indev_operations_t stdin_ops = { 88 .poll = NULL 89 .poll = NULL, 90 .signal = stdin_signal 89 91 }; 90 92 91 93 static void stdout_write(outdev_t *, wchar_t); 92 94 static void stdout_redraw(outdev_t *); 95 static void stdout_scroll_up(outdev_t *); 96 static void stdout_scroll_down(outdev_t *); 93 97 94 98 static outdev_operations_t stdout_ops = { 95 99 .write = stdout_write, 96 .redraw = stdout_redraw 100 .redraw = stdout_redraw, 101 .scroll_up = stdout_scroll_up, 102 .scroll_down = stdout_scroll_down 97 103 }; 98 104 … … 114 120 } 115 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 116 136 void stdout_wire(outdev_t *outdev) 117 137 { … … 126 146 static void stdout_write(outdev_t *dev, wchar_t ch) 127 147 { 128 list_foreach(dev->list, cur) { 129 outdev_t *sink = list_get_instance(cur, outdev_t, link); 148 list_foreach(dev->list, link, outdev_t, sink) { 130 149 if ((sink) && (sink->op->write)) 131 150 sink->op->write(sink, ch); … … 135 154 static void stdout_redraw(outdev_t *dev) 136 155 { 137 list_foreach(dev->list, cur) { 138 outdev_t *sink = list_get_instance(cur, outdev_t, link); 156 list_foreach(dev->list, link, outdev_t, sink) { 139 157 if ((sink) && (sink->op->redraw)) 140 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); 141 175 } 142 176 } … … 149 183 * 150 184 */ 151 void k log_init(void)152 { 153 void *faddr = (void *) KA2PA(k log);185 void kio_init(void) 186 { 187 void *faddr = (void *) KA2PA(kio); 154 188 155 189 ASSERT((uintptr_t) faddr % FRAME_SIZE == 0); 156 190 157 k log_parea.pbase = (uintptr_t) faddr;158 k log_parea.frames = SIZE2FRAMES(sizeof(klog));159 k log_parea.unpriv = false;160 k log_parea.mapped = false;161 ddi_parea_register(&k log_parea);162 163 sysinfo_set_item_val("k log.faddr", NULL, (sysarg_t) faddr);164 sysinfo_set_item_val("k log.pages", NULL, KLOG_PAGES);165 166 event_set_unmask_callback(EVENT_K LOG, klog_update);167 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); 168 202 } 169 203 170 204 void grab_console(void) 171 205 { 206 event_notify_1(EVENT_KCONSOLE, false, true); 172 207 bool prev = console_override; 173 208 … … 187 222 { 188 223 console_override = false; 224 event_notify_1(EVENT_KCONSOLE, false, false); 189 225 } 190 226 191 227 /** Activate kernel console override */ 192 sysarg_t sys_debug_ activate_console(void)228 sysarg_t sys_debug_console(void) 193 229 { 194 230 #ifdef CONFIG_KCONSOLE … … 232 268 } 233 269 } 270 234 271 if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) { 235 272 putchar(ch); … … 250 287 } 251 288 252 void k log_update(void *event)253 { 254 if (!atomic_get(&k log_inited))289 void kio_update(void *event) 290 { 291 if (!atomic_get(&kio_inited)) 255 292 return; 256 293 257 spinlock_lock(&klog_lock); 258 259 if (klog_uspace > 0) { 260 if (event_notify_3(EVENT_KLOG, true, klog_start, klog_len, 261 klog_uspace) == EOK) 262 klog_uspace = 0; 263 } 264 265 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++; 266 353 } 267 354 … … 270 357 bool ordy = ((stdout) && (stdout->op->write)); 271 358 272 spinlock_lock(&klog_lock); 273 274 /* Print charaters stored in kernel log */ 275 if (ordy) { 276 while (klog_stored > 0) { 277 wchar_t tmp = klog[(klog_start + klog_len - klog_stored) % KLOG_LENGTH]; 278 klog_stored--; 279 280 /* 281 * We need to give up the spinlock for 282 * the physical operation of writting out 283 * the character. 284 */ 285 spinlock_unlock(&klog_lock); 286 stdout->op->write(stdout, tmp); 287 spinlock_lock(&klog_lock); 288 } 289 } 290 291 /* Store character in the cyclic kernel log */ 292 klog[(klog_start + klog_len) % KLOG_LENGTH] = ch; 293 if (klog_len < KLOG_LENGTH) 294 klog_len++; 295 else 296 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(); 297 365 298 366 if (!ordy) { 299 if (klog_stored < klog_len)300 klog_stored++;301 }302 303 /* The character is stored for uspace */304 if (klog_uspace < klog_len)305 klog_uspace++;306 307 spinlock_unlock(&klog_lock);308 309 if (ordy) {310 /*311 * Output the character. In this case312 * it should be no longer buffered.313 */314 stdout->op->write(stdout, ch);315 } else {316 367 /* 317 368 * No standard output routine defined yet. … … 329 380 /* Force notification on newline */ 330 381 if (ch == '\n') 331 k log_update(NULL);382 kio_update(NULL); 332 383 } 333 384 … … 337 388 * 338 389 */ 339 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) 340 391 { 341 392 char *data; 342 393 int rc; 343 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 344 406 if (size > PAGE_SIZE) 345 407 return (sysarg_t) ELIMIT; … … 357 419 data[size] = 0; 358 420 359 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 360 434 free(data); 361 } else 362 klog_update(NULL); 363 435 } 436 364 437 return size; 365 438 }
Note:
See TracChangeset
for help on using the changeset viewer.