sead3-init.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
  7. */
  8. #include <linux/init.h>
  9. #include <linux/io.h>
  10. #include <asm/bootinfo.h>
  11. #include <asm/cacheflush.h>
  12. #include <asm/traps.h>
  13. #include <asm/mips-boards/generic.h>
  14. #include <asm/fw/fw.h>
  15. extern char except_vec_nmi;
  16. extern char except_vec_ejtag_debug;
  17. #ifdef CONFIG_SERIAL_8250_CONSOLE
  18. static void __init console_config(void)
  19. {
  20. char console_string[40];
  21. int baud = 0;
  22. char parity = '\0', bits = '\0', flow = '\0';
  23. char *s;
  24. if ((strstr(fw_getcmdline(), "console=")) == NULL) {
  25. s = fw_getenv("modetty0");
  26. if (s) {
  27. while (*s >= '0' && *s <= '9')
  28. baud = baud*10 + *s++ - '0';
  29. if (*s == ',')
  30. s++;
  31. if (*s)
  32. parity = *s++;
  33. if (*s == ',')
  34. s++;
  35. if (*s)
  36. bits = *s++;
  37. if (*s == ',')
  38. s++;
  39. if (*s == 'h')
  40. flow = 'r';
  41. }
  42. if (baud == 0)
  43. baud = 38400;
  44. if (parity != 'n' && parity != 'o' && parity != 'e')
  45. parity = 'n';
  46. if (bits != '7' && bits != '8')
  47. bits = '8';
  48. if (flow == '\0')
  49. flow = 'r';
  50. sprintf(console_string, " console=ttyS0,%d%c%c%c", baud,
  51. parity, bits, flow);
  52. strcat(fw_getcmdline(), console_string);
  53. }
  54. }
  55. #endif
  56. static void __init mips_nmi_setup(void)
  57. {
  58. void *base;
  59. base = cpu_has_veic ?
  60. (void *)(CAC_BASE + 0xa80) :
  61. (void *)(CAC_BASE + 0x380);
  62. #ifdef CONFIG_CPU_MICROMIPS
  63. /*
  64. * Decrement the exception vector address by one for microMIPS.
  65. */
  66. memcpy(base, (&except_vec_nmi - 1), 0x80);
  67. /*
  68. * This is a hack. We do not know if the boot loader was built with
  69. * microMIPS instructions or not. If it was not, the NMI exception
  70. * code at 0x80000a80 will be taken in MIPS32 mode. The hand coded
  71. * assembly below forces us into microMIPS mode if we are a pure
  72. * microMIPS kernel. The assembly instructions are:
  73. *
  74. * 3C1A8000 lui k0,0x8000
  75. * 375A0381 ori k0,k0,0x381
  76. * 03400008 jr k0
  77. * 00000000 nop
  78. *
  79. * The mode switch occurs by jumping to the unaligned exception
  80. * vector address at 0x80000381 which would have been 0x80000380
  81. * in MIPS32 mode. The jump to the unaligned address transitions
  82. * us into microMIPS mode.
  83. */
  84. if (!cpu_has_veic) {
  85. void *base2 = (void *)(CAC_BASE + 0xa80);
  86. *((unsigned int *)base2) = 0x3c1a8000;
  87. *((unsigned int *)base2 + 1) = 0x375a0381;
  88. *((unsigned int *)base2 + 2) = 0x03400008;
  89. *((unsigned int *)base2 + 3) = 0x00000000;
  90. flush_icache_range((unsigned long)base2,
  91. (unsigned long)base2 + 0x10);
  92. }
  93. #else
  94. memcpy(base, &except_vec_nmi, 0x80);
  95. #endif
  96. flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
  97. }
  98. static void __init mips_ejtag_setup(void)
  99. {
  100. void *base;
  101. base = cpu_has_veic ?
  102. (void *)(CAC_BASE + 0xa00) :
  103. (void *)(CAC_BASE + 0x300);
  104. #ifdef CONFIG_CPU_MICROMIPS
  105. /* Deja vu... */
  106. memcpy(base, (&except_vec_ejtag_debug - 1), 0x80);
  107. if (!cpu_has_veic) {
  108. void *base2 = (void *)(CAC_BASE + 0xa00);
  109. *((unsigned int *)base2) = 0x3c1a8000;
  110. *((unsigned int *)base2 + 1) = 0x375a0301;
  111. *((unsigned int *)base2 + 2) = 0x03400008;
  112. *((unsigned int *)base2 + 3) = 0x00000000;
  113. flush_icache_range((unsigned long)base2,
  114. (unsigned long)base2 + 0x10);
  115. }
  116. #else
  117. memcpy(base, &except_vec_ejtag_debug, 0x80);
  118. #endif
  119. flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
  120. }
  121. void __init prom_init(void)
  122. {
  123. board_nmi_handler_setup = mips_nmi_setup;
  124. board_ejtag_handler_setup = mips_ejtag_setup;
  125. fw_init_cmdline();
  126. #ifdef CONFIG_EARLY_PRINTK
  127. if ((strstr(fw_getcmdline(), "console=ttyS0")) != NULL)
  128. fw_init_early_console(0);
  129. else if ((strstr(fw_getcmdline(), "console=ttyS1")) != NULL)
  130. fw_init_early_console(1);
  131. #endif
  132. #ifdef CONFIG_SERIAL_8250_CONSOLE
  133. if ((strstr(fw_getcmdline(), "console=")) == NULL)
  134. strcat(fw_getcmdline(), " console=ttyS0,38400n8r");
  135. console_config();
  136. #endif
  137. }
  138. void __init prom_free_prom_memory(void)
  139. {
  140. }