Ignore:
File:
1 edited

Legend:

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

    ra71c158 rd797054c  
    5656 */
    5757
     58SPINLOCK_INITIALIZE(egalock);
     59static uint32_t ega_cursor;
     60static uint8_t *videoram;
     61static uint8_t *backbuf;
     62static ioport8_t *ega_base;
     63
    5864#define SPACE  0x20
    5965#define STYLE  0x1e
     
    6268#define EMPTY_CHAR  ((STYLE << 8) | SPACE)
    6369
    64 typedef struct {
    65         SPINLOCK_DECLARE(lock);
    66        
    67         uint32_t cursor;
    68         uint8_t *addr;
    69         uint8_t *backbuf;
    70         ioport8_t *base;
    71 } ega_instance_t;
    72 
    73 static void ega_putchar(outdev_t *dev, wchar_t ch, bool silent);
    74 static void ega_redraw(outdev_t *dev);
    75 
    76 static outdev_operations_t egadev_ops = {
    77         .write = ega_putchar,
    78         .redraw = ega_redraw
    79 };
    80 
    8170static uint16_t ega_oem_glyph(const wchar_t ch)
    8271{
     
    438427 * This function takes care of scrolling.
    439428 */
    440 static void ega_check_cursor(ega_instance_t *instance, bool silent)
    441 {
    442         if (instance->cursor < EGA_SCREEN)
     429static void ega_check_cursor(bool silent)
     430{
     431        if (ega_cursor < EGA_SCREEN)
    443432                return;
    444433       
    445         memmove((void *) instance->backbuf,
    446             (void *) (instance->backbuf + EGA_COLS * 2),
     434        memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2),
    447435            (EGA_SCREEN - EGA_COLS) * 2);
    448         memsetw(instance->backbuf + (EGA_SCREEN - EGA_COLS) * 2,
    449             EGA_COLS, EMPTY_CHAR);
     436        memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
    450437       
    451438        if (!silent) {
    452                 memmove((void *) instance->addr,
    453                     (void *) (instance->addr + EGA_COLS * 2),
     439                memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2),
    454440                    (EGA_SCREEN - EGA_COLS) * 2);
    455                 memsetw(instance->addr + (EGA_SCREEN - EGA_COLS) * 2,
    456                     EGA_COLS, EMPTY_CHAR);
     441                memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
    457442        }
    458443       
    459         instance->cursor = instance->cursor - EGA_COLS;
    460 }
    461 
    462 static void ega_show_cursor(ega_instance_t *instance, bool silent)
     444        ega_cursor = ega_cursor - EGA_COLS;
     445}
     446
     447static void ega_show_cursor(bool silent)
    463448{
    464449        if (!silent) {
    465                 pio_write_8(instance->base + EGA_INDEX_REG, 0x0a);
    466                 uint8_t stat = pio_read_8(instance->base + EGA_DATA_REG);
    467                 pio_write_8(instance->base + EGA_INDEX_REG, 0x0a);
    468                 pio_write_8(instance->base + EGA_DATA_REG, stat & (~(1 << 5)));
     450                pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
     451                uint8_t stat = pio_read_8(ega_base + EGA_DATA_REG);
     452                pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
     453                pio_write_8(ega_base + EGA_DATA_REG, stat & (~(1 << 5)));
    469454        }
    470455}
    471456
    472 static void ega_move_cursor(ega_instance_t *instance, bool silent)
     457static void ega_move_cursor(bool silent)
    473458{
    474459        if (!silent) {
    475                 pio_write_8(instance->base + EGA_INDEX_REG, 0x0e);
    476                 pio_write_8(instance->base + EGA_DATA_REG,
    477                     (uint8_t) ((instance->cursor >> 8) & 0xff));
    478                 pio_write_8(instance->base + EGA_INDEX_REG, 0x0f);
    479                 pio_write_8(instance->base + EGA_DATA_REG,
    480                     (uint8_t) (instance->cursor & 0xff));
     460                pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
     461                pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff));
     462                pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
     463                pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff));
    481464        }
    482465}
    483466
    484 static void ega_sync_cursor(ega_instance_t *instance, bool silent)
     467static void ega_sync_cursor(bool silent)
    485468{
    486469        if (!silent) {
    487                 pio_write_8(instance->base + EGA_INDEX_REG, 0x0e);
    488                 uint8_t hi = pio_read_8(instance->base + EGA_DATA_REG);
    489                 pio_write_8(instance->base + EGA_INDEX_REG, 0x0f);
    490                 uint8_t lo = pio_read_8(instance->base + EGA_DATA_REG);
     470                pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
     471                uint8_t hi = pio_read_8(ega_base + EGA_DATA_REG);
     472                pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
     473                uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG);
    491474               
    492                 instance->cursor = (hi << 8) | lo;
     475                ega_cursor = (hi << 8) | lo;
    493476        } else
    494                 instance->cursor = 0;
    495        
    496         if (instance->cursor >= EGA_SCREEN)
    497                 instance->cursor = 0;
    498        
    499         if ((instance->cursor % EGA_COLS) != 0)
    500                 instance->cursor =
    501                     (instance->cursor + EGA_COLS) - instance->cursor % EGA_COLS;
    502        
    503         memsetw(instance->backbuf + instance->cursor * 2,
    504             EGA_SCREEN - instance->cursor, EMPTY_CHAR);
     477                ega_cursor = 0;
     478       
     479        if (ega_cursor >= EGA_SCREEN)
     480                ega_cursor = 0;
     481       
     482        if ((ega_cursor % EGA_COLS) != 0)
     483                ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
     484       
     485        memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
    505486       
    506487        if (!silent)
    507                 memsetw(instance->addr + instance->cursor * 2,
    508                     EGA_SCREEN - instance->cursor, EMPTY_CHAR);
    509        
    510         ega_check_cursor(instance, silent);
    511         ega_move_cursor(instance, silent);
    512         ega_show_cursor(instance, silent);
    513 }
    514 
    515 static void ega_display_char(ega_instance_t *instance, wchar_t ch, bool silent)
     488                memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
     489       
     490        ega_check_cursor(silent);
     491        ega_move_cursor(silent);
     492        ega_show_cursor(silent);
     493}
     494
     495static void ega_display_char(wchar_t ch, bool silent)
    516496{
    517497        uint16_t index = ega_oem_glyph(ch);
     
    527507        }
    528508       
    529         instance->backbuf[instance->cursor * 2] = glyph;
    530         instance->backbuf[instance->cursor * 2 + 1] = style;
     509        backbuf[ega_cursor * 2] = glyph;
     510        backbuf[ega_cursor * 2 + 1] = style;
    531511       
    532512        if (!silent) {
    533                 instance->addr[instance->cursor * 2] = glyph;
    534                 instance->addr[instance->cursor * 2 + 1] = style;
     513                videoram[ega_cursor * 2] = glyph;
     514                videoram[ega_cursor * 2 + 1] = style;
    535515        }
    536516}
    537517
    538 static void ega_putchar(outdev_t *dev, wchar_t ch, bool silent)
    539 {
    540         ega_instance_t *instance = (ega_instance_t *) dev->data;
    541        
    542         ipl_t ipl = interrupts_disable();
    543         spinlock_lock(&instance->lock);
     518static void ega_putchar(outdev_t *dev __attribute__((unused)), wchar_t ch, bool silent)
     519{
     520        ipl_t ipl;
     521       
     522        ipl = interrupts_disable();
     523        spinlock_lock(&egalock);
    544524       
    545525        switch (ch) {
    546526        case '\n':
    547                 instance->cursor = (instance->cursor + EGA_COLS)
    548                     - instance->cursor % EGA_COLS;
     527                ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
    549528                break;
    550529        case '\t':
    551                 instance->cursor = (instance->cursor + 8)
    552                     - instance->cursor % 8;
     530                ega_cursor = (ega_cursor + 8) - ega_cursor % 8;
    553531                break;
    554532        case '\b':
    555                 if (instance->cursor % EGA_COLS)
    556                         instance->cursor--;
     533                if (ega_cursor % EGA_COLS)
     534                        ega_cursor--;
    557535                break;
    558536        default:
    559                 ega_display_char(instance, ch, silent);
    560                 instance->cursor++;
     537                ega_display_char(ch, silent);
     538                ega_cursor++;
    561539                break;
    562540        }
    563         ega_check_cursor(instance, silent);
    564         ega_move_cursor(instance, silent);
    565        
    566         spinlock_unlock(&instance->lock);
     541        ega_check_cursor(silent);
     542        ega_move_cursor(silent);
     543       
     544        spinlock_unlock(&egalock);
    567545        interrupts_restore(ipl);
    568546}
    569547
    570 static void ega_redraw(outdev_t *dev)
    571 {
    572         ega_instance_t *instance = (ega_instance_t *) dev->data;
    573        
    574         ipl_t ipl = interrupts_disable();
    575         spinlock_lock(&instance->lock);
    576        
    577         memcpy(instance->addr, instance->backbuf, EGA_VRAM_SIZE);
    578         ega_move_cursor(instance, silent);
    579         ega_show_cursor(instance, silent);
    580        
    581         spinlock_unlock(&instance->lock);
    582         interrupts_restore(ipl);
    583 }
    584 
    585 outdev_t *ega_init(ioport8_t *base, uintptr_t addr)
    586 {
    587         outdev_t *egadev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
    588         if (!egadev)
    589                 return NULL;
    590        
    591         ega_instance_t *instance = malloc(sizeof(ega_instance_t), FRAME_ATOMIC);
    592         if (!instance) {
    593                 free(egadev);
    594                 return NULL;
    595         }
    596        
    597         outdev_initialize("egadev", egadev, &egadev_ops);
    598         egadev->data = instance;
    599        
    600         spinlock_initialize(&instance->lock, "*ega_lock");
    601        
    602         instance->base = base;
    603         instance->addr = (uint8_t *) hw_map(addr, EGA_VRAM_SIZE);
    604         if (!instance->addr) {
    605                 LOG("Unable to EGA video memory.");
    606                 free(instance);
    607                 free(egadev);
    608                 return NULL;
    609         }
    610        
    611         instance->backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0);
    612         if (!instance->backbuf) {
    613                 LOG("Unable to allocate backbuffer.");
    614                 free(instance);
    615                 free(egadev);
    616                 return NULL;
    617         }
     548static outdev_t ega_console;
     549static outdev_operations_t ega_ops = {
     550        .write = ega_putchar
     551};
     552
     553void ega_init(ioport8_t *base, uintptr_t videoram_phys)
     554{
     555        /* Initialize the software structure. */
     556        ega_base = base;
     557       
     558        backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0);
     559        if (!backbuf)
     560                panic("Unable to allocate backbuffer.");
     561       
     562        videoram = (uint8_t *) hw_map(videoram_phys, EGA_VRAM_SIZE);
    618563       
    619564        /* Synchronize the back buffer and cursor position. */
    620         memcpy(instance->backbuf, instance->addr, EGA_VRAM_SIZE);
    621         ega_sync_cursor(instance, silent);
    622        
    623         if (!fb_exported) {
    624                 /*
    625                  * This is the necessary evil until the userspace driver is entirely
    626                  * self-sufficient.
    627                  */
    628                 sysinfo_set_item_val("fb", NULL, true);
    629                 sysinfo_set_item_val("fb.kind", NULL, 2);
    630                 sysinfo_set_item_val("fb.width", NULL, EGA_COLS);
    631                 sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);
    632                 sysinfo_set_item_val("fb.blinking", NULL, true);
    633                 sysinfo_set_item_val("fb.address.physical", NULL, addr);
    634                
    635                 fb_exported = true;
    636         }
    637        
    638         return egadev;
     565        memcpy(backbuf, videoram, EGA_VRAM_SIZE);
     566        ega_sync_cursor(silent);
     567       
     568        outdev_initialize("ega", &ega_console, &ega_ops);
     569        stdout = &ega_console;
     570       
     571        sysinfo_set_item_val("fb", NULL, true);
     572        sysinfo_set_item_val("fb.kind", NULL, 2);
     573        sysinfo_set_item_val("fb.width", NULL, EGA_COLS);
     574        sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);
     575        sysinfo_set_item_val("fb.blinking", NULL, true);
     576        sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys);
     577}
     578
     579void ega_redraw(void)
     580{
     581        memcpy(videoram, backbuf, EGA_VRAM_SIZE);
     582        ega_move_cursor(silent);
     583        ega_show_cursor(silent);
    639584}
    640585
Note: See TracChangeset for help on using the changeset viewer.