Skip to content

Instantly share code, notes, and snippets.

@sunwayforever
Created July 19, 2017 07:52
Show Gist options
  • Save sunwayforever/8b4fde551ed28ece24a3256da557187f to your computer and use it in GitHub Desktop.
Save sunwayforever/8b4fde551ed28ece24a3256da557187f to your computer and use it in GitHub Desktop.
kgdb patch for android 7.1 on nexus5x
diff --git a/arch/arm64/configs/bullhead_defconfig b/arch/arm64/configs/bullhead_defconfig
index 8256805..3a4a363 100644
--- a/arch/arm64/configs/bullhead_defconfig
+++ b/arch/arm64/configs/bullhead_defconfig
@@ -672,3 +672,16 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
CONFIG_QMI_ENCDEC=y
CONFIG_STRICT_MEMORY_RWX=y
+
+CONFIG_CMDLINE=" kgdboc=ttyHSL0,115200"
+CONFIG_CMDLINE_EXTEND=y
+CONFIG_STRICT_MEMORY_RWX=n
+CONFIG_DEBUG_RODATA=n
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_KGDB=y
+CONFIG_KGDB_SERIAL_CONSOLE=y
+CONFIG_KALLSYMS=y
+CONFIG_MSM_WATCHDOG_V2=n
\ No newline at end of file
diff --git a/drivers/soc/qcom/lge/lge_handle_panic.c b/drivers/soc/qcom/lge/lge_handle_panic.c
index e2d1d43..c64ee68 100644
--- a/drivers/soc/qcom/lge/lge_handle_panic.c
+++ b/drivers/soc/qcom/lge/lge_handle_panic.c
@@ -402,20 +402,23 @@ extern void __iomem *wdt_timer_get_timer0_base(void);
static int gen_wdt_bark(const char *val, struct kernel_param *kp)
{
- void __iomem *msm_tmr0_base;
- msm_tmr0_base = wdt_timer_get_timer0_base();
-
- pr_info("%s\n", __func__);
- writel_relaxed(0, msm_tmr0_base + WDT0_EN);
- writel_relaxed(1, msm_tmr0_base + WDT0_RST);
- writel_relaxed(0x31F3, msm_tmr0_base + WDT0_BARK_TIME);
- writel_relaxed(5 * 0x31F3, msm_tmr0_base + WDT0_BITE_TIME);
- writel_relaxed(1, msm_tmr0_base + WDT0_EN);
- mb();
- mdelay(5000);
-
- pr_err("%s failed\n", __func__);
-
+ /*
+ * void __iomem *msm_tmr0_base;
+ * msm_tmr0_base = wdt_timer_get_timer0_base();
+ *
+ * pr_info("%s\n", __func__);
+ * writel_relaxed(0, msm_tmr0_base + WDT0_EN);
+ * writel_relaxed(1, msm_tmr0_base + WDT0_RST);
+ * writel_relaxed(0x31F3, msm_tmr0_base + WDT0_BARK_TIME);
+ * writel_relaxed(5 * 0x31F3, msm_tmr0_base + WDT0_BITE_TIME);
+ * writel_relaxed(1, msm_tmr0_base + WDT0_EN);
+ * mb();
+ * mdelay(5000);
+ *
+ * pr_err("%s failed\n", __func__);
+ *
+ * return -EIO;
+ */
return -EIO;
}
module_param_call(gen_wdt_bark, gen_wdt_bark, param_get_bool,
@@ -423,20 +426,23 @@ module_param_call(gen_wdt_bark, gen_wdt_bark, param_get_bool,
static int gen_wdt_bite(const char *val, struct kernel_param *kp)
{
- void __iomem *msm_tmr0_base;
- msm_tmr0_base = wdt_timer_get_timer0_base();
-
- pr_info("%s\n", __func__);
- writel_relaxed(0, msm_tmr0_base + WDT0_EN);
- writel_relaxed(1, msm_tmr0_base + WDT0_RST);
- writel_relaxed(5 * 0x31F3, msm_tmr0_base + WDT0_BARK_TIME);
- writel_relaxed(0x31F3, msm_tmr0_base + WDT0_BITE_TIME);
- writel_relaxed(1, msm_tmr0_base + WDT0_EN);
- mb();
- mdelay(5000);
-
- pr_err("%s failed\n", __func__);
-
+ /*
+ * void __iomem *msm_tmr0_base;
+ * msm_tmr0_base = wdt_timer_get_timer0_base();
+ *
+ * pr_info("%s\n", __func__);
+ * writel_relaxed(0, msm_tmr0_base + WDT0_EN);
+ * writel_relaxed(1, msm_tmr0_base + WDT0_RST);
+ * writel_relaxed(5 * 0x31F3, msm_tmr0_base + WDT0_BARK_TIME);
+ * writel_relaxed(0x31F3, msm_tmr0_base + WDT0_BITE_TIME);
+ * writel_relaxed(1, msm_tmr0_base + WDT0_EN);
+ * mb();
+ * mdelay(5000);
+ *
+ * pr_err("%s failed\n", __func__);
+ *
+ * return -EIO;
+ */
return -EIO;
}
module_param_call(gen_wdt_bite, gen_wdt_bite, param_get_bool,
@@ -583,21 +589,23 @@ module_param_call(gen_unknown_reset, gen_unknown_reset, param_get_bool,
void lge_disable_watchdog(void)
{
- static int once = 1;
- void __iomem *msm_tmr0_base;
-
- if (once > 1)
- return;
-
- msm_tmr0_base = wdt_timer_get_timer0_base();
- if (!msm_tmr0_base)
- return;
-
- writel_relaxed(0, msm_tmr0_base + WDT0_EN);
- mb();
- once++;
-
- pr_info("%s\n", __func__);
+ /*
+ * static int once = 1;
+ * void __iomem *msm_tmr0_base;
+ *
+ * if (once > 1)
+ * return;
+ *
+ * msm_tmr0_base = wdt_timer_get_timer0_base();
+ * if (!msm_tmr0_base)
+ * return;
+ *
+ * writel_relaxed(0, msm_tmr0_base + WDT0_EN);
+ * mb();
+ * once++;
+ *
+ * pr_info("%s\n", __func__);
+ */
}
void lge_panic_handler_fb_free_page(unsigned long mem_addr, unsigned long size)
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index 1002054..338c1ef 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -29,6 +29,7 @@ static struct kgdb_io kgdboc_io_ops;
static int configured = -1;
static char config[MAX_CONFIG_LEN];
+static int config_retry_time = 0;
static struct kparam_string kps = {
.string = config,
.maxlen = MAX_CONFIG_LEN,
@@ -152,7 +153,26 @@ static void cleanup_kgdboc(void)
if (configured == 1)
kgdb_unregister_io_module(&kgdboc_io_ops);
}
+static int kgdbretry_option_setup(char *opt)
+{
+ if (strlen(opt) > MAX_CONFIG_LEN) {
+ printk(KERN_ERR "kgdbretry: config string too long\n");
+ return -ENOSPC;
+ }
+ config_retry_time = simple_strtoul(opt, NULL, 10);
+ return 0;
+}
+
+__setup("kgdbretry=", kgdbretry_option_setup);
+static int configure_kgdboc(void);
+static void ttycheck_func(struct work_struct *work)
+{
+ config_retry_time = 0;
+ configure_kgdboc();
+}
+
+static DECLARE_DELAYED_WORK(ttycheck_work, ttycheck_func);
static int configure_kgdboc(void)
{
struct tty_driver *p;
@@ -179,9 +199,16 @@ static int configure_kgdboc(void)
goto do_register;
p = tty_find_polling_driver(cptr, &tty_line);
- if (!p)
+ if (!p) {
+ printk(KERN_INFO "kgdb will retry in %d secs\n", config_retry_time);
+ if (config_retry_time > 0) {
+ INIT_DELAYED_WORK(&ttycheck_work, ttycheck_func);
+ schedule_delayed_work(&ttycheck_work, config_retry_time * HZ);
+ return -ENODEV;
+ }
goto noconfig;
-
+ }
+
cons = console_drivers;
while (cons) {
int idx;
@@ -335,5 +362,6 @@ module_init(init_kgdboc);
module_exit(cleanup_kgdboc);
module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644);
MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]");
+MODULE_PARM_DESC(kgdbretry, "<delay in seconds> before retrying tty");
MODULE_DESCRIPTION("KGDB Console TTY Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index 87feac4..ae3a707 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -821,6 +821,8 @@ static void msm_hsl_reset(struct uart_port *port)
msm_hsl_write(port, RESET_BREAK_INT, regmap[vid][UARTDM_CR]);
msm_hsl_write(port, RESET_CTS, regmap[vid][UARTDM_CR]);
msm_hsl_write(port, RFR_LOW, regmap[vid][UARTDM_CR]);
+ /* Disable DM modes */
+ msm_hsl_write(port, 0, regmap[vid][UARTDM_DMEN]);
}
static unsigned int msm_hsl_get_mctrl(struct uart_port *port)
@@ -1355,6 +1357,136 @@ static void msm_hsl_power(struct uart_port *port, unsigned int state,
}
}
+#ifdef CONFIG_CONSOLE_POLL
+
+/* defines from msm_serial.h */
+#define UARTDM_DMEN_RX_SC_ENABLE BIT(5)
+#define UARTDM_DMEN_TX_SC_ENABLE BIT(4)
+
+#define UARTDM_RXFS_BUF_SHIFT 0x7
+#define UARTDM_RXFS_BUF_MASK 0x7
+
+static int msm_poll_init(struct uart_port *port)
+{
+ unsigned int vid;
+
+ vid = UART_TO_MSM(port)->ver_id;
+
+ /* Enable single character mode on RX FIFO */
+ /* A later patch from David Boyd suggests this causes problems... */
+ /*msm_hsl_write(port, UARTDM_DMEN_RX_SC_ENABLE, regmap[vid][UARTDM_DMEN]);*/
+
+ return 0;
+}
+
+static int msm_poll_get_char_dm(struct uart_port *port)
+{
+ int c;
+ static u32 slop;
+ static int count;
+ unsigned char *sp = (unsigned char *)&slop;
+ unsigned int vid;
+
+ vid = UART_TO_MSM(port)->ver_id;
+
+ /* Check if a previous read had more than one char */
+ if (count) {
+ c = sp[sizeof(slop) - count];
+ count--;
+ /* Or if FIFO is empty */
+ } else if (!(msm_hsl_read(port, regmap[vid][UARTDM_SR]) & UARTDM_SR_RXRDY_BMSK)) { /* bit 0 */
+ /*
+ * If RX packing buffer has less than a word, force stale to
+ * push contents into RX FIFO
+ */
+ count = msm_hsl_read(port, regmap[vid][UARTDM_RXFS]);
+
+ count = (count >> UARTDM_RXFS_BUF_SHIFT) & UARTDM_RXFS_BUF_MASK;
+ if (count) {
+ msm_hsl_write(port, FORCE_STALE_EVENT, regmap[vid][UARTDM_CR]);
+ slop = msm_hsl_read(port, regmap[vid][UARTDM_RF]);
+ c = sp[0];
+ count--;
+
+ msm_hsl_write(port, RESET_STALE_INT, regmap[vid][UARTDM_CR]);
+ msm_hsl_write(port, 0xFF, regmap[vid][UARTDM_DMRX]);
+ msm_hsl_write(port, STALE_EVENT_ENABLE, regmap[vid][UARTDM_CR]);
+
+ } else {
+ c = NO_POLL_CHAR;
+ }
+ /* FIFO has a word */
+ } else {
+ slop = msm_hsl_read(port, regmap[vid][UARTDM_RF]);
+ c = sp[0];
+ count = sizeof(slop) - 1;
+ }
+ return c;
+}
+
+
+static int msm_poll_get_char(struct uart_port *port)
+{
+ u32 imr;
+ int c;
+ unsigned int vid;
+
+ vid = UART_TO_MSM(port)->ver_id;
+
+ /* Disable all interrupts */
+ imr = msm_hsl_read(port, regmap[vid][UARTDM_IMR]);
+ msm_hsl_write(port, 0, regmap[vid][UARTDM_IMR]);
+
+
+ c = msm_poll_get_char_dm(port);
+
+
+ /* Enable interrupts */
+ msm_hsl_write(port, imr, regmap[vid][UARTDM_IMR]);
+ return c;
+}
+
+static void reset_dm_count(struct uart_port *port, int count)
+{
+ unsigned int vid;
+
+ vid = UART_TO_MSM(port)->ver_id;
+
+ wait_for_xmitr(port);
+ msm_hsl_write(port, count, regmap[vid][UARTDM_NCF_TX]);
+ msm_hsl_read(port, regmap[vid][UARTDM_NCF_TX]);
+}
+
+static void msm_poll_put_char(struct uart_port *port, unsigned char c)
+{
+ u32 imr;
+ unsigned int vid;
+
+ vid = UART_TO_MSM(port)->ver_id;
+
+ /* Disable all interrupts */
+ imr = msm_hsl_read(port, regmap[vid][UARTDM_IMR]);
+ msm_hsl_write(port, 0, regmap[vid][UARTDM_IMR]);
+
+ /*if (msm_port->is_uartdm)*/
+ reset_dm_count(port, 1);
+
+ /* Wait until FIFO is empty */
+ while (!(msm_hsl_read(port, regmap[vid][UARTDM_SR]) & UARTDM_SR_TXRDY_BMSK))
+ cpu_relax();
+
+ /* Write a character */
+ msm_hsl_write(port, c, regmap[vid][UARTDM_TF]);
+
+ /* Wait until FIFO is empty */
+ while (!(msm_hsl_read(port, regmap[vid][UARTDM_SR]) & UARTDM_SR_TXRDY_BMSK))
+ cpu_relax();
+
+ /* Enable interrupts */
+ msm_hsl_write(port, imr, regmap[vid][UARTDM_IMR]);
+ return;
+}
+#endif
static struct uart_ops msm_hsl_uart_pops = {
.tx_empty = msm_hsl_tx_empty,
.set_mctrl = msm_hsl_set_mctrl,
@@ -1373,6 +1505,11 @@ static struct uart_ops msm_hsl_uart_pops = {
.config_port = msm_hsl_config_port,
.verify_port = msm_hsl_verify_port,
.pm = msm_hsl_power,
+ #ifdef CONFIG_CONSOLE_POLL
+ .poll_init = msm_poll_init,
+ .poll_get_char = msm_poll_get_char,
+ .poll_put_char = msm_poll_put_char,
+ #endif
};
static struct msm_hsl_port msm_hsl_uart_ports[] = {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment