usage of the boot paramter to establish an early output device

This commit is contained in:
Stefan Lankes 2014-12-29 00:15:03 +01:00
parent c26a8fa4f8
commit 83a4832d15
3 changed files with 67 additions and 23 deletions

View file

@ -78,7 +78,7 @@ qemu: $(NAME).elf
$(QEMU) $(QEMUFLAGS) -kernel $(NAME).elf
uart: $(NAME).elf
$(QEMU) $(QEMUFLAGS) $(QEMUSERIALFLAGS) -kernel $(NAME).elf
$(QEMU) $(QEMUFLAGS) $(QEMUSERIALFLAGS) -kernel $(NAME).elf -append uart=io:0xc110
debug: $(NAME).elf
$(TERM) -e $(GDB) $(GDBFLAGS) &

View file

@ -46,6 +46,12 @@ extern "C" {
*/
int uart_init(void);
/** @brief Initialize UART output without a device check
*
* @return Returns 0 on success
*/
int uart_early_init(char*);
/** @brief Simple string output on a serial device.
*
* If you want a new line you will have to "\\n".

View file

@ -25,9 +25,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <eduos/stdlib.h>
#include <eduos/stdio.h>
#include <eduos/string.h>
#include <eduos/mailbox.h>
#include <eduos/ctype.h>
#include <asm/io.h>
#include <asm/page.h>
#include <asm/uart.h>
@ -198,10 +200,8 @@ static int uart_thread(void* arg)
return 0;
}
static void uart_config(void)
static int uart_config(uint8_t early)
{
mailbox_uint8_init(&input_queue);
/*
* enable FIFOs
* clear RX and TX FIFO
@ -236,14 +236,45 @@ static void uart_config(void)
/* set DLAB=0 */
write_to_uart(UART_LCR, lcr & (~UART_LCR_DLAB));
/* enable interrupt */
write_to_uart(UART_IER, UART_IER_RDI | UART_IER_RLSI | UART_IER_THRI);
if (!early) {
mailbox_uint8_init(&input_queue);
int err = create_kernel_task(&id, uart_thread, NULL, HIGH_PRIO);
if (BUILTIN_EXPECT(err, 0))
kprintf("Failed to create task for the uart device: %d\n", err);
/* enable interrupt */
write_to_uart(UART_IER, UART_IER_RDI | UART_IER_RLSI | UART_IER_THRI);
koutput_add_uart();
int err = create_kernel_task(&id, uart_thread, NULL, HIGH_PRIO);
if (BUILTIN_EXPECT(err, 0))
kprintf("Failed to create task for the uart device: %d\n", err);
koutput_add_uart();
}
return 0;
}
int uart_early_init(char* cmdline)
{
if (BUILTIN_EXPECT(!cmdline, 0))
return -EINVAL;
char* str = strstr(cmdline, "uart=");
if (!str)
return -EINVAL;
if (strncmp(str, "uart=io:", 8) == 0) {
iobase = strtol(str+8, (char **)NULL, 16);
if (!iobase)
return -EINVAL;
mmio = 0;
} else if (strncmp(str, "uart=mmio:", 10) == 0) {
iobase = strtol(str+10, (char **)NULL, 16);
if (!iobase)
return -EINVAL;
mmio = 1;
}
// configure uart
return uart_config(1);
}
int uart_init(void)
@ -253,16 +284,16 @@ int uart_init(void)
uint32_t bar = 0;
// Searching for Intel's UART device
if (pci_get_device_info(0x8086, 0x0936, &pci_info) == 0)
if (pci_get_device_info(0x8086, 0x0936, iobase, &pci_info) == 0)
goto Lsuccess;
// Searching for Qemu's UART device
if (pci_get_device_info(0x1b36, 0x0002, &pci_info) == 0)
if (pci_get_device_info(0x1b36, 0x0002, iobase, &pci_info) == 0)
goto Lsuccess;
// Searching for Qemu's 2x UART device (pci-serial-2x)
if (pci_get_device_info(0x1b36, 0x0003, &pci_info) == 0)
if (pci_get_device_info(0x1b36, 0x0003, iobase, &pci_info) == 0)
goto Lsuccess;
// Searching for Qemu's 4x UART device (pci-serial-4x)
if (pci_get_device_info(0x1b36, 0x0003, &pci_info) == 0)
if (pci_get_device_info(0x1b36, 0x0003, iobase, &pci_info) == 0)
goto Lsuccess;
return -1;
@ -275,20 +306,27 @@ Lsuccess:
kprintf("UART uses io address 0x%x\n", iobase);
} else {
mmio = 1;
page_map(iobase & PAGE_MASK, iobase & PAGE_MASK, 1, PG_GLOBAL | PG_RW | PG_PCD);
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);
}
#else
// per default we use COM1...
mmio = 0;
iobase = 0x3F8;
irq_install_handler(32+4, uart_handler);
#endif
// configure uart
uart_config();
return uart_config(0);
#else
// per default we use COM1...
if (!iobase)
iobase = 0x3F8;
mmio = 0;
if ((iobase == 0x3F8) || (iobase == 0x3E8))
irq_install_handler(32+4, uart_handler);
else if ((iobase == 0x2F8) || (iobase == 0x2E8))
irq_install_handler(32+3, uart_handler);
else
return -EINVAL;
return 0;
// configure uart
return uart_config(0);
#endif
}
#endif