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:
parent
dbefde4927
commit
d4668dc59e
2 changed files with 50 additions and 52 deletions
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue