Ignore:
Timestamp:
2021-08-04T18:52:58Z (3 years ago)
Author:
Marek Benc <dusxmt@…>
Parents:
a977e37
git-author:
Marek Benc <dusxmt@…> (2021-06-23 20:56:38)
git-committer:
Marek Benc <dusxmt@…> (2021-08-04 18:52:58)
Message:

Configure NS16550 transmission format settings on initialization on PCs.

Currently, the NS116550 serial line controller is left with its
settings as it was left by the boot firmware and/or bootloader.
On my computer, this was an invalid configuration, and it left me
with a really slow booting system, since each output character
had to go through the full timeout loop in ns16550_sendb().

This patch adds the necessary bit and register descriptions to configure
the baud rate and transmission settings, as well as configuring them on
post-SMP initialization on ia32 and amd64, currently with values matching
the ns8250 userspace character device driver (38400 baud, 8-bit words,
2 stop bits, no parity).

This could perhaps be changed to be adjustable with a kernel command-line
argument, or through the configuration system.

This change does not affect emulators, since those largely ignore these
settings.

File:
1 edited

Legend:

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

    ra977e37 rec16831  
    132132};
    133133
     134/** Configure ns16550 transmission format.
     135 *
     136 * @param instance   NS 16550 driver instance.
     137 * @param baud_rate  Transmission speed in bits per second, also known as baud,
     138 *                   maximum value is 115200.
     139 * @param lcr_format Line Control Register configuration bits, as defined by
     140 *                   the @c LCR_ macros.  These configure the word width,
     141 *                   parity type, and stop bit count.
     142 */
     143void ns16550_format_set(ns16550_instance_t *instance,
     144    unsigned baud_rate, uint8_t lcr_format)
     145{
     146        uint16_t divisor;
     147
     148        divisor = (uint16_t)(NS156440_CLOCK / baud_rate);
     149        if (divisor == 0)
     150                divisor = 1;  /* Avoid division by zero. */
     151
     152        ns16550_reg_write(instance, NS16550_REG_LCR, LCR_DLAB);
     153        ns16550_reg_write(instance, NS16550_REG_DLL, divisor & 0xFF);
     154        ns16550_reg_write(instance, NS16550_REG_DLH, (divisor >> 8) & 0xFF);
     155        ns16550_reg_write(instance, NS16550_REG_LCR, lcr_format & ~LCR_DLAB);
     156}
     157
    134158/** Initialize ns16550.
    135159 *
Note: See TracChangeset for help on using the changeset viewer.