// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2009 Corey Tabaka
// Copyright (c) 2016 Travis Geiselbrecht
//
// 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 <assert.h>
#include <ctype.h>
#include <debug.h>
#include <lib/cbuf.h>
#include <platform.h>
#include <sys/types.h>
#include <trace.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <arch/x86.h>
#include <arch/x86/apic.h>
#include <dev/interrupt.h>
#include <kernel/thread.h>
#include <platform/console.h>
#include <platform/keyboard.h>
#include <platform/pc.h>
#include <platform/timer.h>

#include "platform_p.h"

#define LOCAL_TRACE 0

static inline uint8_t i8042_read_data(void) { return inp(I8042_DATA_REG); }

static inline uint8_t i8042_read_status(void) { return inp(I8042_STATUS_REG); }

static inline void i8042_write_data(uint8_t val) { outp(I8042_DATA_REG, val); }

static inline void i8042_write_command(uint8_t val) { outp(I8042_COMMAND_REG, val); }

/*
 * timeout in milliseconds
 */
#define I8042_CTL_TIMEOUT 500

/*
 * status register bits
 */
#define I8042_STR_PARITY 0x80
#define I8042_STR_TIMEOUT 0x40
#define I8042_STR_AUXDATA 0x20
#define I8042_STR_KEYLOCK 0x10
#define I8042_STR_CMDDAT 0x08
#define I8042_STR_MUXERR 0x04
#define I8042_STR_IBF 0x02
#define I8042_STR_OBF 0x01

/*
 * control register bits
 */
#define I8042_CTR_KBDINT 0x01
#define I8042_CTR_AUXINT 0x02
#define I8042_CTR_IGNKEYLK 0x08
#define I8042_CTR_KBDDIS 0x10
#define I8042_CTR_AUXDIS 0x20
#define I8042_CTR_XLATE 0x40

/*
 * commands
 */
#define I8042_CMD_CTL_RCTR 0x0120
#define I8042_CMD_CTL_WCTR 0x1060
#define I8042_CMD_CTL_TEST 0x01aa

#define I8042_CMD_KBD_DIS 0x00ad
#define I8042_CMD_KBD_EN 0x00ae
#define I8042_CMD_PULSE_RESET 0x00fe
#define I8042_CMD_KBD_TEST 0x01ab
#define I8042_CMD_KBD_MODE 0x01f0

/*
 * used for flushing buffers. the i8042 internal buffer shouldn't exceed this.
 */
#define I8042_BUFFER_LENGTH 32

/* extended keys that aren't pure ascii */
enum extended_keys {
  KEY_RETURN = 0x80,
  KEY_ESC,
  KEY_LSHIFT,
  KEY_RSHIFT,
  KEY_LCTRL,
  KEY_RCTRL,
  KEY_LALT,
  KEY_RALT,
  KEY_CAPSLOCK,
  KEY_LWIN,
  KEY_RWIN,
  KEY_MENU,
  KEY_F1,
  KEY_F2,
  KEY_F3,
  KEY_F4,
  KEY_F5,
  KEY_F6,
  KEY_F7,
  KEY_F8,
  KEY_F9,
  KEY_F10,
  KEY_F11,
  KEY_F12,
  KEY_F13,
  KEY_F14,
  KEY_F15,
  KEY_F16,
  KEY_F17,
  KEY_F18,
  KEY_F19,
  KEY_F20,
  KEY_PRTSCRN,
  KEY_SCRLOCK,
  KEY_PAUSE,
  KEY_TAB,
  KEY_BACKSPACE,
  KEY_INS,
  KEY_DEL,
  KEY_HOME,
  KEY_END,
  KEY_PGUP,
  KEY_PGDN,
  KEY_ARROW_UP,
  KEY_ARROW_DOWN,
  KEY_ARROW_LEFT,
  KEY_ARROW_RIGHT,
  KEY_PAD_NUMLOCK,
  KEY_PAD_DIVIDE,
  KEY_PAD_MULTIPLY,
  KEY_PAD_MINUS,
  KEY_PAD_PLUS,
  KEY_PAD_ENTER,
  KEY_PAD_PERIOD,
  KEY_PAD_0,
  KEY_PAD_1,
  KEY_PAD_2,
  KEY_PAD_3,
  KEY_PAD_4,
  KEY_PAD_5,
  KEY_PAD_6,
  KEY_PAD_7,
  KEY_PAD_8,
  KEY_PAD_9,

