62 lines
1.6 KiB
C
62 lines
1.6 KiB
C
/*
|
|
* Copyright (c) 2018 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <devicetree.h>
|
|
#include <kernel.h>
|
|
#include <sys/util.h>
|
|
|
|
/* Super-primitive 8250/16550 serial output-only driver, 115200 8n1 */
|
|
|
|
#define PORT ((io_port_t)DT_REG_ADDR(DT_INST(0, ns16550)))
|
|
|
|
#define REG_IER 0x01 /* Interrupt enable reg. */
|
|
#define REG_LCR 0x03 /* Line control reg. */
|
|
#define REG_MCR 0x04 /* Modem control reg. */
|
|
#define REG_LSR 0x05 /* Line status reg. */
|
|
#define REG_DL_LO 0x00 /* Divisor latch low byte */
|
|
#define REG_DL_HI 0x01 /* Divisor latch high byte */
|
|
|
|
#define IER_DISABLE 0x00
|
|
#define LCR_8N1 (BIT(0) | BIT(1))
|
|
#define LCR_DLAB_SELECT BIT(7)
|
|
#define MCR_DTR BIT(0)
|
|
#define MCR_RTS BIT(1)
|
|
#define LCR_THRE BIT(5)
|
|
|
|
static void serout(int c)
|
|
{
|
|
while (!(sys_in8(PORT + REG_LSR) & LCR_THRE)) {
|
|
}
|
|
sys_out8(c, PORT);
|
|
}
|
|
|
|
static int console_out(int c)
|
|
{
|
|
if (c == '\n') {
|
|
serout('\r');
|
|
}
|
|
serout(c);
|
|
return c;
|
|
}
|
|
|
|
extern void __printk_hook_install(int (*fn)(int));
|
|
|
|
void z_x86_early_serial_init(void)
|
|
{
|
|
/* In fact Qemu already has most of this set up and works by
|
|
* default
|
|
*/
|
|
sys_out8(IER_DISABLE, PORT + REG_IER); /* Disable interrupts */
|
|
sys_out8(LCR_DLAB_SELECT, PORT + REG_LCR); /* DLAB select */
|
|
sys_out8(1, PORT + REG_DL_LO); /* Baud divisor = 1 */
|
|
sys_out8(0, PORT + REG_DL_HI);
|
|
sys_out8(LCR_8N1, PORT + REG_LCR); /* LCR = 8n1 + DLAB off */
|
|
sys_out8(MCR_DTR | MCR_RTS, PORT + REG_MCR);
|
|
|
|
/* Will be replaced later when a real serial driver comes up */
|
|
__printk_hook_install(console_out);
|
|
}
|