// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2009 Corey Tabaka
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <arch/x86.h>
#include <arch/x86/apic.h>
#include <bits.h>
#include <dev/interrupt.h>
#include <kernel/cmdline.h>
#include <kernel/spinlock.h>
#include <kernel/thread.h>
#include <kernel/timer.h>
#include <lib/cbuf.h>
#include <lib/debuglog.h>
#include <lk/init.h>
#include <platform.h>
#include <platform/console.h>
#include <platform/debug.h>
#include <platform/pc.h>
#include <platform/pc/bootloader.h>
#include <reg.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <trace.h>
#include <vm/physmap.h>
#include <zircon/time.h>
#include <zircon/types.h>

#include "platform_p.h"

static const int uart_baud_rate = 115200;
static int uart_io_port = 0x3f8;
static uint64_t uart_mem_addr = 0;
static uint32_t uart_irq = ISA_IRQ_SERIAL1;

cbuf_t console_input_buf;
static bool output_enabled = false;
uint32_t uart_fifo_depth;

// tx driven irq
static bool uart_tx_irq_enabled = false;
static event_t uart_dputc_event = EVENT_INITIAL_VALUE(uart_dputc_event, true,
                                                      EVENT_FLAG_AUTOUNSIGNAL);
static spin_lock_t uart_spinlock = SPIN_LOCK_INITIAL_VALUE;

static uint8_t uart_read(uint8_t reg) {
    if (uart_mem_addr) {
        return (uint8_t)readl(uart_mem_addr + 4 * reg);
    } else {
        return (uint8_t)inp((uint16_t)(uart_io_port + reg));
    }
}

static void uart_write(uint8_t reg, uint8_t val) {
    if (uart_mem_addr) {
        writel(val, uart_mem_addr + 4 * reg);
    } else {
        outp((uint16_t)(uart_io_port + reg), val);
    }
}

static interrupt_eoi uart_irq_handler(void *arg) {
    spin_lock(&uart_spinlock);

    // see why we have gotten an irq
    for (;;) {
        uint8_t iir = uart_read(2);
        if (BIT(iir, 0))
            break; // no valid interrupt

        // 3 bit identification field
        uint ident = BITS(iir, 3, 0);
        switch (ident) {
        case 0b0100:
        case 0b1100: {
            // rx fifo is non empty, drain it
            unsigned char c = uart_read(0);
            cbuf_write_char(&console_input_buf, c);
            break;
        }
        case 0b0010:
            // transmitter is empty, signal any waiting senders
            event_signal(&uart_dputc_event, true);
            // disable the tx irq
            uart_write(1, (1<<0)); // just rx interrupt enable
            break;
        case 0b0110: // receiver line status
            uart_read(5); // read the LSR
            break;
        default:
            spin_unlock(&uart_spinlock);
            panic("UART: unhandled ident %#x\n", ident);
        }
    }

    spin_unlock(&uart_spinlock);
    return IRQ_EOI_DEACTIVATE;
}

static void platform_drain_debug_uart_rx(void) {
    while (uart_read(5) & (1<<0)) {
        unsigned char c = uart_read(0);
        cbuf_write_char(&console_input_buf, c);
    }
}

static constexpr TimerSlack kSlack{ZX_MSEC(1), TIMER_SLACK_CENTER};

// for devices where the uart rx interrupt doesn't seem to work
static void uart_rx_poll(timer_t* t, zx_time_t now, void* arg) {
    const Deadline deadline(zx_time_add_duration(now, ZX_MSEC(10)), kSlack);
    timer_set(t, deadline, uart_rx_poll, NULL);
    platform_drain_debug_uart_rx();
}

void platform_debug_start_uart_timer();

void platform_debug_start_uart_timer(void) {
    static timer_t uart_rx_poll_timer;
    static bool started = false;

    if (!started) {
        started = true;
        timer_init(&uart_rx_poll_timer);
        const Deadline deadline(zx_time_add_duration(current_time(), ZX_MSEC(10)), kSlack);
        timer_set(&uart_rx_poll_timer, deadline, uart_rx_poll, NULL);
    }
}

