py-console.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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) 2001, 2002, 2004 Ralf Baechle
  7. */
  8. #include <linux/init.h>
  9. #include <linux/console.h>
  10. #include <linux/kdev_t.h>
  11. #include <linux/major.h>
  12. #include <linux/termios.h>
  13. #include <linux/sched.h>
  14. #include <linux/tty.h>
  15. #include <linux/serial.h>
  16. #include <linux/serial_core.h>
  17. #include <asm/serial.h>
  18. #include <asm/io.h>
  19. /* SUPERIO uart register map */
  20. struct yo_uartregs {
  21. union {
  22. volatile u8 rbr; /* read only, DLAB == 0 */
  23. volatile u8 thr; /* write only, DLAB == 0 */
  24. volatile u8 dll; /* DLAB == 1 */
  25. } u1;
  26. union {
  27. volatile u8 ier; /* DLAB == 0 */
  28. volatile u8 dlm; /* DLAB == 1 */
  29. } u2;
  30. union {
  31. volatile u8 iir; /* read only */
  32. volatile u8 fcr; /* write only */
  33. } u3;
  34. volatile u8 iu_lcr;
  35. volatile u8 iu_mcr;
  36. volatile u8 iu_lsr;
  37. volatile u8 iu_msr;
  38. volatile u8 iu_scr;
  39. } yo_uregs_t;
  40. #define iu_rbr u1.rbr
  41. #define iu_thr u1.thr
  42. #define iu_dll u1.dll
  43. #define iu_ier u2.ier
  44. #define iu_dlm u2.dlm
  45. #define iu_iir u3.iir
  46. #define iu_fcr u3.fcr
  47. #define ssnop() __asm__ __volatile__("sll $0, $0, 1\n");
  48. #define ssnop_4() do { ssnop(); ssnop(); ssnop(); ssnop(); } while (0)
  49. #define IO_BASE_64 0x9000000000000000ULL
  50. static unsigned char readb_outer_space(unsigned long long phys)
  51. {
  52. unsigned long long vaddr = IO_BASE_64 | phys;
  53. unsigned char res;
  54. unsigned int sr;
  55. sr = read_c0_status();
  56. write_c0_status((sr | ST0_KX) & ~ ST0_IE);
  57. ssnop_4();
  58. __asm__ __volatile__ (
  59. " .set mips3 \n"
  60. " ld %0, %1 \n"
  61. " lbu %0, (%0) \n"
  62. " .set mips0 \n"
  63. : "=r" (res)
  64. : "m" (vaddr));
  65. write_c0_status(sr);
  66. ssnop_4();
  67. return res;
  68. }
  69. static void writeb_outer_space(unsigned long long phys, unsigned char c)
  70. {
  71. unsigned long long vaddr = IO_BASE_64 | phys;
  72. unsigned long tmp;
  73. unsigned int sr;
  74. sr = read_c0_status();
  75. write_c0_status((sr | ST0_KX) & ~ ST0_IE);
  76. ssnop_4();
  77. __asm__ __volatile__ (
  78. " .set mips3 \n"
  79. " ld %0, %1 \n"
  80. " sb %2, (%0) \n"
  81. " .set mips0 \n"
  82. : "=&r" (tmp)
  83. : "m" (vaddr), "r" (c));
  84. write_c0_status(sr);
  85. ssnop_4();
  86. }
  87. void prom_putchar(char c)
  88. {
  89. unsigned long lsr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_lsr);
  90. unsigned long thr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_thr);
  91. while ((readb_outer_space(lsr) & 0x20) == 0);
  92. writeb_outer_space(thr, c);
  93. }