Changeset c4cfe4c in mainline for kernel/genarch


Ignore:
Timestamp:
2025-04-17T16:01:16Z (9 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master
Children:
888c06e
Parents:
1db4e2ae (diff), 250a435 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-17 15:51:11)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-17 16:01:16)
Message:

Convert kernel console writing to byte arrays

More buffer per buffer (the original char32_t buffer takes up four
times as much space for the same amount of backlog, which is wasteful).
It is also faster, possibly thanks to bigger chunks being processed in bulk.
Gonna try to figure out if the locking can be improved further.

Also changed to use a syscall for reading KIO buffer from uspace,
to allow better synchronization.

Location:
kernel/genarch/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/drivers/ega/ega.c

    r1db4e2ae rc4cfe4c  
    6969        uint8_t *backbuf;
    7070        ioport8_t *base;
     71        mbstate_t mbstate;
    7172} ega_instance_t;
    7273
    73 static void ega_putuchar(outdev_t *, char32_t);
     74static void ega_write(outdev_t *, const char *, size_t);
    7475static void ega_redraw(outdev_t *);
    7576
    7677static outdev_operations_t egadev_ops = {
    77         .write = ega_putuchar,
     78        .write = ega_write,
    7879        .redraw = ega_redraw,
    7980        .scroll_up = NULL,
     
    538539}
    539540
    540 static void ega_putuchar(outdev_t *dev, char32_t ch)
    541 {
    542         ega_instance_t *instance = (ega_instance_t *) dev->data;
    543 
    544         irq_spinlock_lock(&instance->lock, true);
    545 
     541static void _putuchar(ega_instance_t *instance, char32_t ch)
     542{
    546543        switch (ch) {
    547544        case '\n':
     
    564561        ega_check_cursor(instance);
    565562        ega_move_cursor(instance);
     563}
     564
     565static void ega_write(outdev_t *dev, const char *s, size_t n)
     566{
     567        ega_instance_t *instance = (ega_instance_t *) dev->data;
     568
     569        irq_spinlock_lock(&instance->lock, true);
     570
     571        size_t offset = 0;
     572        char32_t ch;
     573
     574        while ((ch = str_decode_r(s, &offset, n, U_SPECIAL, &instance->mbstate)))
     575                _putuchar(instance, ch);
    566576
    567577        irq_spinlock_unlock(&instance->lock, true);
  • kernel/genarch/src/drivers/ns16550/ns16550.c

    r1db4e2ae rc4cfe4c  
    112112}
    113113
    114 static void ns16550_putuchar(outdev_t *dev, char32_t ch)
     114static void ns16550_write(outdev_t *dev, const char *s, size_t n)
    115115{
    116116        ns16550_instance_t *instance = (ns16550_instance_t *) dev->data;
    117117
    118         if ((!instance->parea.mapped) || (console_override)) {
    119                 if (ch == '\n')
     118        if (instance->parea.mapped && !console_override)
     119                return;
     120
     121        const char *top = s + n;
     122        assert(top >= s);
     123
     124        for (; s < top; s++) {
     125                if (*s == '\n')
    120126                        ns16550_sendb(instance, '\r');
    121127
    122                 if (ascii_check(ch))
    123                         ns16550_sendb(instance, (uint8_t) ch);
    124                 else
    125                         ns16550_sendb(instance, U_SPECIAL);
     128                ns16550_sendb(instance, (uint8_t) *s);
    126129        }
    127130}
    128131
    129132static outdev_operations_t ns16550_ops = {
    130         .write = ns16550_putuchar,
     133        .write = ns16550_write,
    131134        .redraw = NULL
    132135};
  • kernel/genarch/src/drivers/pl011/pl011.c

    r1db4e2ae rc4cfe4c  
    5656}
    5757
    58 static void pl011_uart_putuchar(outdev_t *dev, char32_t ch)
     58static void pl011_uart_write(outdev_t *dev, const char *s, size_t n)
    5959{
    6060        pl011_uart_t *uart = dev->data;
     
    6464                return;
    6565
    66         if (!ascii_check(ch))
    67                 pl011_uart_sendb(uart, U_SPECIAL);
    68         else {
    69                 if (ch == '\n')
    70                         pl011_uart_sendb(uart, (uint8_t) '\r');
    71                 pl011_uart_sendb(uart, (uint8_t) ch);
     66        const char *top = s + n;
     67        assert(top >= s);
     68
     69        for (; s < top; s++) {
     70                if (*s == '\n')
     71                        pl011_uart_sendb(uart, '\r');
     72
     73                pl011_uart_sendb(uart, (uint8_t) *s);
    7274        }
    7375}
    7476
    7577static outdev_operations_t pl011_uart_ops = {
    76         .write = pl011_uart_putuchar,
     78        .write = pl011_uart_write,
    7779        .redraw = NULL,
    7880        .scroll_up = NULL,
  • kernel/genarch/src/fb/fb.c

    r1db4e2ae rc4cfe4c  
    121121        /** Current backbuffer position */
    122122        unsigned int position;
     123
     124        /** Partial character between writes */
     125        mbstate_t mbstate;
    123126} fb_instance_t;
    124127
    125 static void fb_putuchar(outdev_t *, char32_t);
     128static void fb_write(outdev_t *, const char *, size_t);
    126129static void fb_redraw(outdev_t *);
    127130static void fb_scroll_up(outdev_t *);
     
    129132
    130133static outdev_operations_t fbdev_ops = {
    131         .write = fb_putuchar,
     134        .write = fb_write,
    132135        .redraw = fb_redraw,
    133136        .scroll_up = fb_scroll_up,
     
    418421 *
    419422 */
    420 static void fb_putuchar(outdev_t *dev, char32_t ch)
    421 {
    422         fb_instance_t *instance = (fb_instance_t *) dev->data;
    423         spinlock_lock(&instance->lock);
    424 
     423static void _putuchar(fb_instance_t *instance, char32_t ch)
     424{
    425425        switch (ch) {
    426426        case '\n':
    427                 cursor_remove(instance);
    428427                instance->position += instance->cols;
    429428                instance->position -= instance->position % instance->cols;
    430429                break;
    431430        case '\r':
    432                 cursor_remove(instance);
    433431                instance->position -= instance->position % instance->cols;
    434432                break;
    435433        case '\b':
    436                 cursor_remove(instance);
    437434                if (instance->position % instance->cols)
    438435                        instance->position--;
    439436                break;
    440437        case '\t':
    441                 cursor_remove(instance);
    442438                do {
    443439                        glyph_draw(instance, fb_font_glyph(' '),
     
    459455                screen_scroll(instance);
    460456        }
     457}
     458
     459static void fb_write(outdev_t *dev, const char *s, size_t n)
     460{
     461        fb_instance_t *instance = (fb_instance_t *) dev->data;
     462
     463        spinlock_lock(&instance->lock);
     464        cursor_remove(instance);
     465
     466        size_t offset = 0;
     467        char32_t ch;
     468
     469        while ((ch = str_decode_r(s, &offset, n, U_SPECIAL, &instance->mbstate)))
     470                _putuchar(instance, ch);
    461471
    462472        cursor_put(instance);
    463 
    464473        spinlock_unlock(&instance->lock);
    465474}
Note: See TracChangeset for help on using the changeset viewer.