  _KEY_LAST,
};

static_assert(_KEY_LAST < 0x100, "");

/* scancode translation tables */
const uint8_t pc_keymap_set1_lower[128] = {
    /* 0x00 */ 0,
    KEY_ESC,
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    '0',
    '-',
    '=',
    KEY_BACKSPACE,
    KEY_TAB,
    /* 0x10 */ 'q',
    'w',
    'e',
    'r',
    't',
    'y',
    'u',
    'i',
    'o',
    'p',
    '[',
    ']',
    KEY_RETURN,
    KEY_LCTRL,
    'a',
    's',
    /* 0x20 */ 'd',
    'f',
    'g',
    'h',
    'j',
    'k',
    'l',
    ';',
    '\'',
    '`',
    KEY_LSHIFT,
    '\\',
    'z',
    'x',
    'c',
    'v',
    /* 0x30 */ 'b',
    'n',
    'm',
    ',',
    '.',
    '/',
    KEY_RSHIFT,
    '*',
    KEY_LALT,
    ' ',
    KEY_CAPSLOCK,
    KEY_F1,
    KEY_F2,
    KEY_F3,
    KEY_F4,
    KEY_F5,
    /* 0x40 */ KEY_F6,
    KEY_F7,
    KEY_F8,
    KEY_F9,
    KEY_F10,
    KEY_PAD_NUMLOCK,
    KEY_SCRLOCK,
    KEY_PAD_7,
    KEY_PAD_8,
    KEY_PAD_9,
    KEY_PAD_MINUS,
    KEY_PAD_4,
    KEY_PAD_5,
    KEY_PAD_6,
    KEY_PAD_PLUS,
    KEY_PAD_1,
    /* 0x50 */ KEY_PAD_2,
    KEY_PAD_3,
    KEY_PAD_0,
    KEY_PAD_PERIOD,
    0,
    0,
    0,
    KEY_F11,
    KEY_F12,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
};

const uint8_t pc_keymap_set1_upper[128] = {
    /* 0x00 */ 0,
    KEY_ESC,
    '!',
    '@',
    '#',
    '$',
    '%',
    '^',
    '&',
    '*',
    '(',
    ')',
    '_',
    '+',
    KEY_BACKSPACE,
    KEY_TAB,
    /* 0x10 */ 'Q',
    'W',
    'E',
    'R',
    'T',
    'Y',
    'U',
    'I',
    'O',
    'P',
    '{',
    '}',
    KEY_RETURN,
    KEY_LCTRL,
    'A',
    'S',
    /* 0x20 */ 'D',
    'F',
    'G',
    'H',
    'J',
    'K',
    'L',
    ':',
    '"',
    '~',
    KEY_LSHIFT,
    '|',
    'Z',
    'X',
    'C',
    'V',
    /* 0x30 */ 'B',
    'N',
    'M',
    '<',
    '>',
    '?',
    KEY_RSHIFT,
    '*',
    KEY_LALT,
    ' ',
    KEY_CAPSLOCK,
    KEY_F1,
    KEY_F2,
    KEY_F3,
    KEY_F4,
    KEY_F5,
    /* 0x40 */ KEY_F6,
    KEY_F7,
    KEY_F8,
    KEY_F9,
    KEY_F10,
    KEY_PAD_NUMLOCK,
    KEY_SCRLOCK,
    KEY_PAD_7,
    KEY_PAD_8,
    KEY_PAD_9,
    KEY_PAD_MINUS,
    KEY_PAD_4,
    KEY_PAD_5,
    KEY_PAD_6,
    KEY_PAD_PLUS,
    KEY_PAD_1,
    /* 0x50 */ KEY_PAD_2,
    KEY_PAD_3,
    KEY_PAD_0,
    KEY_PAD_PERIOD,
    0,
    0,
    0,
    KEY_F11,
    KEY_F12,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
};