static void init_uart() {
    /* configure the uart */
    int divisor = 115200 / uart_baud_rate;

    /* get basic config done so that tx functions */
    uart_write(1, 0);                                  // mask all irqs
    uart_write(3, 0x80);                               // set up to load divisor latch
    uart_write(0, static_cast<uint8_t>(divisor));      // lsb
    uart_write(1, static_cast<uint8_t>(divisor >> 8)); // msb
    uart_write(3, 3);                                  // 8N1
    // enable FIFO, rx FIFO reset, tx FIFO reset, 16750 64 byte fifo enable,
    // Rx FIFO irq trigger level at 14-bytes
    uart_write(2, 0xe7);
    // Drive flow control bits high since we don't actively manage them
    uart_write(4, 0x3);

    /* figure out the fifo depth */
    uint8_t fcr = uart_read(2);
    if (BITS_SHIFT(fcr, 7, 6) == 3 && BIT(fcr, 5)) {
        // this is a 16750
        uart_fifo_depth = 64;
    } else if (BITS_SHIFT(fcr, 7, 6) == 3) {
        // this is a 16550A
        uart_fifo_depth = 16;
    } else {
        uart_fifo_depth = 1;
    }
}

bool platform_serial_enabled() {
    return bootloader.uart.type != ZBI_UART_NONE;
}

// This just initializes the default serial console to be disabled.
// It's in a function rather than just a compile-time assignment to the
// bootloader structure because our C++ compiler doesn't support non-trivial
// designated initializers.
void pc_init_debug_default_early() {
    bootloader.uart.type = ZBI_UART_NONE;
}

static void handle_serial_cmdline() {
    const char* serial_mode = cmdline_get("kernel.serial");
    if (serial_mode == NULL) {
        return;
    }
    if (!strcmp(serial_mode, "none")) {
        bootloader.uart.type = ZBI_UART_NONE;
        return;
    }
    if (!strcmp(serial_mode, "legacy")) {
        bootloader.uart.type = ZBI_UART_PC_PORT;
        bootloader.uart.base = 0x3f8;
        bootloader.uart.irq = ISA_IRQ_SERIAL1;
        return;
    }

    // type can be "ioport" or "mmio"
    constexpr size_t kMaxTypeLen = 6 + 1;
    char type_buf[kMaxTypeLen];
    // Addr can be up to 32 characters (numeric in any base strtoul will take),
    // and + 1 for \0
    constexpr size_t kMaxAddrLen = 32 + 1;
    char addr_buf[kMaxAddrLen];

    char* endptr;
    const char* addr_start;
    const char* irq_start;
    size_t addr_len, type_len;
    unsigned long irq_val;

    addr_start = strchr(serial_mode, ',');
    if (addr_start == nullptr) {
        goto bail;
    }
    addr_start++;
    irq_start = strchr(addr_start, ',');
    if (irq_start == nullptr) {
        goto bail;
    }
    irq_start++;

    // Parse out the type part
    type_len = addr_start - serial_mode - 1;
    if (type_len + 1 > kMaxTypeLen) {
        goto bail;
    }
    memcpy(type_buf, serial_mode, type_len);
    type_buf[type_len] = 0;
    if (!strcmp(type_buf, "ioport")) {
        bootloader.uart.type = ZBI_UART_PC_PORT;
    } else if (!strcmp(type_buf, "mmio")) {
        bootloader.uart.type = ZBI_UART_PC_MMIO;
    } else {
        goto bail;
    }

    // Parse out the address part
    addr_len = irq_start - addr_start - 1;
    if (addr_len + 1 > kMaxAddrLen) {
        goto bail;
    }
    memcpy(addr_buf, addr_start, addr_len);
    addr_buf[addr_len] = 0;
    bootloader.uart.base = strtoul(addr_buf, &endptr, 0);
    if (endptr != addr_buf + addr_len) {
        goto bail;
    }

    // Parse out the IRQ part
    irq_val = strtoul(irq_start, &endptr, 0);
    if (*endptr != '\0' || irq_val > UINT32_MAX) {
        goto bail;
    }
    // For now, we don't support non-ISA IRQs
    if (irq_val >= NUM_ISA_IRQS) {
        goto bail;
    }
    bootloader.uart.irq = static_cast<uint32_t>(irq_val);
    return;

bail:
    bootloader.uart.type = ZBI_UART_NONE;
    return;
}

