1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

revise UART support, determine port via PCI scan

This commit is contained in:
Stefan Lankes 2017-04-03 07:17:46 +02:00
parent dbefde4927
commit d4668dc59e
2 changed files with 50 additions and 52 deletions

View file

@ -97,6 +97,8 @@
#define UART_MCR_RTS 0x02 /* RTS complement */
#define UART_MCR_DTR 0x01 /* DTR complement */
#define DEFAULT_UART_PORT 0xc110
static size_t iobase = 0;
static inline unsigned char read_from_uart(uint32_t off)
@ -167,9 +169,9 @@ static int uart_config(void)
write_to_uart(UART_LCR, lcr);
/*
* set baudrate to 115200
* set baudrate to 9600
*/
uint32_t divisor = 1843200 / 115200;
uint32_t divisor = 1843200 / 9600; //115200;
write_to_uart(UART_DLL, divisor & 0xff);
write_to_uart(UART_DLM, (divisor >> 8) & 0xff);
@ -186,8 +188,32 @@ int uart_init(void)
if (is_uhyve())
return 0;
pci_info_t pci_info;
uint32_t bar = 0;
// Searching for Intel's UART device
if (pci_get_device_info(0x8086, 0x0936, &pci_info, 1) == 0)
goto Lsuccess;
// Searching for Qemu's UART device
if (pci_get_device_info(0x1b36, 0x0002, &pci_info, 1) == 0)
goto Lsuccess;
// Searching for Qemu's 2x UART device (pci-serial-2x)
if (pci_get_device_info(0x1b36, 0x0003, &pci_info, 1) == 0)
goto Lsuccess;
// Searching for Qemu's 4x UART device (pci-serial-4x)
if (pci_get_device_info(0x1b36, 0x0004, &pci_info, 1) == 0)
goto Lsuccess;
// default value of our QEMU configuration
iobase = 0xc110;
iobase = DEFAULT_UART_PORT;
// configure uart
return uart_config();;
Lsuccess:
iobase = pci_info.base[bar];
//irq_install_handler(32+pci_info.irq, uart_handler);
kprintf("UART uses io address 0x%x\n", iobase);
// configure uart
return uart_config();

View file

@ -90,16 +90,15 @@
#define UART_MCR_RTS 0x02 /* RTS complement */
#define UART_MCR_DTR 0x01 /* DTR complement */
static uint8_t mmio = 0;
#define DEFAULT_UART_PORT 0 //0xc110
static size_t iobase = 0;
static inline unsigned char read_from_uart(uint32_t off)
{
uint8_t c;
if (mmio)
c = *((const volatile unsigned char*) (iobase + off));
else
if (iobase)
c = inportb(iobase + off);
return c;
@ -107,9 +106,7 @@ static inline unsigned char read_from_uart(uint32_t off)
static void write_to_uart(uint32_t off, unsigned char c)
{
if (mmio)
*((volatile unsigned char*) (iobase + off)) = c;
else
if (iobase)
outportb(iobase + off, c);
}
@ -140,6 +137,9 @@ int uart_puts(const char *text)
static int uart_config(void)
{
if (!iobase)
return 0;
/*
* enable FIFOs
* clear RX and TX FIFO
@ -165,9 +165,9 @@ static int uart_config(void)
write_to_uart(UART_LCR, lcr);
/*
* set baudrate to 115200
* set baudrate to 9600
*/
uint32_t divisor = 1843200 / 115200;
uint32_t divisor = 1843200 / 9600; // 115200;
write_to_uart(UART_DLL, divisor & 0xff);
write_to_uart(UART_DLM, (divisor >> 8) & 0xff);
@ -183,7 +183,7 @@ int uart_early_init(char* cmdline)
{
#if 1
// default value of our QEMU configuration
iobase = 0xc110;
iobase = DEFAULT_UART_PORT;
#else
if (BUILTIN_EXPECT(!cmdline, 0))
return -EINVAL;
@ -195,28 +195,8 @@ int uart_early_init(char* cmdline)
if (strncmp(str, "uart=io:", 8) == 0) {
iobase = strtol(str+8, (char **)NULL, 16);
if (!iobase)
iobase = DEFAULT_UART_PORT;
return -EINVAL;
mmio = 0;
} else if (strncmp(str, "uart=mmio:", 10) == 0) {
iobase = strtol(str+10, (char **)NULL, 16);
if (!iobase)
return -EINVAL;
if (iobase >= PAGE_MAP_ENTRIES*PAGE_SIZE) {
/* at this point we use the boot page table
* => IO address is not mapped
* => dirty hack, map device before the kernel
*/
int err;
size_t newaddr = ((size_t) &kernel_start - PAGE_SIZE);
err = page_map_bootmap(newaddr & PAGE_MASK, iobase & PAGE_MASK, PG_GLOBAL | PG_ACCESSED | PG_DIRTY | PG_RW | PG_PCD);
if (BUILTIN_EXPECT(err, 0)) {
iobase = 0;
return err;
}
iobase = newaddr;
}
mmio = 1;
}
#endif
@ -231,40 +211,32 @@ int uart_init(void)
uint32_t bar = 0;
// Searching for Intel's UART device
if (pci_get_device_info(0x8086, 0x0936, iobase, &pci_info) == 0)
if (pci_get_device_info(0x8086, 0x0936, &pci_info) == 0)
goto Lsuccess;
// Searching for Qemu's UART device
if (pci_get_device_info(0x1b36, 0x0002, iobase, &pci_info) == 0)
if (pci_get_device_info(0x1b36, 0x0002, &pci_info) == 0)
goto Lsuccess;
// Searching for Qemu's 2x UART device (pci-serial-2x)
if (pci_get_device_info(0x1b36, 0x0003, iobase, &pci_info) == 0)
if (pci_get_device_info(0x1b36, 0x0003, &pci_info) == 0)
goto Lsuccess;
// Searching for Qemu's 4x UART device (pci-serial-4x)
if (pci_get_device_info(0x1b36, 0x0004, iobase, &pci_info) == 0)
if (pci_get_device_info(0x1b36, 0x0004, &pci_info) == 0)
goto Lsuccess;
return -1;
iobase = DEFAULT_UART_PORT;
return uart_config();
Lsuccess:
iobase = pci_info.base[bar];
//irq_install_handler(32+pci_info.irq, uart_handler);
if (pci_info.type[0]) {
mmio = 0;
kprintf("UART uses io address 0x%x\n", iobase);
} else {
mmio = 1;
page_map(iobase & PAGE_MASK, iobase & PAGE_MASK, 1, PG_GLOBAL | PG_ACCESSED | PG_DIRTY | PG_RW | PG_PCD);
kprintf("UART uses mmio address 0x%x\n", iobase);
vma_add(iobase, iobase + PAGE_SIZE, VMA_READ|VMA_WRITE);
}
kprintf("UART uses io address 0x%x\n", iobase);
// configure uart
return uart_config();
#else
// per default we use COM1...
if (!iobase)
iobase = 0x3F8;
mmio = 0;
// default value of our QEMU configuration
iobase = DEFAULT_UART_PORT;
// configure uart
return uart_config();