const uint8_t pc_keymap_set1_e0[128] = {
    /* 0x00 */ 0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    /* 0x10 */ 0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    KEY_PAD_ENTER,
    KEY_RCTRL,
    0,
    0,
    /* 0x20 */ 0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    /* 0x30 */ 0,
    0,
    0,
    0,
    0,
    KEY_PAD_DIVIDE,
    0,
    KEY_PRTSCRN,
    KEY_RALT,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    /* 0x40 */ 0,
    0,
    0,
    0,
    0,
    0,
    0,
    KEY_HOME,
    KEY_ARROW_UP,
    KEY_PGUP,
    0,
    KEY_ARROW_LEFT,
    0,
    KEY_ARROW_RIGHT,
    0,
    KEY_END,
    /* 0x50 */ KEY_ARROW_DOWN,
    KEY_PGDN,
    KEY_INS,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    KEY_LWIN,
    KEY_RWIN,
    KEY_MENU,
    0,
    0};

/*
 * state key flags
 */
static bool key_lshift;
static bool key_rshift;
static int last_code;

static Cbuf* key_buf;

static void i8042_process_scode(uint8_t scode, unsigned int flags) {
  // is this a multi code sequence?
  bool multi = (last_code == 0xe0);

  // update the last received code
  last_code = scode;

  // save the key up event bit
  bool key_up = !!(scode & 0x80);
  scode &= 0x7f;

  // translate the key based on our translation table
  uint8_t key_code;
  if (multi) {
    key_code = pc_keymap_set1_e0[scode];
  } else if (key_lshift || key_rshift) {
    key_code = pc_keymap_set1_upper[scode];
  } else {
    key_code = pc_keymap_set1_lower[scode];
  }

  LTRACEF("scancode 0x%x, keyup %d, multi %d: keycode 0x%x\n", scode, !!key_up, multi, key_code);

  // generate a character string to feed into the queue
  char str[4] = {0};
  switch (key_code) {
    // for all the usual ascii strings, generate the target string directly
    case 1 ... 0x7f:
      str[0] = key_code;
      break;

    // a few special keys we can generate stuff for directly
    case KEY_RETURN:
    case KEY_PAD_ENTER:
      str[0] = '\n';
      break;
    case KEY_BACKSPACE:
      str[0] = '\b';
      break;
    case KEY_TAB:
      str[0] = '\t';
      break;

    // generate vt100 key codes for arrows
    case KEY_ARROW_UP:
      str[0] = 0x1b;
      str[1] = '[';
      str[2] = 65;
      break;
    case KEY_ARROW_DOWN:
      str[0] = 0x1b;
      str[1] = '[';
      str[2] = 66;
      break;
    case KEY_ARROW_RIGHT:
      str[0] = 0x1b;
      str[1] = '[';
      str[2] = 67;
      break;
    case KEY_ARROW_LEFT:
      str[0] = 0x1b;
      str[1] = '[';
      str[2] = 68;
      break;

    // left and right shift are special
    case KEY_LSHIFT:
      key_lshift = !key_up;
      break;
    case KEY_RSHIFT:
      key_rshift = !key_up;
      break;

    // everything else we just eat
    default:;  // nothing
  }

  if (!key_up) {
    for (uint i = 0; str[i] != '\0'; i++) {
      LTRACEF("char 0x%hhx (%c)\n", str[i], isprint(str[i]) ? (str[i]) : ' ');
      key_buf->WriteChar(str[i]);
    }
  }
}

static int i8042_wait_read(void) {
  int i = 0;
  while ((~i8042_read_status() & I8042_STR_OBF) && (i < I8042_CTL_TIMEOUT)) {
    spin(10);
    i++;
  }
  return -(i == I8042_CTL_TIMEOUT);
}

static int i8042_wait_write(void) {
  int i = 0;
  while ((i8042_read_status() & I8042_STR_IBF) && (i < I8042_CTL_TIMEOUT)) {
    spin(10);
    i++;
  }
  return -(i == I8042_CTL_TIMEOUT);
}