void pc_init_debug_early() {
    handle_serial_cmdline();

    switch (bootloader.uart.type) {
    case ZBI_UART_PC_PORT:
        uart_io_port = static_cast<uint32_t>(bootloader.uart.base);
        uart_irq = bootloader.uart.irq;
        break;
    case ZBI_UART_PC_MMIO:
        uart_mem_addr = (uint64_t)paddr_to_physmap(bootloader.uart.base);
        uart_irq = bootloader.uart.irq;
        break;
    case ZBI_UART_NONE: // fallthrough
    default:
        bootloader.uart.type = ZBI_UART_NONE;
        return;
    }

    init_uart();

    output_enabled = true;

    dprintf(INFO, "UART: FIFO depth %u\n", uart_fifo_depth);
}

void pc_init_debug(void) {
    bool tx_irq_driven = false;
    /* finish uart init to get rx going */
    cbuf_initialize(&console_input_buf, 1024);

    if (!platform_serial_enabled()) {
        // Need to bail after initializing the input_buf to prevent uninitialized
        // access to it.
        return;
    }

    if ((uart_irq == 0) || cmdline_get_bool("kernel.debug_uart_poll", false) ||
        dlog_bypass()) {
        printf("debug-uart: polling enabled\n");
        platform_debug_start_uart_timer();
    } else {
        uart_irq = apic_io_isa_to_global(static_cast<uint8_t>(uart_irq));
        zx_status_t status = register_int_handler(uart_irq, uart_irq_handler, NULL);
        DEBUG_ASSERT(status == ZX_OK);
        unmask_interrupt(uart_irq);

        uart_write(1, (1<<0)); // enable receive data available interrupt

        // modem control register: Auxiliary Output 2 is another IRQ enable bit
        const uint8_t mcr = uart_read(4);
        uart_write(4, mcr | 0x8);
        printf("UART: started IRQ driven RX\n");
        tx_irq_driven = true;
    }
    if (tx_irq_driven) {
        // start up tx driven output
        printf("UART: started IRQ driven TX\n");
        uart_tx_irq_enabled = true;
    }
}

void pc_suspend_debug(void) {
    output_enabled = false;
}

void pc_resume_debug(void) {
    if (platform_serial_enabled()) {
        init_uart();
        output_enabled = true;
    }
}

/*
 * This is called when the FIFO is detected to be empty. So we can write an
 * entire FIFO's worth of bytes. Much more efficient than writing 1 byte
 * at a time (and then checking for FIFO to drain).
 */
static char *debug_platform_tx_FIFO_bytes(const char *str, size_t *len,
                                          bool *copied_CR,
                                          size_t *wrote_bytes,
                                          bool map_NL)
{
    size_t i, copy_bytes;;
    char *s = (char *)str;

    copy_bytes = MIN(uart_fifo_depth, *len);
    for (i = 0 ; i < copy_bytes ; i++) {
        if (*s == '\n' && map_NL && !*copied_CR) {
            uart_write(0, '\r');
            *copied_CR = true;
            if (++i == copy_bytes)
                break;
            uart_write(0, '\n');
        } else {
            uart_write(0, *s);
            *copied_CR = false;
        }
        s++;
        (*len)--;
    }
    if (wrote_bytes != NULL)
        *wrote_bytes = i;
    return s;
}

