Ignore:
File:
1 edited

Legend:

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

    r24abb85d r448e093  
    11/*
    22 * Copyright (c) 2009 Jakub Jermar
     3 * Copyright (c) 2018 CZ.NIC, z.s.p.o.
    34 * All rights reserved.
    45 *
     
    4647#define LSR_TH_READY    0x20
    4748
     49static uint8_t ns16550_reg_read(ns16550_instance_t *inst, ns16550_reg_t reg)
     50{
     51        return pio_read_8(&inst->ns16550[reg << inst->reg_shift]);
     52}
     53
     54static void ns16550_reg_write(ns16550_instance_t *inst, ns16550_reg_t reg,
     55    uint8_t val)
     56{
     57        pio_write_8(&inst->ns16550[reg << inst->reg_shift], val);
     58}
     59
    4860static irq_ownership_t ns16550_claim(irq_t *irq)
    4961{
    5062        ns16550_instance_t *instance = irq->instance;
    51         ns16550_t *dev = instance->ns16550;
    52        
    53         if (pio_read_8(&dev->lsr) & LSR_DATA_READY)
     63
     64        if (ns16550_reg_read(instance, NS16550_REG_LSR) & LSR_DATA_READY)
    5465                return IRQ_ACCEPT;
    5566        else
     
    6071{
    6172        ns16550_instance_t *instance = irq->instance;
    62         ns16550_t *dev = instance->ns16550;
    6373       
    64         if (pio_read_8(&dev->lsr) & LSR_DATA_READY) {
    65                 uint8_t data = pio_read_8(&dev->rbr);
     74        while (ns16550_reg_read(instance, NS16550_REG_LSR) & LSR_DATA_READY) {
     75                uint8_t data = ns16550_reg_read(instance, NS16550_REG_RBR);
    6676                indev_push_character(instance->input, data);
    6777        }
     
    6979
    7080/**< Clear input buffer. */
    71 static void ns16550_clear_buffer(ns16550_t *dev)
     81static void ns16550_clear_buffer(ns16550_instance_t *instance)
    7282{
    73         while ((pio_read_8(&dev->lsr) & LSR_DATA_READY))
    74                 (void) pio_read_8(&dev->rbr);
     83        while (ns16550_reg_read(instance, NS16550_REG_LSR) & LSR_DATA_READY)
     84                (void) ns16550_reg_read(instance, NS16550_REG_RBR);
    7585}
    7686
    77 static void ns16550_sendb(ns16550_t *dev, uint8_t byte)
     87static void ns16550_sendb(ns16550_instance_t *instance, uint8_t byte)
    7888{
    79         while (!(pio_read_8(&dev->lsr) & LSR_TH_READY))
     89        while (!(ns16550_reg_read(instance, NS16550_REG_LSR) & LSR_TH_READY))
    8090                ;
    81         pio_write_8(&dev->thr, byte);
     91        ns16550_reg_write(instance, NS16550_REG_THR, byte);
    8292}
    8393
     
    8898        if ((!instance->parea.mapped) || (console_override)) {
    8999                if (ascii_check(ch))
    90                         ns16550_sendb(instance->ns16550, (uint8_t) ch);
     100                        ns16550_sendb(instance, (uint8_t) ch);
    91101                else
    92                         ns16550_sendb(instance->ns16550, U_SPECIAL);
     102                        ns16550_sendb(instance, U_SPECIAL);
    93103        }
    94104}
     
    101111/** Initialize ns16550.
    102112 *
    103  * @param dev      Addrress of the beginning of the device in I/O space.
    104  * @param inr      Interrupt number.
    105  * @param cir      Clear interrupt function.
    106  * @param cir_arg  First argument to cir.
    107  * @param output   Where to store pointer to the output device
    108  *                 or NULL if the caller is not interested in
    109  *                 writing to the serial port.
     113 * @param dev        Address of the beginning of the device in I/O space.
     114 * @param reg_shift  Spacing between individual register addresses, in log2.
     115 *                   The individual register location is calculated as
     116 *                   `base + (register offset << reg_shift)`.
     117 * @param inr        Interrupt number.
     118 * @param cir        Clear interrupt function.
     119 * @param cir_arg    First argument to cir.
     120 * @param output     Where to store pointer to the output device
     121 *                   or NULL if the caller is not interested in
     122 *                   writing to the serial port.
    110123 *
    111124 * @return Keyboard instance or NULL on failure.
    112125 *
    113126 */
    114 ns16550_instance_t *ns16550_init(ns16550_t *dev, inr_t inr, cir_t cir,
    115     void *cir_arg, outdev_t **output)
     127ns16550_instance_t *ns16550_init(ioport8_t *dev, unsigned reg_shift, inr_t inr,
     128    cir_t cir, void *cir_arg, outdev_t **output)
    116129{
    117130        ns16550_instance_t *instance
     
    119132        if (instance) {
    120133                instance->ns16550 = dev;
     134                instance->reg_shift = reg_shift;
    121135                instance->input = NULL;
    122136                instance->output = NULL;
     
    162176        irq_register(&instance->irq);
    163177       
    164         ns16550_clear_buffer(instance->ns16550);
     178        ns16550_clear_buffer(instance);
    165179       
    166180        /* Enable interrupts */
    167         pio_write_8(&instance->ns16550->ier, IER_ERBFI);
    168         pio_write_8(&instance->ns16550->mcr, MCR_OUT2);
     181        ns16550_reg_write(instance, NS16550_REG_IER, IER_ERBFI);
     182        ns16550_reg_write(instance, NS16550_REG_MCR, MCR_OUT2);
    169183}
    170184
Note: See TracChangeset for help on using the changeset viewer.