static int i8042_flush(void) {
  unsigned char data __UNUSED;
  int i = 0;

  while ((i8042_read_status() & I8042_STR_OBF) && (i++ < I8042_BUFFER_LENGTH)) {
    spin(10);
    data = i8042_read_data();
  }

  return i;
}

static int i8042_command(uint8_t* param, uint16_t command) {
  int retval = 0, i = 0;

  retval = i8042_wait_write();
  if (!retval) {
    i8042_write_command(static_cast<uint8_t>(command));
  }

  if (!retval) {
    for (i = 0; i < ((command >> 12) & 0xf); i++) {
      if ((retval = i8042_wait_write())) {
        break;
      }

      i8042_write_data(param[i]);
    }
  }

  if (!retval) {
    for (i = 0; i < ((command >> 8) & 0xf); i++) {
      if ((retval = i8042_wait_read())) {
        break;
      }

      if (i8042_read_status() & I8042_STR_AUXDATA) {
        param[i] = static_cast<uint8_t>(~i8042_read_data());
      } else {
        param[i] = i8042_read_data();
      }
    }
  }

  return retval;
}

static int keyboard_command(uint8_t* param, int command) {
  int retval = 0, i = 0;

  retval = i8042_wait_write();
  if (!retval) {
    i8042_write_data(static_cast<uint8_t>(command));
  }

  if (!retval) {
    for (i = 0; i < ((command >> 12) & 0xf); i++) {
      if ((retval = i8042_wait_write())) {
        break;
      }

      i8042_write_data(param[i]);
    }
  }

  if (!retval) {
    for (i = 0; i < ((command >> 8) & 0xf); i++) {
      if ((retval = i8042_wait_read())) {
        break;
      }

      if (i8042_read_status() & I8042_STR_AUXDATA) {
        param[i] = static_cast<uint8_t>(~i8042_read_data());
      } else {
        param[i] = i8042_read_data();
      }
    }
  }

  return retval;
}

static interrupt_eoi i8042_interrupt(void* arg) {
  // keep handling status on the keyboard controller until no bits are set we care about
  bool retry;
  do {
    retry = false;

    uint8_t str = i8042_read_status();

    // check for incoming data from the controller
    if (str & I8042_STR_OBF) {
      uint8_t data = i8042_read_data();
      i8042_process_scode(data, ((str & I8042_STR_PARITY) ? I8042_STR_PARITY : 0) |
                                    ((str & I8042_STR_TIMEOUT) ? I8042_STR_TIMEOUT : 0));

      retry = true;
    }

    // TODO: check other status bits here
  } while (retry);
  return IRQ_EOI_DEACTIVATE;
}

void platform_init_keyboard(Cbuf* buffer) {
  uint8_t ctr;

  key_buf = buffer;

  i8042_flush();

  if (i8042_command(&ctr, I8042_CMD_CTL_RCTR)) {
    dprintf(SPEW, "Failed to read CTR while initializing i8042\n");
    return;
  }

  // turn on translation
  ctr |= I8042_CTR_XLATE;

  // enable keyboard and keyboard irq
  ctr &= static_cast<uint8_t>(~I8042_CTR_KBDDIS);
  ctr |= I8042_CTR_KBDINT;

  if (i8042_command(&ctr, I8042_CMD_CTL_WCTR)) {
    dprintf(SPEW, "Failed to write CTR while initializing i8042\n");
    return;
  }

  /* enable PS/2 port */
  i8042_command(NULL, I8042_CMD_KBD_EN);

  /* send a enable scan command to the keyboard */
  keyboard_command(&ctr, 0x1f4);

  uint32_t irq = apic_io_isa_to_global(ISA_IRQ_KEYBOARD);
  zx_status_t status = register_permanent_int_handler(irq, &i8042_interrupt, NULL);
  DEBUG_ASSERT(status == ZX_OK);
  unmask_interrupt(irq);

  i8042_interrupt(NULL);
}

void pc_keyboard_reboot(void) {
  if (i8042_wait_write() != 0) {
    return;
  }

  i8042_write_command(I8042_CMD_PULSE_RESET);
  // Wait a second for the command to process before declaring failure
  spin(1000000);
}