/*
 * dputs() Tx is either polling driven (if the caller is non-preemptible
 * or earlyboot or panic) or blocking (and irq driven).
 * TODO - buffered Tx support may be a win, (lopri but worth investigating)
 * When we do that dputs() can be completely asynchronous, and return when
 * the write has been (atomically) deposited into the buffer, except when
 * we run out of room in the Tx buffer (rare) - we'd either need to spin
 * (if non-blocking) or block waiting for space in the Tx buffer (adding
 * support to optionally block in cbuf_write_char() would be easiest way
 * to achieve that).
 *
 * block : Blocking vs Non-Blocking
 * map_NL : If true, map a '\n' to '\r'+'\n'
 */
static void platform_dputs(const char* str, size_t len,
                           bool block, bool map_NL) {
    spin_lock_saved_state_t state;
    bool copied_CR = false;
    size_t wrote;

    // drop strings if we haven't initialized the uart yet
    if (unlikely(!output_enabled))
        return;
    if (!uart_tx_irq_enabled)
        block = false;
    spin_lock_irqsave(&uart_spinlock, state);
    while (len > 0) {
        // Is FIFO empty ?
        while (!(uart_read(5) & (1<<5))) {
            if (block) {
                /*
                 * We want to Tx more and FIFO is empty, re-enable
                 * Tx interrupts before blocking.
                 */
                uart_write(1, (1<<0)|(1<<1)); // rx and tx interrupt enable
                spin_unlock_irqrestore(&uart_spinlock, state);
                event_wait(&uart_dputc_event);
            } else {
                spin_unlock_irqrestore(&uart_spinlock, state);
                arch_spinloop_pause();
            }
            spin_lock_irqsave(&uart_spinlock, state);
        }
        // Fifo is completely empty now, we can shove an entire
        // fifo's worth of Tx...
        str = debug_platform_tx_FIFO_bytes(str, &len, &copied_CR,
                                           &wrote, map_NL);
        if (block && wrote > 0) {
            // If blocking/irq driven wakeps, enable rx/tx intrs
            uart_write(1, (1<<0)|(1<<1)); // rx and tx interrupt enable
        }
    }
    spin_unlock_irqrestore(&uart_spinlock, state);
}

void platform_dputs_thread(const char* str, size_t len) {
    if (platform_serial_enabled()) {
        platform_dputs(str, len, true, true);
    }
}

void platform_dputs_irq(const char* str, size_t len) {
    if (platform_serial_enabled()) {
        platform_dputs(str, len, false, true);
    }
}

// polling versions of debug uart read/write
static int debug_uart_getc_poll(char *c) {
    // if there is a character available, read it
    if (uart_read(5) & (1<<0)) {
        *c = uart_read(0);
        return 0;
    }

    return -1;
}

static void debug_uart_putc_poll(char c) {
    // while the fifo is non empty, spin
    while (!(uart_read(5) & (1<<6))) {
        arch_spinloop_pause();
    }
    uart_write(0, c);
}


int platform_dgetc(char* c, bool wait) {
    if (platform_serial_enabled()) {
        return static_cast<int>(cbuf_read_char(&console_input_buf, c, wait));
    }
    return ZX_ERR_NOT_SUPPORTED;
}

// panic time polling IO for the panic shell
void platform_pputc(char c) {
    if (platform_serial_enabled()) {
        if (c == '\n')
            debug_uart_putc_poll('\r');
        debug_uart_putc_poll(c);
    }
}

int platform_pgetc(char *c, bool wait) {
    if (platform_serial_enabled()) {
        return debug_uart_getc_poll(c);
    }
    return ZX_ERR_NOT_SUPPORTED;
}

/*
 * Called on start of a panic.
 * When we do Tx buffering, drain the Tx buffer here in polling mode.
 * Turn off Tx interrupts, so force Tx be polling from this point
 */
void platform_debug_panic_start(void) {
    uart_tx_irq_enabled = false;
}
