diff options
Diffstat (limited to 'kernel/debug/kdb/kdb_main.c')
| -rw-r--r-- | kernel/debug/kdb/kdb_main.c | 132 |
1 files changed, 120 insertions, 12 deletions
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index ebe4a287419e..8577e45a9a58 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
| @@ -312,7 +312,7 @@ int kdbgetularg(const char *arg, unsigned long *value) | |||
| 312 | 312 | ||
| 313 | if (endp == arg) { | 313 | if (endp == arg) { |
| 314 | /* | 314 | /* |
| 315 | * Try base 16, for us folks too lazy to type the | 315 | * Also try base 16, for us folks too lazy to type the |
| 316 | * leading 0x... | 316 | * leading 0x... |
| 317 | */ | 317 | */ |
| 318 | val = simple_strtoul(arg, &endp, 16); | 318 | val = simple_strtoul(arg, &endp, 16); |
| @@ -325,6 +325,25 @@ int kdbgetularg(const char *arg, unsigned long *value) | |||
| 325 | return 0; | 325 | return 0; |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | int kdbgetu64arg(const char *arg, u64 *value) | ||
| 329 | { | ||
| 330 | char *endp; | ||
| 331 | u64 val; | ||
| 332 | |||
| 333 | val = simple_strtoull(arg, &endp, 0); | ||
| 334 | |||
| 335 | if (endp == arg) { | ||
| 336 | |||
| 337 | val = simple_strtoull(arg, &endp, 16); | ||
| 338 | if (endp == arg) | ||
| 339 | return KDB_BADINT; | ||
| 340 | } | ||
| 341 | |||
| 342 | *value = val; | ||
| 343 | |||
| 344 | return 0; | ||
| 345 | } | ||
| 346 | |||
| 328 | /* | 347 | /* |
| 329 | * kdb_set - This function implements the 'set' command. Alter an | 348 | * kdb_set - This function implements the 'set' command. Alter an |
| 330 | * existing environment variable or create a new one. | 349 | * existing environment variable or create a new one. |
| @@ -1770,11 +1789,65 @@ static int kdb_go(int argc, const char **argv) | |||
| 1770 | */ | 1789 | */ |
| 1771 | static int kdb_rd(int argc, const char **argv) | 1790 | static int kdb_rd(int argc, const char **argv) |
| 1772 | { | 1791 | { |
| 1773 | int diag = kdb_check_regs(); | 1792 | int len = kdb_check_regs(); |
| 1774 | if (diag) | 1793 | #if DBG_MAX_REG_NUM > 0 |
| 1775 | return diag; | 1794 | int i; |
| 1795 | char *rname; | ||
| 1796 | int rsize; | ||
| 1797 | u64 reg64; | ||
| 1798 | u32 reg32; | ||
| 1799 | u16 reg16; | ||
| 1800 | u8 reg8; | ||
| 1801 | |||
| 1802 | if (len) | ||
| 1803 | return len; | ||
| 1804 | |||
| 1805 | for (i = 0; i < DBG_MAX_REG_NUM; i++) { | ||
| 1806 | rsize = dbg_reg_def[i].size * 2; | ||
| 1807 | if (rsize > 16) | ||
| 1808 | rsize = 2; | ||
| 1809 | if (len + strlen(dbg_reg_def[i].name) + 4 + rsize > 80) { | ||
| 1810 | len = 0; | ||
| 1811 | kdb_printf("\n"); | ||
| 1812 | } | ||
| 1813 | if (len) | ||
| 1814 | len += kdb_printf(" "); | ||
| 1815 | switch(dbg_reg_def[i].size * 8) { | ||
| 1816 | case 8: | ||
| 1817 | rname = dbg_get_reg(i, ®8, kdb_current_regs); | ||
| 1818 | if (!rname) | ||
| 1819 | break; | ||
| 1820 | len += kdb_printf("%s: %02x", rname, reg8); | ||
| 1821 | break; | ||
| 1822 | case 16: | ||
| 1823 | rname = dbg_get_reg(i, ®16, kdb_current_regs); | ||
| 1824 | if (!rname) | ||
| 1825 | break; | ||
| 1826 | len += kdb_printf("%s: %04x", rname, reg16); | ||
| 1827 | break; | ||
| 1828 | case 32: | ||
| 1829 | rname = dbg_get_reg(i, ®32, kdb_current_regs); | ||
| 1830 | if (!rname) | ||
| 1831 | break; | ||
| 1832 | len += kdb_printf("%s: %08x", rname, reg32); | ||
| 1833 | break; | ||
| 1834 | case 64: | ||
| 1835 | rname = dbg_get_reg(i, ®64, kdb_current_regs); | ||
| 1836 | if (!rname) | ||
| 1837 | break; | ||
| 1838 | len += kdb_printf("%s: %016llx", rname, reg64); | ||
| 1839 | break; | ||
| 1840 | default: | ||
| 1841 | len += kdb_printf("%s: ??", dbg_reg_def[i].name); | ||
| 1842 | } | ||
| 1843 | } | ||
| 1844 | kdb_printf("\n"); | ||
| 1845 | #else | ||
| 1846 | if (len) | ||
| 1847 | return len; | ||
| 1776 | 1848 | ||
| 1777 | kdb_dumpregs(kdb_current_regs); | 1849 | kdb_dumpregs(kdb_current_regs); |
| 1850 | #endif | ||
| 1778 | return 0; | 1851 | return 0; |
| 1779 | } | 1852 | } |
| 1780 | 1853 | ||
| @@ -1782,32 +1855,67 @@ static int kdb_rd(int argc, const char **argv) | |||
| 1782 | * kdb_rm - This function implements the 'rm' (register modify) command. | 1855 | * kdb_rm - This function implements the 'rm' (register modify) command. |
| 1783 | * rm register-name new-contents | 1856 | * rm register-name new-contents |
| 1784 | * Remarks: | 1857 | * Remarks: |
| 1785 | * Currently doesn't allow modification of control or | 1858 | * Allows register modification with the same restrictions as gdb |
| 1786 | * debug registers. | ||
| 1787 | */ | 1859 | */ |
| 1788 | static int kdb_rm(int argc, const char **argv) | 1860 | static int kdb_rm(int argc, const char **argv) |
| 1789 | { | 1861 | { |
| 1862 | #if DBG_MAX_REG_NUM > 0 | ||
| 1790 | int diag; | 1863 | int diag; |
| 1791 | int ind = 0; | 1864 | const char *rname; |
| 1792 | unsigned long contents; | 1865 | int i; |
| 1866 | u64 reg64; | ||
| 1867 | u32 reg32; | ||
| 1868 | u16 reg16; | ||
| 1869 | u8 reg8; | ||
| 1793 | 1870 | ||
| 1794 | if (argc != 2) | 1871 | if (argc != 2) |
| 1795 | return KDB_ARGCOUNT; | 1872 | return KDB_ARGCOUNT; |
| 1796 | /* | 1873 | /* |
| 1797 | * Allow presence or absence of leading '%' symbol. | 1874 | * Allow presence or absence of leading '%' symbol. |
| 1798 | */ | 1875 | */ |
| 1799 | if (argv[1][0] == '%') | 1876 | rname = argv[1]; |
| 1800 | ind = 1; | 1877 | if (*rname == '%') |
| 1878 | rname++; | ||
| 1801 | 1879 | ||
| 1802 | diag = kdbgetularg(argv[2], &contents); | 1880 | diag = kdbgetu64arg(argv[2], ®64); |
| 1803 | if (diag) | 1881 | if (diag) |
| 1804 | return diag; | 1882 | return diag; |
| 1805 | 1883 | ||
| 1806 | diag = kdb_check_regs(); | 1884 | diag = kdb_check_regs(); |
| 1807 | if (diag) | 1885 | if (diag) |
| 1808 | return diag; | 1886 | return diag; |
| 1887 | |||
| 1888 | diag = KDB_BADREG; | ||
| 1889 | for (i = 0; i < DBG_MAX_REG_NUM; i++) { | ||
| 1890 | if (strcmp(rname, dbg_reg_def[i].name) == 0) { | ||
| 1891 | diag = 0; | ||
| 1892 | break; | ||
| 1893 | } | ||
| 1894 | } | ||
| 1895 | if (!diag) { | ||
| 1896 | switch(dbg_reg_def[i].size * 8) { | ||
| 1897 | case 8: | ||
| 1898 | reg8 = reg64; | ||
| 1899 | dbg_set_reg(i, ®8, kdb_current_regs); | ||
| 1900 | break; | ||
| 1901 | case 16: | ||
| 1902 | reg16 = reg64; | ||
| 1903 | dbg_set_reg(i, ®16, kdb_current_regs); | ||
| 1904 | break; | ||
| 1905 | case 32: | ||
| 1906 | reg32 = reg64; | ||
| 1907 | dbg_set_reg(i, ®32, kdb_current_regs); | ||
| 1908 | break; | ||
| 1909 | case 64: | ||
| 1910 | dbg_set_reg(i, ®64, kdb_current_regs); | ||
| 1911 | break; | ||
| 1912 | } | ||
| 1913 | } | ||
| 1914 | return diag; | ||
| 1915 | #else | ||
| 1809 | kdb_printf("ERROR: Register set currently not implemented\n"); | 1916 | kdb_printf("ERROR: Register set currently not implemented\n"); |
| 1810 | return 0; | 1917 | return 0; |
| 1918 | #endif | ||
| 1811 | } | 1919 | } |
| 1812 | 1920 | ||
| 1813 | #if defined(CONFIG_MAGIC_SYSRQ) | 1921 | #if defined(CONFIG_MAGIC_SYSRQ) |
